IT/Spring

@Async, @Scheduled, ListenableFuture Exception handling

최고영회 2022. 3. 28. 08:15
728x90
반응형
SMALL

별도의 Thread 로 동작하는 method 에서 발생하는 예외는 어떻게 처리해야 할까?

적절한 처리가 없을 경우 오류 발생 시 로그조차 기록되지 않아 큰 문제가 될 수 있다. 

 

@Async

- Async annotation 을 이용할 경우 보통 AsyncConfigurer 를 implements 하여 Thread-pool 을 정의 해 주는 것이 좋다. 

- AsyncConfigurer 를 implements 할 때 getAsyncUncaughtExceptionHandler 를 Override 하여 작성한다. 

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return (ex, method, params) -> {
        log.error("Throwable Exception message : {}", ex.getMessage());
        log.error("Method name : {}", method.getName());
        for (Object param : params) {
            log.error("Parameter value: {}", param);
        }
        log.error("stack Trace ", ex);
    };
}

 

@Scheduled

- Scheduled annotation 을 이용할 경우에도 SchedulingConfigurer 를 implements 하여 Thread-pool 을 정의 해 주는 것이 좋다.

- ThreadPoolTaskScheduler 의 setErrorHandler method 가 있으니 이 메서드를 이용하면 된다. 

@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
    ThreadPoolTaskScheduler task = new ThreadPoolTaskScheduler();

    task.setPoolSize(prop.getPoolSize());
    task.setThreadNamePrefix("schedule-thread-");
    task.setErrorHandler(ex -> log.error("Exception in task", ex));
    task.initialize();

    taskRegistrar.setTaskScheduler(task);
}

 

ListenableFuture 

Async method 에서 ListenableFuture 를 return 하는 경우 위와 같이 AsyncConfigurer, ShcedulingConfiurer 에서 로그를 기록하더라도 로그가 남지 않는다. 

ListenableFuture 를 사용하는 이유는 보통 callback 에서 어떤 처리를 하기 위함이고 FailureCallback 을 parameter 로 받는 addCallback method 가 정의되어 있기 때문에 이 부분에서 처리 해야 한다. 

간단히 로그만 기록해 보자. 

analyzer.analyze(req).addCallback(s -> progress(), e -> {log.error("", e); progress();});

 

728x90
반응형
LIST