Synchronous Tasks"

From Documentation
m (remove empty version history (via JWB))
 
(19 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{ZKDevelopersReferencePageHeader}}
 
{{ZKDevelopersReferencePageHeader}}
  
Server push is a technology to actively ''push'' data to the client. For ZK, the data is usually UI updates or its variants. Thus, for sake of understanding, we could consider the task is about updating UI concurrently with regular Ajax requests (poll-type request). For example, in a chat application, we have to update UI when the people you talk to have entered a message. Since the entering of a message takes place in another session, the server has to ''push'' to all clients that involve in the conversation.
 
  
If the task of updating UI takes place in a working thread, it generally more convenient to execute it synchronously. On the other hand, if the task can be encapsulated as an event listener (<javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc>), you could refer to the [[ZK Developer's Reference/Server Push/Asynchronous Tasks|Asynchronous Tasks]] section.
+
__TOC__
 +
 
 +
 
 +
Server push is a technology to actively ''push'' data to the client. For ZK, the data is usually the UI updates or its variants. Thus, for the sake of understanding, we could consider the task to be about updating UI in parallel with regular Ajax requests (poll-type requests). For example, in a chat application, once a message is entered by a participant, the server has to ''push'' it to all clients that are involved in the conversation.
 +
 
 +
If the task of updating UI takes place in a working thread, it is generally more convenient to execute it synchronously as described later. On the other hand, if the task can be encapsulated as an event listener (<javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc>), you could execute it asynchronously -- please refer to the [[ZK Developer's Reference/Server Push/Asynchronous Tasks|Asynchronous Tasks]] section for more information.
  
 
=Enable Server Push=
 
=Enable Server Push=
  
By default, the server push is disabled (for better performance). To enable it, you have to invoke <javadoc method="enableServerPush(boolean)" type="interface">org.zkoss.zk.ui.Desktop</javadoc> with the desktop that you want to update in working thread.
+
By default, the server push is disabled (for better performance). Before pushing data for a given desktop, you have to enable the server push for it.
 +
 
 +
It can be done by use of <javadoc method="enableServerPush(boolean)" type="interface">org.zkoss.zk.ui.Desktop</javadoc>:
  
 
<source lang="java">
 
<source lang="java">
Line 13: Line 19:
 
</source>
 
</source>
  
After the server push of a given desktop is enabled, you could use any number of working thread to update the UI concurrently<ref>For better performance, it is suggested to disable the server push if it is no longer used in the give desktop.</ref>.
+
After the server push of a given desktop is enabled, you could use any number of working threads to update the desktop concurrently as described in the following section<ref>For better performance, it is suggested to disable the server push if it is no longer used in the given desktop.</ref>.
  
 
<blockquote>
 
<blockquote>
Line 21: Line 27:
  
 
=Update UI in a Working Thread=
 
=Update UI in a Working Thread=
To updating the UI synchronously in a working thread, we have to do as follows.
+
To update the UI synchronously in a working thread, we have to do as follows.
  
 
#Invoke <javadoc method="activate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc>. It has two purposes:
 
#Invoke <javadoc method="activate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc>. It has two purposes:
##It grants the right to access the UI of the given desktop to the thread<ref>Notice that, for each desktop, there is at most one thread is allowed to access.</ref>.
+
##It grants the right to access the UI of the given desktop to the caller's thread.
##It establishes a connection with the client (the browser window displaying the desktop), such that the update will be sent to the client after finished
+
##: Notice that, for each desktop, at most one thread is allowed to access at the same time.
 +
##It establishes a connection with the client (the browser window displaying the desktop), such that the update will be sent to the client after finished.
 
#Update UI any way you want, just like any regular event listener.
 
#Update UI any way you want, just like any regular event listener.
#Invoke <javadoc method="deactivate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc> to return the control, such that other thread could have a chance to update UI.
+
#Invoke <javadoc method="deactivate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc> to return the control, such that other threads could have a chance to update UI.
 +
 
 +
Here is an example code that illustrates the usages:
  
Here is the pseudo code that illustrates the flow:
 
  
<source lang="java">
+
<syntaxhighlight line lang="java" highlight="9,15">
 
public class WorkingThread extends Thread {
 
public class WorkingThread extends Thread {
 
     public void run() {
 
     public void run() {
 
         try {
 
         try {
             while (anyDataToShow()) { //whatever you like
+
             while (anyDataToShow()) {
 
                 //Step 1. Prepare the data that will be updated to UI
 
                 //Step 1. Prepare the data that will be updated to UI
                 collectData(); //whatever you like
+
                 collectData(); //prepare the data to set to components
  
                 //Step 2. Activate to grant the access of the give desktop
+
                 //Step 2. Activate to grant the access of the given desktop
 
                 Executions.activate(desktop);
 
                 Executions.activate(desktop);
 
                 try {
 
                 try {
 
                     //Step 3. Update UI
 
                     //Step 3. Update UI
                     updateUI(); //whatever you like
+
                     updateUI(); //implement the logic to change UI, call ZK component API or notify change
 
                 } finally {
 
                 } finally {
 
                     //Step 4. Deactivate to return the control of UI back
 
                     //Step 4. Deactivate to return the control of UI back
                     Executions.deactivate(_desktop);
+
                     Executions.deactivate(desktop);
 
                 }
 
                 }
 
             }
 
             }
Line 52: Line 60:
 
             //Interrupted. You might want to handle it
 
             //Interrupted. You might want to handle it
 
         }
 
         }
 +
    }
 +
 +
  /**
 +
    * To update UI you can do one of the followings:
 +
    * - to notify changes with {@link BindUtils#postNotifyChange(Object, String)} if changing a ViewModel's property
 +
    * - call a component's setter
 +
    * - If calling a {@link org.zkoss.zul.ListModel} method, it automatically updates for you without notifying
 +
    */
 +
    protected void updateUI() {
 +
        data.clear();
 +
        data.add("now " + System.currentTimeMillis());
 
     }
 
     }
 
}
 
}
</source>
+
</syntaxhighlight>
 +
 
 +
* Line 9-15: the task between <javadoc method="activate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc> and <javadoc method="deactivate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc> has to take less time, since it blocks others, including the end users (of the desktop), from accessing the UI. It is suggested to prepare the data before <javadoc method="activate(org.zkoss.zk.ui.Desktop)">org.zkoss.zk.ui.Executions</javadoc>, such that it can be done in parallel with other threads.
 +
 
 +
For a real example, please refer to small talks: [[Small Talks/2007/August/Simple and Intuitive Server Push with a Chat Room Example|Simple and Intuitive Server Push with a Chat Room Example]] and [[Small Talks/2008/May/Server Push with a Stock Chart Example|Server Push with a Stock Chart Example]].
  
<blockquote>
 
----
 
<references/>
 
</blockquote>
 
  
=Version History=
 
{{LastUpdated}}
 
{| border='1px' | width="100%"
 
! Version !! Date !! Content
 
|-
 
| &nbsp;
 
| &nbsp;
 
| &nbsp;
 
|}
 
  
 
{{ZKDevelopersReferencePageFooter}}
 
{{ZKDevelopersReferencePageFooter}}

Latest revision as of 10:25, 5 February 2024


Synchronous Tasks




Server push is a technology to actively push data to the client. For ZK, the data is usually the UI updates or its variants. Thus, for the sake of understanding, we could consider the task to be about updating UI in parallel with regular Ajax requests (poll-type requests). For example, in a chat application, once a message is entered by a participant, the server has to push it to all clients that are involved in the conversation.

If the task of updating UI takes place in a working thread, it is generally more convenient to execute it synchronously as described later. On the other hand, if the task can be encapsulated as an event listener (EventListener), you could execute it asynchronously -- please refer to the Asynchronous Tasks section for more information.

Enable Server Push

By default, the server push is disabled (for better performance). Before pushing data for a given desktop, you have to enable the server push for it.

It can be done by use of Desktop.enableServerPush(boolean):

desktop.enableServerPush(true);

After the server push of a given desktop is enabled, you could use any number of working threads to update the desktop concurrently as described in the following section[1].


  1. For better performance, it is suggested to disable the server push if it is no longer used in the given desktop.

Update UI in a Working Thread

To update the UI synchronously in a working thread, we have to do as follows.

  1. Invoke Executions.activate(Desktop). It has two purposes:
    1. It grants the right to access the UI of the given desktop to the caller's thread.
      Notice that, for each desktop, at most one thread is allowed to access at the same time.
    2. It establishes a connection with the client (the browser window displaying the desktop), such that the update will be sent to the client after finished.
  2. Update UI any way you want, just like any regular event listener.
  3. Invoke Executions.deactivate(Desktop) to return the control, such that other threads could have a chance to update UI.

Here is an example code that illustrates the usages:


 1 public class WorkingThread extends Thread {
 2     public void run() {
 3         try {
 4             while (anyDataToShow()) {
 5                 //Step 1. Prepare the data that will be updated to UI
 6                 collectData(); //prepare the data to set to components
 7 
 8                 //Step 2. Activate to grant the access of the given desktop
 9                 Executions.activate(desktop);
10                 try {
11                      //Step 3. Update UI
12                      updateUI(); //implement the logic to change UI, call ZK component API or notify change
13                 } finally {
14                     //Step 4. Deactivate to return the control of UI back
15                      Executions.deactivate(desktop);
16                 }
17             }
18         } catch (InterruptedException ex) {
19             //Interrupted. You might want to handle it
20         }
21     }
22 
23    /**
24      * To update UI you can do one of the followings:
25      * - to notify changes with {@link BindUtils#postNotifyChange(Object, String)} if changing a ViewModel's property
26      * - call a component's setter
27      * - If calling a {@link org.zkoss.zul.ListModel} method, it automatically updates for you without notifying
28      */
29     protected void updateUI() {
30         data.clear();
31         data.add("now " + System.currentTimeMillis());
32     }
33 }

For a real example, please refer to small talks: Simple and Intuitive Server Push with a Chat Room Example and Server Push with a Stock Chart Example.




Last Update : 2024/02/05

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.