【rose】portal

rose的portal是一个非常不错的web服务端技术

传统的web服务器对一个request请求的处理是串行的
只有所有逻辑处理完后才返回数据给页面渲染
这样的好处固然简单,但是也有极为严重的缺陷
如果其中一段代码发生异常将可能造成请求处理中断,直接导致500错误

而rose的portal技术则是一种并发的web服务端技术
这里所讲的并发是指portal将request的处理分成了多个并发处理的window
portal把控整个处理过程,并分发处理请求给每个window
每个window只负责处理自己的逻辑
页面渲染时所需要的数据也由对应的window提供,最终的请求返回由portal控制

详细的rose-portal介绍可点击这里 http://code.google.com/p/paoding-rose/wiki/Rose_Portal_Demo

portal使用的是多线程的思想来实现这个并发处理的portal、window机制


//portal的使用是基于rose的,同样也是一个controller ,如下所示
public class ShowController {
       // 标注@Get,表示这个方法要处理的是对/portal的GET请求
    // 在主控控制方法上声明Portal参数即表示这个页面是portal,就这样!
    @Get
    @PortalSetting(timeout = 3000000)
    public String home(Invocation inv, Portal portal) throws Exception {
      
        // 使用addWindow向这个portal页面加入各种子信息(我们成为窗口)
        portal.addWindow( "weather", "/windows/weather" );
        // 第一个参数是用于标识该窗口,使得portal页面中可以引用到这个窗口的 html
        // 第二个参数表示这个窗口的地址(可以包含参数),这个地址等价于forward的地址(也就是这里只要能forward的地址都可以,无论是否是rose框架的,甚至可以是一个 jsp页面)
        // 因此,地址没有说一定要以"/windows"开始
        portal.addWindow( "todo", "/windows/todo?name=value" );
               
        inv.addModel( "word", "hello world" );  

        return "portal-home";
    }
}
//可以把portal想象成我们要渲染的页面,每个window就是页面中的一个模块
//portal.addWindow 把各个页面模块添加到portal 中


//下面是addWindow 的代码实现
//这里可以看到window 实现的整个过程:
//创建window实例、并创建window处理任务,最终会交由executorService 来执行
public Window addWindow(String name, String windowPath, Map<String, Object> attributes) {
        // 创建 窗口对象
        WindowImpl window = new WindowImpl((PortalImpl) this, name, windowPath);

        //
        if (attributes != null) {
            synchronized (attributes) {
                for (Map.Entry<String, Object> entry : attributes.entrySet()) {
                    window.set(entry.getKey(), entry.getValue());
                }
            }
        }

        // 定义窗口任务
        WindowTask task = new WindowTask(window);

        // 注册到相关变量中
        synchronized (windows ) {
            this.windows .add(window);
        }
        this.invocation .addModel(name, window);

        // 事件侦听回调
        onWindowAdded(window);

        // 提交到执行服务中执行
        Future<?> future = submitWindow( this.executorService , task);
        window.setFuture(future);

        // 返回窗口对象
        return window;
    }

//window 对象实例化过程主要是设置portal 控制器、window自身的属性如name、path
// 另外很重要的就是设置window的request和response对象,这是非常出色和有趣的构建
public WindowImpl(PortalImpl portal, String name, String windowPath) {
        this.portal = portal;
        this.name = name;
        this.path = windowPath;
        this.request = new WindowRequest(portal.getRequest());
        this.response = new WindowResponse( this);
    }

// 有了window实例,就可以创建对应的window task
final class WindowTask implements Runnable {

    private static final Log logger = LogFactory.getLog(WindowTask.class);

    private final WindowImpl window ;

    public WindowTask (WindowImpl window) {
        if (window == null) {
            throw new NullPointerException("window");
        }
        this.window = window;
    }

    public WindowImpl getWindow() {
        return window ;
    }

// 可以看到,一个window task 是一个转发请求
// 通过这样的方式来细分化一个request请求,这样的切分思想实在是充满了智慧
    @Override
    public void run() {
        try {
            // started
            window.getPortal().onWindowStarted(window );

            // doRequest
            final HttpServletRequest request = window .getRequest();
            final RequestDispatcher rd = request.getRequestDispatcher(window .getPath());
            request.setAttribute( "$$paoding-rose-portal.window" , window);
            rd.forward(request, window.getResponse());

            // done!
            window.getPortal().onWindowDone(window );
        } catch (Throwable e) {
            logger.error("" , e);
            window.setThrowable(e);
            window.getPortal().onWindowError(window );
        }
    }
          .......
}
// 每个window task请求会交由一个新的线程去处理
// 这个多线程的任务机制是由executor框架来管理的
protected Future<?> submitWindow(ExecutorService executor, WindowTask task) {
        Future<?> future = executor.submit(task);
        return new WindowFuture(future, task.getWindow());
    }
// 转发后的请求将会重新走一遍rosefilter的处理流程


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值