Servlet 规范是否保证单线程初始化和内联 attributeChanged 事件?

发布于 2024-12-25 10:08:43 字数 1212 浏览 0 评论 0原文

我有一个 Web 应用程序,在初始化 ServletContext 时从外部系统引导事件接收器。所有需要接收事件的组件都在侦听 ServletContext 属性事件并将自身附加为侦听器。由于我不希望事件侦听器错过事件,因此我想仅在附加所有侦听器后才启动事件源。

我在 Servlet 2.5 和 3.0 规范中找不到任何初始化的线程要求,因此我假设完全异步初始化模型,但我注意到 Tomcat 立即从 setAttribute() 方法触发 ServletContext 属性更改事件。这意味着如果所有其他 servlet 容器都效仿,我可以简化我的启动过程。

编辑:根据要求,这是一个示例(我已尝试尽可能具体)。在我的 web.xml 中,我目前已

  • 在 servlet 上下文初始化上注册: BootstrapEventSourceContextListener
    1. 创建事件源并将其设置为 servlet-context 属性。
    2. 事件源此时尚未启动(即它不发出事件)
  • 当接收到包含事件源的属性已被设置的通知时, ConsumerAContextAttributeListener
    1. 从 servlet-context 属性查找事件源
    2. 实例化 ConsumerA
    3. 将 ConsumerA 连接到事件源
    4. 将 ConsumerA 的数据模型设置为 servlet-context 中的属性
  • ConsumerBContextAttributeListener - 与 Comsumer 相同A
  • ConsumerCContextAttributeListener - 与 A 和 B 相同,不同之处在于它还取决于
  • 页面启动时 B StartEventSourceFilter 的数据模型访问:
    1. 从 servlet 上下文查找事件源
    2. 启动事件源
    3. 阻塞,直到事件源收到初始快照
    4. 继续渲染页面

问题是我是否真的需要 StartEventSourceFilter,或者是否保证当我设置事件源属性时,所有消费者都将被附加(即属性侦听器不会延迟)。我关心 Tomcat、Jetty 和 Websphere。

I have a web application that bootstraps event-receiver from external system when a ServletContext is initialized. All components that need to receive events are listening for ServletContext attribute events and attaching themselves as listeners. As I do not want the event-listeners to miss events, I want to start the event-source only after all listeners have been attached.

I could not find any threading requirements for initialization in the Servlet 2.5 and 3.0 specification, so I was assuming completely async initialization model, yet I noticed that Tomcat fires the ServletContext attribute-changed events immediately from the setAttribute() method. This would mean that if all other servlet containers follow suit, I can simplify my startup procedure.

EDIT: As requested, here is an example (I have tried to be as concrete as possible). In my web.xml, I currently have registered:

  • BootstrapEventSourceContextListener on servlet-context initialization:
    1. creates event-source and sets it as servlet-context attribute.
    2. the event-source is not started at this time (i.e. it does not emit events)
  • ConsumerAContextAttributeListener when it receives a notification that the attribute containing the event-source has been set:
    1. looks up the event-source from the servlet-context attribute
    2. instantiates ConsumerA
    3. attaches ConsumerA to the event-source
    4. sets the data model of ConsumerA as attribute in the servlet-context
  • ConsumerBContextAttributeListener - same as Comsumer A
  • ConsumerCContextAttributeListener - same as A and B, except that it also depends on the datamodel of B
  • StartEventSourceFilter when a page is accessed:
    1. looks up the event-source from the servlet-context
    2. starts the event-source
    3. blocks until the event-source has received initial snapshot
    4. continues to render the page

The question is whether I really need the StartEventSourceFilter, or is it guaranteed that all the consumers will be attached the moment I set the event-source attribute (i.e. attribute listeners are not deferred). I care about Tomcat, Jetty and Websphere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心碎的声音 2025-01-01 10:08:43

由于没有人回答,我深入研究,发现了以下内容:

Servlet 3.0 规范没有提到侦听器是内联通知还是异步通知,但它在第 11 章中提供了以下保证:

  • 11.2 所有有资格处理特定事件的侦听器都是按照在 web.xml 中注册的顺序调用。
  • 11.5 ServletContext 生命周期侦听器将在容器为其第一个请求提供服务之前实例化。没有明确的线程规范,但考虑到上面的一点保证了顺序,我认为这意味着它们也将被顺序和同步调用(在调用下一个实例之前等待当前实例完成) - 很可能这意味着相同的线程。也没有明确说明,但我发现可以合理地假设容器将等到所有通知方法完成后再为第一个请求提供服务。确认这就是 Tomcat 和 Jetty 所做的事情。
  • 11.5 ServletContext 和 HTTP 会话的属性更改可以同时运行。鉴于这也提到了 HTTP 会话,我认为这意味着如果 servlet 修改上下文,这些修改可以同时运行。在我们的例子中,上下文侦听器修改上下文属性,正如前面所说,它们是同步运行的,并且由于 ctx 属性侦听器的排序要求成立,我们可以假设属性侦听器在初始化时按顺序运行。

唯一剩下的问题是 servlet-context 属性侦听器是否始终与 setter 内联运行,或者是否存在将它们排队的实现(例如合并同一属性的多个更改事件)。我相信可以合理地假设规范的意图和所有实现都会内联通知侦听器(并在 Tomcat 和 Jetty 中证实了这一点)。

底线是:当从 context-init 侦听器设置上下文属性时,可以相当安全地假设所有上下文属性侦听器在 setter 方法返回时都已完成。规范没有明确保证这一点,但所有指定的约束和保证都指向这个方向。

As nobody answered, I dug in and here is what I found:

The Servlet 3.0 spec does not mention whether listeners are notified inline or asynchronously, but it provides the following guarantees in chapter 11:

  • 11.2 All listeners, eligible to handle a particular event are invoked in the order they are registered in web.xml
  • 11.5 ServletContext lifecycle listeners will be instantiated before the container serving its first request. There is no explicit threading specification, but given that the point above guarantees the ordering, I assume this means that they will also be invoked sequentially and synchronously (wait for the current instance to finish before callinfg the next) - most likely this means same thread. Also not explicitly stated, but I find it reasonable to assume that the container would wait until all notification methods complete before servicing the first request. Confirmed that is what Tomcat and Jetty do.
  • 11.5 Attribute changes to ServletContext and HTTP session can run concurently. Given that this also mentions HTTP session, I take this to mean that if servlets modify the context, these modifications can run concurrently. In our case, the context listeners modify context attributes, and as in previous point we have stated they are running synchronously, and as the ordering requirement holds for ctx-attribute listeners, we can assume that attribute listeners at init time run sequentially.

The only remaining issue is whether the servlet-context attribute listeners always run inline with the setters, or are there implementations that queue them up (say to coalesce multiple change events for the same attribute). I believe it is reasonable to assume that the intent of the spec and all implementations would notify the listeners inline (and confirmed this for Tomcat and Jetty).

Bottom-line is: when setting a context attribute from a context-init listener, it is reasonably safe to assume that all context-attribute listeners will have finished when the setter method returns. The specification does not explicitly guarantee this, but all specified constraints and guarantees point in that direction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文