Netty - 通过ExecutionHandler.handleUpstream继续处理消息

时间:2013-05-01 20:50:08

标签: netty

我需要能够在单独的线程中隔离某些处理。只有某些消息需要此额外处理。它确实涉及本地呼叫和远程资源;因此,我真的希望能够使用我自己的线程池/队列来严格控制这个处理。

我的初始实现使用ThreadPoolExecutor,可以从我的ChannelHandler访问。一旦我的处理程序识别出需要特殊处理的消息,我就将我的Worker提交给Executor进行处理。注意,我确实看到post关于扩展ExecutionHandler并在那时进行过滤,但我想仍然会遇到同样的问题。

问题在工作进程完成后,我希望消息在我的管道中定义的ExecutionHandler / ThreadPool中继续。因此,释放“工人”线程;再次,工作线程池在队列大小,最大线程等方面有严格的限制。

下面是我的工作者(我的ChannleHandler的内部类)。接下来,我得到管道中使用的ExecutionHandler并调用handleUpstream方法。似乎对我有用,但想知道是否有任何我不考虑的隐藏问题...

public class EncryptionWorker implements Runnable
{
    private ChannelHandlerContext _ctx;
    private MessageEvent _e;

    public EncryptionWorker(ChannelHandlerContext ctx, MessageEvent e)
    {
        _ctx = ctx;
        _e = e;
    }

    @Override
    public void run()
    {
        Object m = _e.getMessage();
        if ( !( m instanceof AESSLMessageCtx ) )
        {            
            LOGGER.error( "Invalid Message sent to EncryptionWorker.");
            return;
        }
        AESSLMessageCtx msgContext = (AESSLMessageCtx) m;

        LOGGER.info( "EncryptionWorker initiated, id: " + msgContext.getIdentifier());

        // TODO - Process the  Message.      
        try 
        {
            // Encryption needs to be isolated from main pipeline.
            // Only occurs for special messages; could block for
            // a period of time; do not want it affecting normal
            // traffic.
            //.......
            Thread.sleep( 2000 );
        }
        catch (Exception ex)
        {
            LOGGER.warn( "Exception processing encrypted message, id: " +  msgContext.getIdentifier(), ex );
            sendError( _ctx.getChannel(), msgContext, TxnMessageCtx.ErrorReason.SYSLEVEL_ERROR );
            return;
        }

        // Continue processing message as normal....
        // Do not want to do "_ctx.sendUpstream( _e )"
        // because it continues to use my EncryptionWorker Thread.
        // I would rather do something like the following in order to
        // get it back into service pipeline Executor Threadpool.

        // Get ExecutionHandler being used in pipeline.
        ChannelHandler ch = _ctx.getPipeline().get( "executor" );
        if (ch == null || !(ch instanceof ExecutionHandler))
        {
            LOGGER.error( "ExecutionHandler not found.");
            return;                
        }
        ExecutionHandler execHandler = (ExecutionHandler) ch;

        try
        {
            // Use ExecutionHandler Executor to continue processing
            execHandler.handleUpstream( _ctx, _e );
        }
        catch (Exception ex)
        {
            LOGGER.error( "Exception initiating upstream handling after encryption processing, tpdu: " + txnContext.getIdentifier(), ex );
            sendError( _ctx.getChannel(), msgContext, TxnMessageCtx.ErrorReason.SYSLEVEL_ERROR );
            return;                
        }

        return;
    }
}

0 个答案:

没有答案