Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ShedLock: Running multiple instances runs scheduler tasks multiple times

I am using Shedlock to run my scheduler task only once if multiple instances of the service are running.

I followed the documentation and this is what I did.

This is the function that needs to run periodically

@Scheduled(fixedDelayString = "300000")
@SchedulerLock(name = "onlineIngestionTask", lockAtMostFor = 240000, lockAtLeastFor = 240000)
public void pullTasksFromRemote() {
        //Code
}

In my config class I have the following beans

@Bean
public ScheduledLockConfiguration taskScheduler(LockProvider lockProvider) {
    return ScheduledLockConfigurationBuilder
        .withLockProvider(lockProvider)
        .withPoolSize(10)
        .withDefaultLockAtMostFor(Duration.ofMinutes(10))
        .build();
}



@Bean
public LockProvider lockProvider(DataSource dataSource) {
    return new JdbcTemplateLockProvider(dataSource);
}

The pom includes

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>0.14.0</version>
</dependency>

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>0.14.0</version>
</dependency>

I added a table to my db, the one to which jdbc connects.

CREATE TABLE shedlock(
    name VARCHAR(64), 
    lock_until TIMESTAMP(3) NULL, 
    locked_at TIMESTAMP(3) NULL, 
    locked_by  VARCHAR(255), 
    PRIMARY KEY (name)
) 

After this I tried to test the functionality by running tha pp first on port 8080. Then I use server.port=9000 to run it again on port 9000. But both these instances start running the task. Am I missing something. Is something wrong in the implementation? Can someone give any ideas. Thanks !!

like image 987
varunkr Avatar asked Aug 08 '17 07:08

varunkr


People also ask

How does ShedLock work internally?

ShedLock makes sure that your scheduled tasks are executed at most once at the same time. If a task is being executed on one node, it acquires a lock which prevents execution of the same task from another node (or thread).

How does Spring ShedLock work?

ShedLock is a distributed lock for scheduled tasks. It ensures a task is only executed once at the same time. Once the first Spring Boot instance acquires the lock for a scheduled task, all other instances will skip the task execution.

Can we have multiple scheduler in spring boot?

We can choose to delay the first execution of the method by specifying the interval using the initialDelay attribute. We can deploy multiple Scheduler Instances using the ShedLock library which ensures only one instance to run at a time by using a locking mechanism in a shared database.


3 Answers

dlock guarantees to have one lock at any time by using database indexes and constraints. You can simply do something like below.

@Scheduled(cron = "30 30 3 * * *")
@TryLock(name = "onlineIngestionTask", owner = SERVER_NAME, lockFor = 240000)
public void pullTasksFromRemote() {

}

See the article about using it.

like image 55
Will Hughes Avatar answered Oct 03 '22 20:10

Will Hughes


we recently had this issue in prod where we could see multiple runs of shedlock schedulers. if you are using spring boot 2.2.1.RELEASE onwards then use below deps for shedlock

<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.9.3</version>
</dependency>

    <dependency>
        <groupId>net.javacrumbs.shedlock</groupId>
        <artifactId>shedlock-provider-redis-spring</artifactId>
        <version>4.8.0</version>
    </dependency>
like image 45
user1973594 Avatar answered Oct 03 '22 20:10

user1973594


Please try with cron expression inside @scheduled instead of fixedDelayString, below scheduler run every hour.

@Scheduled(cron = "0 */1 * * *")
like image 23
Ramesh Kandari Avatar answered Oct 03 '22 18:10

Ramesh Kandari