Search in sources :

Example 1 with TaskScheduler

use of io.micronaut.scheduling.TaskScheduler in project micronaut-core by micronaut-projects.

the class ScheduledMethodProcessor method process.

@SuppressWarnings("unchecked")
@Override
public void process(BeanDefinition<?> beanDefinition, ExecutableMethod<?, ?> method) {
    if (!(beanContext instanceof ApplicationContext)) {
        return;
    }
    List<AnnotationValue<Scheduled>> scheduledAnnotations = method.getAnnotationValuesByType(Scheduled.class);
    for (AnnotationValue<Scheduled> scheduledAnnotation : scheduledAnnotations) {
        String fixedRate = scheduledAnnotation.get(MEMBER_FIXED_RATE, String.class).orElse(null);
        String initialDelayStr = scheduledAnnotation.get(MEMBER_INITIAL_DELAY, String.class).orElse(null);
        Duration initialDelay = null;
        if (StringUtils.hasText(initialDelayStr)) {
            initialDelay = conversionService.convert(initialDelayStr, Duration.class).orElseThrow(() -> new SchedulerConfigurationException(method, "Invalid initial delay definition: " + initialDelayStr));
        }
        String scheduler = scheduledAnnotation.get(MEMBER_SCHEDULER, String.class).orElse(TaskExecutors.SCHEDULED);
        Optional<TaskScheduler> optionalTaskScheduler = beanContext.findBean(TaskScheduler.class, Qualifiers.byName(scheduler));
        if (!optionalTaskScheduler.isPresent()) {
            optionalTaskScheduler = beanContext.findBean(ExecutorService.class, Qualifiers.byName(scheduler)).filter(ScheduledExecutorService.class::isInstance).map(ScheduledExecutorTaskScheduler::new);
        }
        TaskScheduler taskScheduler = optionalTaskScheduler.orElseThrow(() -> new SchedulerConfigurationException(method, "No scheduler of type TaskScheduler configured for name: " + scheduler));
        Runnable task = () -> {
            io.micronaut.context.Qualifier<Object> qualifer = beanDefinition.getAnnotationTypeByStereotype(AnnotationUtil.QUALIFIER).map(type -> Qualifiers.byAnnotation(beanDefinition, type)).orElse(null);
            Class<Object> beanType = (Class<Object>) beanDefinition.getBeanType();
            Object bean = null;
            try {
                bean = beanContext.getBean(beanType, qualifer);
                if (method.getArguments().length == 0) {
                    ((ExecutableMethod) method).invoke(bean);
                }
            } catch (Throwable e) {
                io.micronaut.context.Qualifier<TaskExceptionHandler> qualifier = Qualifiers.byTypeArguments(beanType, e.getClass());
                Collection<BeanDefinition<TaskExceptionHandler>> definitions = beanContext.getBeanDefinitions(TaskExceptionHandler.class, qualifier);
                Optional<BeanDefinition<TaskExceptionHandler>> mostSpecific = definitions.stream().filter(def -> {
                    List<Argument<?>> typeArguments = def.getTypeArguments(TaskExceptionHandler.class);
                    if (typeArguments.size() == 2) {
                        return typeArguments.get(0).getType() == beanType && typeArguments.get(1).getType() == e.getClass();
                    }
                    return false;
                }).findFirst();
                TaskExceptionHandler finalHandler = mostSpecific.map(bd -> beanContext.getBean(bd.getBeanType(), qualifier)).orElse(this.taskExceptionHandler);
                finalHandler.handle(bean, e);
            }
        };
        String cronExpr = scheduledAnnotation.get(MEMBER_CRON, String.class, null);
        String fixedDelay = scheduledAnnotation.get(MEMBER_FIXED_DELAY, String.class).orElse(null);
        if (StringUtils.isNotEmpty(cronExpr)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Scheduling cron task [{}] for method: {}", cronExpr, method);
            }
            taskScheduler.schedule(cronExpr, task);
        } else if (StringUtils.isNotEmpty(fixedRate)) {
            Optional<Duration> converted = conversionService.convert(fixedRate, Duration.class);
            Duration duration = converted.orElseThrow(() -> new SchedulerConfigurationException(method, "Invalid fixed rate definition: " + fixedRate));
            if (LOG.isDebugEnabled()) {
                LOG.debug("Scheduling fixed rate task [{}] for method: {}", duration, method);
            }
            ScheduledFuture<?> scheduledFuture = taskScheduler.scheduleAtFixedRate(initialDelay, duration, task);
            scheduledTasks.add(scheduledFuture);
        } else if (StringUtils.isNotEmpty(fixedDelay)) {
            Optional<Duration> converted = conversionService.convert(fixedDelay, Duration.class);
            Duration duration = converted.orElseThrow(() -> new SchedulerConfigurationException(method, "Invalid fixed delay definition: " + fixedDelay));
            if (LOG.isDebugEnabled()) {
                LOG.debug("Scheduling fixed delay task [{}] for method: {}", duration, method);
            }
            ScheduledFuture<?> scheduledFuture = taskScheduler.scheduleWithFixedDelay(initialDelay, duration, task);
            scheduledTasks.add(scheduledFuture);
        } else if (initialDelay != null) {
            ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(initialDelay, task);
            scheduledTasks.add(scheduledFuture);
        } else {
            throw new SchedulerConfigurationException(method, "Failed to schedule task. Invalid definition");
        }
    }
}
Also used : ScheduledFuture(java.util.concurrent.ScheduledFuture) ScheduledExecutorTaskScheduler(io.micronaut.scheduling.ScheduledExecutorTaskScheduler) BeanContext(io.micronaut.context.BeanContext) LoggerFactory(org.slf4j.LoggerFactory) ExecutableMethod(io.micronaut.inject.ExecutableMethod) TaskExecutors(io.micronaut.scheduling.TaskExecutors) ApplicationContext(io.micronaut.context.ApplicationContext) Duration(java.time.Duration) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Argument(io.micronaut.core.type.Argument) ConversionService(io.micronaut.core.convert.ConversionService) ExecutorService(java.util.concurrent.ExecutorService) Logger(org.slf4j.Logger) Collection(java.util.Collection) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) Singleton(jakarta.inject.Singleton) PreDestroy(jakarta.annotation.PreDestroy) ExecutableMethodProcessor(io.micronaut.context.processor.ExecutableMethodProcessor) SchedulerConfigurationException(io.micronaut.scheduling.exceptions.SchedulerConfigurationException) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) StringUtils(io.micronaut.core.util.StringUtils) List(java.util.List) AnnotationUtil(io.micronaut.core.annotation.AnnotationUtil) Scheduled(io.micronaut.scheduling.annotation.Scheduled) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) Closeable(java.io.Closeable) Optional(java.util.Optional) TaskScheduler(io.micronaut.scheduling.TaskScheduler) BeanDefinition(io.micronaut.inject.BeanDefinition) Queue(java.util.Queue) TaskExceptionHandler(io.micronaut.scheduling.TaskExceptionHandler) ScheduledExecutorTaskScheduler(io.micronaut.scheduling.ScheduledExecutorTaskScheduler) TaskScheduler(io.micronaut.scheduling.TaskScheduler) BeanDefinition(io.micronaut.inject.BeanDefinition) Scheduled(io.micronaut.scheduling.annotation.Scheduled) ApplicationContext(io.micronaut.context.ApplicationContext) List(java.util.List) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Optional(java.util.Optional) Duration(java.time.Duration) ScheduledFuture(java.util.concurrent.ScheduledFuture) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) TaskExceptionHandler(io.micronaut.scheduling.TaskExceptionHandler) SchedulerConfigurationException(io.micronaut.scheduling.exceptions.SchedulerConfigurationException)

Aggregations

ApplicationContext (io.micronaut.context.ApplicationContext)1 BeanContext (io.micronaut.context.BeanContext)1 ExecutableMethodProcessor (io.micronaut.context.processor.ExecutableMethodProcessor)1 AnnotationUtil (io.micronaut.core.annotation.AnnotationUtil)1 AnnotationValue (io.micronaut.core.annotation.AnnotationValue)1 ConversionService (io.micronaut.core.convert.ConversionService)1 Argument (io.micronaut.core.type.Argument)1 StringUtils (io.micronaut.core.util.StringUtils)1 BeanDefinition (io.micronaut.inject.BeanDefinition)1 ExecutableMethod (io.micronaut.inject.ExecutableMethod)1 Qualifiers (io.micronaut.inject.qualifiers.Qualifiers)1 ScheduledExecutorTaskScheduler (io.micronaut.scheduling.ScheduledExecutorTaskScheduler)1 TaskExceptionHandler (io.micronaut.scheduling.TaskExceptionHandler)1 TaskExecutors (io.micronaut.scheduling.TaskExecutors)1 TaskScheduler (io.micronaut.scheduling.TaskScheduler)1 Scheduled (io.micronaut.scheduling.annotation.Scheduled)1 SchedulerConfigurationException (io.micronaut.scheduling.exceptions.SchedulerConfigurationException)1 PreDestroy (jakarta.annotation.PreDestroy)1 Singleton (jakarta.inject.Singleton)1 Closeable (java.io.Closeable)1