Есть ли способ зарегистрировать резервное удаление для ThreadLocal - PullRequest
0 голосов
/ 09 мая 2020

Я кодирую перехватчик для записи стоимости времени запроса. Я использовал ThreadLocal, чтобы создать время начала моего запроса в preHandler и использовать его в postHandler.code следующим образом:


    private final ThreadLocal<Long> inTimeLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MDC.put("traceId", UUID.randomUUID().toString());
        final long beforeHandler = System.currentTimeMillis();
        inTimeLocal.set(beforeHandler);
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        final long afterHandler = System.currentTimeMillis();
        long beforeHandler = inTimeLocal.get();
        inTimeLocal.remove();
        final long interval = afterHandler - beforeHandler;
        String traceId = MDC.get("traceId");
        Log.info("traceId:{},method:{},interval:{}",traceId,handler instanceof HandlerMethod ?((HandlerMethod) handler).getShortLogMessage():"",interval);
        super.postHandle(request, response, handler, modelAndView);
    }

, но если обработчик выдает исключение, postHandler не будет работать, в этом случае , я хочу зарегистрировать резервное удаление в ThreadLocal. Для этого я использую таймер. код вроде этого:

private final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(100, TimeUnit.MILLISECONDS);

    private final ThreadLocal<Long> inTimeLocal = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MDC.put("traceId", UUID.randomUUID().toString());
        final long beforeHandler = System.currentTimeMillis();
        inTimeLocal.set(beforeHandler);
        hashedWheelTimer.newTimeout(timeout->{
            inTimeLocal.remove();
        },65L,TimeUnit.SECONDS);

        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        final long afterHandler = System.currentTimeMillis();
        String traceId = MDC.get("traceId");
        long beforeHandler = inTimeLocal.get();
        final long interval = afterHandler - beforeHandler;
        Log.info("traceId:{},method:{},interval:{}",traceId,handler instanceof HandlerMethod ?((HandlerMethod) handler).getShortLogMessage():"",interval);
        super.postHandle(request, response, handler, modelAndView);
    }

Но таймер создал новый поток для обработки задачи. Таким образом, удаление не вступит в силу.

Есть ли способ зарегистрировать резервное удаление для ThreadLocal

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...