/* * <p> * 版权: ©2011 * </p> */ package org.young.isocket.filter; import java.io.IOException; import org.glassfish.grizzly.filterchain.BaseFilter; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.young.isocket.service.ServiceController; import org.young.isocket.service.ServiceRequest; import org.young.isocket.service.ServiceResponse; import org.young.isocket.threadpool.Job; import org.young.isocket.threadpool.JobDispatcher; import org.young.isocket.util.SocketKeys; /** * <p> * 描述:子定义线程池Filter * </p> * * @see * @author yangjun2 * @email yangjun1120@gmail.com * */ public class ThreadPoolFilter extends BaseFilter { private static final Logger logger = LoggerFactory .getLogger(ThreadPoolFilter.class); private JobDispatcher jobDispatcher; private static ServiceController serviceCtrl; public ThreadPoolFilter(JobDispatcher jobDispatcher) { this.jobDispatcher = jobDispatcher; serviceCtrl = new ServiceController(); } /** * Handle just read operation, when some message has come and ready to be * processed. * * @param ctx * Context of {@link FilterChainContext} processing * @return the next action * @throws java.io.IOException */ @Override public NextAction handleRead(FilterChainContext ctx) throws IOException { final FilterChainContext ctxTmp = ctx; // Peer address is used for non-connected UDP Connection :) final Object peerAddress = ctxTmp.getAddress(); final ServiceRequest message = ctxTmp.getMessage(); if (logger.isDebugEnabled()) logger.debug("address:{},message:{}", new Object[] { peerAddress, message }); if (message != null) {// import:message is not null! // Get the SuspendAction in advance, cause once we execute // LongLastTask in the // custom thread - we lose control over the context final NextAction suspendAction = ctxTmp.getSuspendAction(); // suspend the current execution ctxTmp.suspend(); jobDispatcher.execute(new Job() { public String getKey() { return message.getServiceId(); } public void run() { ServiceResponse response = null; try { response = serviceCtrl.invoke(message); } catch (Exception e) { if (serviceCtrl.isCommonService(message)) { response = new ServiceResponse(); response.setResponseCode(SocketKeys.RESPONSE_CODE_UNKNOWERROR); response.setResponseMessage(new StringBuffer().append( e.getMessage()).toString()); } else { logger.error( String.format( "notify service execute error,service id:%s ,reqid:%s,request:%s", message.getServiceId(), message.getId(), ""+message.getRequestObject()), e); } } try { if (serviceCtrl.isCommonService(message)) { // common service write back to client only. response.setTransformType(message.getTransformType()); // set the message null, to let our filter to // distinguish resumed context ctxTmp.setMessage(response); // write client address ctxTmp.write(peerAddress, response, null); } // set the message null, to let our filter to // distinguish resumed context ctxTmp.setMessage(null); // resume the context ctxTmp.resume(); } catch (Exception e) { logger.error("Job Thread execute error.", e); } } }); // return suspend status return suspendAction; } else {// resume message is null return ctx.getStopAction(); } } }