KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > async > render > RenderHub


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

33
34 package com.icesoft.faces.async.render;
35
36 import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
37 import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
38 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 /**
43  * The RenderHub is designed to handle all server-side rendering calls. Although
44  * it can be created programmatically, it is recommended that the application
45  * developer use a {@link RenderManager} instance for all rendering duties and
46  * for creating named {@link GroupAsyncRenderer)s. The RenderManager creates
47  * and uses its own RenderHub for all rendering.
48  * <p/>
49  * A single RenderHub should handle all server-side rendering duties in a
50  * thread-safe and efficient manner. It uses a specialized queue to hold {@link
51  * Renderable} instances and a thread pool to render each Renderable on the
52  * queue. The queue will only keep a single entry of any particular Renderable.
53  * Subsequent Renderables that are offered to the queue for rendering are
54  * discarded since any pending render call will update the client to the latest
55  * state. This coalescing of render calls makes it safer and more efficient for
56  * the application developer to add rendering into their application.
57  *
58  * @author ICEsoft Technologies, Inc.
59  * @see RenderManager
60  */

61 public class RenderHub {
62
63     private static Log log = LogFactory.getLog(RenderHub.class);
64
65     /**
66      * The specialized thread pool used to execute render calls on Renderable
67      * instances. It uses the supplied settings for defaults.
68      */

69     private ThreadPoolExecutor renderService;
70     private int corePoolSize = 10;
71     private int maxPoolSize = 15;
72     private long keepAliveTime = 300000;
73     private int renderQueueCapacity = 1000;
74
75     /**
76      * The specialized thread pool used to execute render calls at some future
77      * time. The RenderHub makes this available to Renderers that need this
78      * ability.
79      *
80      * @see IntervalRenderer, DelayRenderer
81      */

82     private ScheduledThreadPoolExecutor scheduledService;
83     private int schedulePoolSize = 5;
84
85     /**
86      * Used by the ThreadPoolExector as a callback for rejected Runnable
87      * executions.
88      */

89     private RejectionHandler rejectionHandler;
90
91     /**
92      * Used by the ThreadPoolExecutor to create its thread pool.
93      */

94     private RenderThreadFactory threadFactory;
95
96     /**
97      * Public constructor. Although it possible for developers to construct and
98      * use their own RenderHub, it is highly recommended that a RenderManager be
99      * used. The RenderManager creates and uses it's own internal RenderHub.
100      */

101     public RenderHub() {
102         rejectionHandler = new RejectionHandler();
103         threadFactory = new RenderThreadFactory();
104     }
105
106     /**
107      * Get the starting size of the core thread pool.
108      *
109      * @return The starting size of the core thread pool.
110      */

111     public int getCorePoolSize() {
112         return corePoolSize;
113     }
114
115     /**
116      * Set the thread pool size of the core render service. The default is 10.
117      * This number will need to be adjusted based on the characteristics of the
118      * application. Note that increasing the number of threads past a certain
119      * number (based on OS, JVM, etc) can actually decrease performance as
120      * thread context switching becomes a burden.
121      *
122      * @param corePoolSize The number of threads to dedicate to the scheduled
123      * service thread pool.
124      */

125     public void setCorePoolSize(int corePoolSize) {
126         this.corePoolSize = corePoolSize;
127     }
128
129     /**
130      * Get the maximum size of the core thread pool.
131      *
132      * @return The maximum size of the core thread pool.
133      */

134     public int getMaxPoolSize() {
135         return maxPoolSize;
136     }
137
138     /**
139      * Set the maximum thread pool size of the core render service. The default
140      * is 15. This number will need to be adjusted based on the characteristics
141      * of the application. Note that increasing the number of threads past a
142      * certain number (based on OS, JVM, etc) can actually decrease performance
143      * as thread context switching becomes a burden.
144      *
145      * @param maxPoolSize The maximum number of threads to dedicate to the core
146      * service thread pool.
147      */

148     public void setMaxPoolSize(int maxPoolSize) {
149         this.maxPoolSize = maxPoolSize;
150     }
151
152     /**
153      * Get the keep alive time of threads above the core number. The number of
154      * threads that are created past the core number (up to the maximum number)
155      * are kept alive until they are idle for the keep alive time.
156      *
157      * @return The keep alive time for threads created past the core number.
158      */

159     public long getKeepAliveTime() {
160         return keepAliveTime;
161     }
162
163     /**
164      * Set the amount of idle time to keep threads created above the core size.
165      * The default is 300000 ms.
166      *
167      * @param keepAliveTime The idle time in ms to keep additional threads
168      * alive.
169      */

170     public void setKeepAliveTime(long keepAliveTime) {
171         this.keepAliveTime = keepAliveTime;
172     }
173
174     /**
175      * Get the capacity of the core render service queue.
176      *
177      * @return The capacity of the core render service queue.
178      */

179     public int getRenderQueueCapacity() {
180         return renderQueueCapacity;
181     }
182
183     public void setRenderQueueCapacity(int renderQueueCapacity) {
184         this.renderQueueCapacity = renderQueueCapacity;
185     }
186
187     /**
188      * The prime responsibility of the RenderHub is to perform a render call on
189      * the submitted Renderable. Each call to this method is submitted and, if
190      * not already in the queue, placed on the queue to be rendered. The thread
191      * pool is created here if does not yet exist using whatever configuration
192      * values have been set.
193      *
194      * @param renderable The Renderable instance to add to the rendering queue.
195      */

196     public void requestRender(Renderable renderable) {
197         if (renderService == null) {
198             createCoreService();
199         }
200         renderService.execute(new RunnableRender(renderable));
201     }
202
203     /**
204      * Method for creating the thread pool/queue service. Currently we use a
205      * JDK 1.4.x backport of the JDK 1.5.x concurrency utilities.
206      */

207     private synchronized void createCoreService() {
208
209         SingleEntryQueue queue = new SingleEntryQueue(renderQueueCapacity);
210
211         renderService = new ThreadPoolExecutor(corePoolSize,
212                                                maxPoolSize,
213                                                keepAliveTime,
214                                                TimeUnit.MILLISECONDS,
215                                                queue,
216                                                threadFactory,
217                                                rejectionHandler
218         );
219
220         if (log.isInfoEnabled()) {
221             log.info("core render service created:" +
222                      "\n core pool size : " + corePoolSize +
223                      "\n max pool size : " + maxPoolSize +
224                      "\n keep alive time: " + keepAliveTime);
225         }
226     }
227
228     /**
229      * As a secondary responsibility, the RenderHub also maintains a thread pool
230      * for render calls that should occur in the future. This service is used
231      * by renderers such as the {@link IntervalRenderer} and {@link
232      * DelayRenderer} to delay the eventual render calls. All the rendering is
233      * still handled by the RenderHubs core thread pool/queue. The scheduled
234      * service is used to delay when that occurs. Having this supplied by the
235      * RenderHub ensures that there is only one.
236      *
237      * @return A scheduling service.
238      */

239     public ScheduledThreadPoolExecutor getScheduledService() {
240         if (scheduledService == null) {
241             createScheduledService();
242         }
243         return scheduledService;
244     }
245
246     protected synchronized void createScheduledService() {
247
248         scheduledService = new ScheduledThreadPoolExecutor(corePoolSize,
249                                                            threadFactory,
250                                                            rejectionHandler
251         );
252         if (log.isInfoEnabled()) {
253             log.info("scheduled render service created:" +
254                      "\n core pool size : " + schedulePoolSize);
255         }
256     }
257
258     /**
259      * Get the thread pool size of the scheduled render service.
260      *
261      * @return the size of the schedule service thread pool
262      */

263     public int getSchedulePoolSize() {
264         return schedulePoolSize;
265     }
266
267     /**
268      * Set the thread pool size of the scheduled render service. The default is
269      * 5 and unless you have a lot of renderers that use the scheduling service,
270      * it should really be more than enough.
271      *
272      * @param schedulePoolSize The number of threads to dedicate to the
273      * scheduled service thread pool.
274      */

275     public void setSchedulePoolSize(int schedulePoolSize) {
276         this.schedulePoolSize = schedulePoolSize;
277     }
278
279     /**
280      * Cleanly disposes of the RenderHub's resources. Used by the RenderManager
281      * when the application shuts down.
282      */

283     public void dispose() {
284         if (renderService != null) {
285             renderService.shutdown();
286             renderService = null;
287         }
288
289         if (scheduledService != null) {
290             scheduledService.shutdown();
291             scheduledService = null;
292         }
293     }
294 }
295
Popular Tags