@Override
 protected void before() throws Throwable {
   threadContextHolder = new ThreadContextHolder(restoreMap, restoreStack);
   if (restoreMap) {
     ThreadContext.clearMap();
   }
   if (restoreStack) {
     ThreadContext.clearStack();
   }
 }
 @Override
 @SuppressWarnings("unchecked")
 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
   if (matcher.match(msg)) {
     final I typedMsg = (I) msg;
     try {
       if (quotaMeter.getOneMinuteRate() > USER_QUOTA_LIMIT) {
         sendErrorResponseIfTicked(typedMsg.id);
         return;
       }
       quotaMeter.mark();
       messageReceived(ctx, handlerState, typedMsg);
     } catch (Exception e) {
       handleGeneralException(ctx, e);
     } finally {
       ThreadContext.clearMap();
       ReferenceCountUtil.release(msg);
     }
   }
 }