Micronaut @Scheduled job not running

Viewed 1473

I'm working on a existing micronaut application with groovy and gradle, which has a scheduler and is expected to run every 1 minute. Somehow the scheduler doesn't run at all, neither does the application throw any error (just stays silent). I don't see any reason why it shouldn't but i'm a newbie to micronaut and i might be missing something. Any pointer is appreciated, stuck with this issue from a long time now. Here is the scheduler class.

 @CompileStatic
 @Singleton
 @Requires(notEnv = "test")
 class CsmTestJob {

 private final CsmTestJobExecutor csmTestJobExecutor

 CsmTestJob(CsmTestJobExecutor csmTestJobExecutor) {
    this.csmTestJobExecutor = csmTestJobExecutor
 }

 @Scheduled(fixedDelay = '${feature.job.execute}')
 void executeCsmTests() {
    csmTestJobExecutor.executeCsmTests()
 }
}

Here is the application.yml file

micronaut:
  application:
    name: csm
  server:
    port: 8080
    host: 127.0.0.1

feature: 
  job:
    execute: "1m"
3 Answers

There have been comments about removing static compilation and removing the dynamic schedule value but I don't think either of those are likely to be relevant. There isn't enough code shown in the question to know for sure but I suspect your code may be using the wrong @Singleton annotation.

See the project at https://github.com/jeffbrown/nilambersinghscheduledjob.

https://github.com/jeffbrown/nilambersinghscheduledjob/blob/c7892b556c8564d34d1b3265f53c0f81904150aa/src/main/resources/application.yml

micronaut:
  application:
    name: nilambersinghscheduledjob
feature:
  job:
    execute: "1m"

https://github.com/jeffbrown/nilambersinghscheduledjob/blob/c7892b556c8564d34d1b3265f53c0f81904150aa/src/main/groovy/com/example/CsmTestJob.groovy

package com.example

import groovy.transform.CompileStatic
import io.micronaut.context.annotation.Requires
import io.micronaut.scheduling.annotation.Scheduled
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import javax.inject.Singleton

@CompileStatic
@Singleton
@Requires(notEnv = "test")
class CsmTestJob {

    private static final Logger log = LoggerFactory.getLogger(CsmTestJob)
    @Scheduled(fixedDelay = '${feature.job.execute}')
    void executeCsmTests() {
        log.debug "CSM Test Job Is Running"
    }
}

That all works fine.

I ran into a similar issue a while back and it turned out that one of the other annotations I had on the class was somehow interfering and preventing the scheduler from running.

I would try removing CompileStatic and also hard coding the schedule as a direct string literal.

Also make sure you are importing javax.inject.Singleton because otherwise your reference to Singleton will pick the groovy default groovy.lang.Singleton which will break micronaut mechanics.

A final thing to try is turning on debug logging and reading through the ton of information printed by micronaut. In my case I could see that there was an issue with bean initialization from the debug log.

I realize this is not a direct solution but figured it's better to give a few potential pointers than none at all.

I hit this problem running Micronaut in AWS Docker (EC2 Amazon) (I think also reproducible on 1 Core CPU)

Researh results:

  1. To reproduce run application with @Scheduler in Docker with option --cpus 1

    docker run --cpus 1 microscheduleapp

  2. It looks like Micronaut depends on ForJoinPool on launch, but default ForJoinPool will work if you have more than 1 CPU cores. In this condition Micronaut fails to instantiate Scheduled services. But manually started scheduled tasks work fine.

  3. To fix use ForkJoinPool parallelism option to allow pool to be more than CPU:

    java -Djava.util.concurrent.ForkJoinPool.common.parallelism=4 -jar application.jar

Related