IT技术博客大学习 共学习 共进步

关于 Jetty Continuation

福林雨-博客 2010-12-30 22:49:17 浏览 3,422 次

领导说,我们不能绑定在某个产品,某个框架,某个技术实现上。所以当我们希望使用 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;
    }

建议继续学习

  1. 如何寻找一个不会让你后悔的PHP开发框架 (阅读 6,501)
  2. Netty和Jetty的Java NIO 网络框架模型分析 (阅读 5,460)
  3. 对于PHP大型开发框架的看法 (阅读 5,121)
  4. Apache + Jetty 架设 CAS 单点登录 (阅读 5,060)
  5. 也谈谈前端,架构,框架与库 (阅读 4,961)
  6. 异步编程与响应式框架 (阅读 4,880)
  7. 自己写的一个轻量级javascript框架的设计模式 (阅读 4,760)
  8. PHP API 框架开发的学习 (阅读 4,721)
  9. 服务框架演变过程 (阅读 4,601)
  10. Jetty线程“互锁”导致数据传输性能降低问题分析 (阅读 4,321)