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