领导说,我们不能绑定在某个产品,某个框架,某个技术实现上。所以当我们希望使用 jetty 的 continuation 技术的时候,我们必须对它进行一个包装,以保证将来如果需要,我们可以用其它的技术或框架进行替换。
一个简单的包装:
TaskManager 类:
以下是代码片段: /** * submit a task async * * @param request * @param response * @param task * @return result true for first submit task, false for expire or exception */ public static boolean submitTask(final HttpServletRequest request, final HttpServletResponse response, final AbstractContinuation task) { final Continuation continuation = ContinuationSupport .getContinuation(request); if (continuation.isExpired()) { @SuppressWarnings("unchecked") final FutureTask ftask = (FutureTask) request .getAttribute(TASK_FUTURE); if (ftask != null) { // not Interrupt if it is still running ftask.cancel(false); } task.onExpire(request, response); return false; } // first call of this request continuation.setTimeout(ContinuationConfig.timeout); continuation.suspend(response); try { final FutureTask ftask = new FutureTask(task) { @Override protected void done() { // cancelled, just return if (isCancelled()) { return; } // expired, just return if (continuation.isExpired()) { return; } // complete, so *NO* attribute will take effects // request.setAttribute(TASK_RESULTS, get()); try { final Object result = get(); task.onResult(request, response, result); } catch (final Exception e) { task.onException(request, response, e); } continuation.complete(); } }; exec.submit(ftask); request.setAttribute(TASK_FUTURE, ftask); return true; } catch (final TooManyWaitingTaskException e) { task.onException(request, response, e); return false; } } /** * submit a task sync, with *NO* expire support * * @param request * @param response * @param task * @return result true for first submit task, false for expire or exception */ public static boolean submitTask2(final HttpServletRequest request, final HttpServletResponse response, final AbstractContinuation task) { try { final Object result = task.call(); task.onResult(request, response, result); return true; } catch (final TooManyWaitingTaskException e) { task.onException(request, response, e); return false; } catch (final Exception e) { task.onException(request, response, e); return false; } } |
servlet 里面可以这样调用:(注意,当前不支持 jsp )
以下是代码片段: @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { // create an asynchronous task final AbstractContinuation task = new AbstractContinuation() { @Override public Object call() throws Exception { // do the job } @Override public void onResult(final HttpServletRequest request, final HttpServletResponse response, final Object result) { // has result, so ignore all exception // do output } @Override public void onExpire(final HttpServletRequest request, final HttpServletResponse response) { try { response.sendError(504, "continuation job expired"); log.warn("on expire:" + request); } catch (final IOException e) { log.warn("exception on expire: " + request + e.getMessage()); } return; } @Override public void onException(final HttpServletRequest request, final HttpServletResponse response, final Exception e) { try { response.sendError(503, "some exception occured "); log.warn("on exception:" + request, e); } catch (final IOException ioe) { log.warn("exception on exception: " + request + e.getMessage() + ioe.getMessage()); } return; } }; if (TaskManager.submitTask(request, response, task)) { // first submit // do nothing here } else { // expire, or exception // just ignore here, because we have dealed with it other place } return; } |