Event Threads"
Line 3: | Line 3: | ||
__TOC__ | __TOC__ | ||
− | By default, ZK processes an event in the same Servlet thread that receives the HTTP request. It is the suggested approach because it is | + | By default, ZK processes an event in the same Servlet thread that receives the HTTP request. It is the suggested approach because the performance is better and it is easy to integrate with other frameworks<ref>Many frameworks store per-request information in the thread-local storage.</ref>. |
However, it also implies the developer cannot suspend the execution. Otherwise, the end user won't see any update from the server. To solve it, ZK provides an alternative approach: processes the event in an independent thread called the event processing thread. Therefore, the developer can suspend and resume the execution at any time, without blocking the Servlet thread from sending back the responses to the browser. To turn it on<ref> For ZK 1.x, 2.x and 3.x, the event processing thread is enabled by default.</ref>, you have to specify the following in <tt>WEB-INF/zk.xml</tt>. | However, it also implies the developer cannot suspend the execution. Otherwise, the end user won't see any update from the server. To solve it, ZK provides an alternative approach: processes the event in an independent thread called the event processing thread. Therefore, the developer can suspend and resume the execution at any time, without blocking the Servlet thread from sending back the responses to the browser. To turn it on<ref> For ZK 1.x, 2.x and 3.x, the event processing thread is enabled by default.</ref>, you have to specify the following in <tt>WEB-INF/zk.xml</tt>. | ||
Line 25: | Line 25: | ||
| Less integration issues. | | Less integration issues. | ||
− | Many containers assume the HTTP request is handled in the | + | Many containers assume the HTTP request is handled in the Servlet thread, and many frameworks store per-request information in the thread local storage. |
− | |||
− | + | | You may have to implement <tt>EventThreadInit</tt> and/or <tt>EventThreadCleanup</tt> to solve the integration issue, such as copying the per-request information from the Servlet thread to the event processing thread. | |
+ | |||
+ | Threre are several implementations to solve the integration issue, such as <javadoc>org.zkoss/zkplus.hibernate.HibernateSessionContextListener</javadoc> (they can be found under [http://www.zkoss.org/javadoc/latest/zk/org/zkoss/zkplus/package-summary.html the org.zkoss.zkplus package]). | ||
|- | |- | ||
Line 36: | Line 37: | ||
For example, you cannot create a modal window. | For example, you cannot create a modal window. | ||
| No limitation at all. | | No limitation at all. | ||
+ | |||
+ | |- | ||
+ | | Performance | ||
+ | | No extra cost | ||
+ | |||
+ | | It executes a bit slower to switch from one thread to another, and it might consume a lot more memory if there are a lot of suspended event processing threads. | ||
|} | |} |
Revision as of 03:57, 3 September 2010
This documentation is for an older version of ZK. For the latest one, please click here.
By default, ZK processes an event in the same Servlet thread that receives the HTTP request. It is the suggested approach because the performance is better and it is easy to integrate with other frameworks[1].
However, it also implies the developer cannot suspend the execution. Otherwise, the end user won't see any update from the server. To solve it, ZK provides an alternative approach: processes the event in an independent thread called the event processing thread. Therefore, the developer can suspend and resume the execution at any time, without blocking the Servlet thread from sending back the responses to the browser. To turn it on[2], you have to specify the following in WEB-INF/zk.xml.
<system-config>
<disable-event-thread>false</disable-event-thread>
</system-config>
Here is the advantages and limitations about using the Servlet thread to process events. In the following sections we will talk more about the limitations and workarounds when using the Servlet thread.
Integration | Less integration issues.
Many containers assume the HTTP request is handled in the Servlet thread, and many frameworks store per-request information in the thread local storage. |
You may have to implement EventThreadInit and/or EventThreadCleanup to solve the integration issue, such as copying the per-request information from the Servlet thread to the event processing thread.
Threre are several implementations to solve the integration issue, such as HibernateSessionContextListener (they can be found under the org.zkoss.zkplus package). |
SuspendResume | No way to suspend the execution of the event listener.
For example, you cannot create a modal window. |
No limitation at all. |
Performance | No extra cost | It executes a bit slower to switch from one thread to another, and it might consume a lot more memory if there are a lot of suspended event processing threads. |
Modal Windows
You can not use the modal window anymore. You can create the same visual effect with the highlighted mode. However, at the server side, it works just like the overlapped mode – it returns immediately without waiting for user's response.
win.doHighlighted(); //returns once the mode is changed; not suspended
Message Boxes
The message boxes returns immediately so it always returns Messagebox.OK. Thus, it is meaningless to show buttons other than the OK button. For example, the if clause in the following example is never true.
if (Messagebox.show("Delete?", "Prompt", Messagebox.YES|Messagebox.NO,
Messagebox.QUESTION) == Messagebox.YES) {
this_never_executes();
}
Rather, you have to provide an event listener as follows.
Messagebox.show("Delete?", "Prompt", Messagebox.YES|Messagebox.NO,
Messagebox.QUESTION,
new EventListener() {
public void onEvent(Event evt) {
switch (((Integer)evt.getData()).intValue()) {
case Messagebox.YES: doYes(); break; //the Yes button is pressed
case Messagebox.NO: doNo(); break; //the No button is pressed
}
}
}
);
The event listener you provided is invoked when the user clicks one of the buttons. Then, you can identify which button is clicked by examining the data (Event's getData). The data is an integer whose value is the button's identifier, such as Messagebox.YES.
Alternatively, you can examine the event name:
public void onEvent(Event evt) {
if ("onYes".equals(evt.getName())) {
doYes(); //the Yes button is pressed
} else if ("onNo".equals(evt.getName())) {
doNo(); //the No button is pressed
}
}
Note: The event name for the OK button is onOK, not onOk.
File Upload
The file upload dialog is no longer applicable. Rather, you shall use Button or Toolbarbutton with upload="true" instead. For example,
<zk>
<zscript>
void upload(Event event) {
org.zkoss.util.media.Media media = event.getMedia();
if (media instanceof org.zkoss.image.Image) {
org.zkoss.zul.Image image = new org.zkoss.zul.Image();
image.setContent(media);
image.setParent(pics);
} else {
Messagebox.show("Not an image: "+media, "Error", Messagebox.OK, Messagebox.ERROR);
break; //not to show too many errors
}
}
</zscript>
<button label="Upload" upload="true" onUpload="upload(event)"/>
<toolbarbutton label="Upload" upload="true" onUpload="upload(event)"/>
<vbox id="pics" />
</zk>
If you prefer to use a dialog (Fileupload.get()), please take a look at ZK Component Reference: Fileupload for more inormation.