Skip to content

TaskScheduler does not work with TaskDecorator#23755

@ttddyy

Description

@ttddyy

TaskDecorator doesn't directly work with task scheduler implementations - ThreadPoolTaskScheduler/ConcurrentTaskScheduler.

Related: #18502

I think the underlying reason is there is no easy way of applying TaskDecorator to ScheduledExecutorService.

Currently, I workaround by wrapping ScheduledExecutorService with a proxy that performs task decoration.

Proxy Handler:

publicclassTaskDecoratingScheduledExecutorServiceInterceptorimplementsMethodInterceptor{privatefinalTaskDecoratortaskDecorator; publicTaskDecoratingScheduledExecutorServiceInterceptor(TaskDecoratortaskDecorator){this.taskDecorator = taskDecorator} @OverridepublicObjectinvoke(MethodInvocationinvocation) throwsThrowable{Object[] args = invocation.getArguments(); if (args.length == 0){returninvocation.proceed(); // no decoration, simply proceed } Objectswapped; if (args[0] instanceofRunnable){swapped = replaceRunnable(method, (Runnable) args[0])} elseif (args[0] instanceofCallable){swapped = replaceCallable(method, (Callable) args[0])} elseif (args[0] instanceofCollection){// see the ExecutorService APIswapped = ((Collection<? extendsCallable<?>>) args[0]).stream() .map(callable -> replaceCallable(method, callable)) .collect(toList())} else{returninvocation.proceed(); // bail out, no replace needed } args[0] = swapped; // swapreturninvocation.proceed()} .... }

Wrap created ScheduledThreadPoolExecutor in ThreadPoolTaskScheduler:

ThreadPoolTaskSchedulerscheduler = newThreadPoolTaskScheduler(){privateScheduledThreadPoolExecutorscheduledThreadPoolExecutor; @OverrideprotectedScheduledExecutorServicecreateExecutor(intpoolSize, ThreadFactorythreadFactory, RejectedExecutionHandlerrejectedExecutionHandler){// keep it for "getScheduledThreadPoolExecutor()"this.scheduledThreadPoolExecutor = (ScheduledThreadPoolExecutor) super.createExecutor(poolSize, threadFactory, rejectedExecutionHandler); ScheduledExecutorServiceexecutorService = this.scheduledThreadPoolExecutor; // apply task decorator via proxyProxyFactoryproxyFactory = newProxyFactory(executorService); proxyFactory.addAdvice(newTaskDecoratingScheduledExecutorServiceInterceptor(taskDecorator)); return (ScheduledExecutorService) proxyFactory.getProxy()} @OverridepublicScheduledThreadPoolExecutorgetScheduledThreadPoolExecutor() throwsIllegalStateException{returnthis.scheduledThreadPoolExecutor} }

I think it would be nice that ThreadPoolTaskScheduler/ConcurrentTaskScheduler to have some API to work with TaskDecorator OR a way to easily customize underlying ScheduledExecutorService to apply decorators.

For example, a delegate class that takes TaskDecorator:

publicclassTaskDecoratingScheduledExecutorServiceDelegateimplementScheduledExecutorService{privatefinalScheduledExecutorServicedelegate; privatefinalTaskDecoratortaskDecorator; ... }

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions