18.6. delegate请求排队,让表格按指定顺序加载数据

据以往的经验可知,表格绘制完成后,会再自动发送一个ajax请求到后台去取到表格的数据。在3.2版本之前,这些请求得不到统一的管理,当页面有多个表格同时加载数据时,为保证每个表格能正确拿到自己的数据,需要在引擎的渲染期加同步锁,这会加重服务器的负担,同时存在可能,如果表格过多,那么后面的表格等待的时间过长,客户端就会因为超时而抛弃该取数请求。

在客户端对这些请求进行排队就不会出现这样的问题,只有前一个请求有响应了,下一个请求才会发送出去,服务器一次只处理一个表格的取数请求,同时请注意,该方式保证了每个表格都能正确取到数据,但串行的请求没有并行的效率高,因此需要权衡。

下面将说明如何使用该请求排队机制。首先必须在web.xml配置一个启动参数:

<context-param>
    <param-name>org.operamasks.faces.CLIENT_DELEGATE_QUEUE</param-name>
    <param-value>true</param-value>
</context-param>

这个配置说明了在本应用中,所有的delegate请求将会进行排队。有时某些页面需要做排队,而另外一些页面不必要做排队,那么该怎么办呢?需要下面的queueId解决该问题。

在每个页面的dataGrid或者tree中,可以单独为每个组件设置一个queueId,说明该组件被挂在queueId指定的队列上。每个队列内部会进行排队,队列之间不会进行排队管理。因此对那些不排队的页面,只需要为每个组件设置不同的queueId即可。下一版中将在<w:page>设置本页面delegate请求是否排队的开关。

<w:dataGrid  jsvar="gridJsvar1" paged="true" id="grid1" queueId="my_delegate_queue" queueTimeout="3" value="#{jira.bug845.test2Bean.companys}" >
    <w:outputColumn id="id" hidden="true" hidable="false" />
    <w:outputColumn id="name" width="150" align="center" sortable="true" header="公司" />
    <w:outputColumn id="leadingProduct" header="主打产品"/>
    <w:outputColumn id="address" width="150" header="地址" />
    <w:outputColumn id="phone" header="联系电话" />
    <w:outputColumn id="homepage" width="250" header="公司主页" />
    <w:pagingToolbar pageSize="10"  />
    </w:dataGrid>

上面代码定义的dataGrid被分配了queueId="my_delegate_queue",所以他的所有delegate请求会挂在my_delegate_queue这个队列上,如果没设置该属性则被挂在默认队列(delegate_request_load_queue_id)上。设置了queueTimeout,说明该delegate请求从队列中发出,到最后拿到响应,时间不能超过3s。该时间不包括在队列中等待的时间。

当开启了排队开关时:同页面的dataGrid和tree默认支持客户端排队,并且可以自行定义队列名字和超时时间;同一form内的多个上传组件会由引擎排队,因为他们封装在一个请求中,多个form的上传组件会在客户端排在独立的队列上,并且不能定义超时时间(默认设置了无穷大)。

推荐到官网示例《delegate请求排队》体验该示例。