ShedLock icon indicating copy to clipboard operation
ShedLock copied to clipboard

Provide more generic lock annotation for non scheduler based contexts

Open holgerstolzenberg opened this issue 3 years ago • 7 comments

We are using ShedLock in our projects and like it pretty much. It's very mature and neatly integrated.

Yesterday I came to the point where I needed a distributed lock in a non scheduler based context.

The use case is to create database table partitions on startup of an Spring boot app by a method annotated with @EventListener(ApplicationStartedEvent.class).

@Transactional
@EventListener(ApplicationStartedEvent.class)
@SchedulerLock(name = INIT_PARTITIONS_LOCK_NAME)
public void init() {
  // lock might not be there for tests where scheduling is disabled
  if (isLockProviderAvailable()) {
    LockAssert.assertLocked();
    log.debug("Distributed lock for partition creation has been obtained");
  }

  log.info("Creating necessary partitions on startup...");
  service.forPartitionCreation().forEach(this::createPartition);
  log.info("All partitions have been successfully created");
}

I know that ShedLock is primarily designed for scheduler based stuff, but I gave it a shot and tried to use it as a "regular" distributed lock for the partition creation. What can I say - it worked.

From this situation a few thoughts arise that might end in a feature request for this project or just documentation stuff, so please forgive me if that is not a typical Github issue.

These are the points that I am thinking about:

  • Is it safe to use @SchedulerLock without @Scheduled
  • If so - is scope of ShedLock much broader than it is advertised for at the moment
  • If so - would it be possible to provide a more generic annotation for the given purpose, e.g. @DistributedLock
  • What other options do we have

Sure I could add another framework for providing the distributed lock or implement something custom in our code base. But why if ShedLock already has everything in its package? Looking at for example https://github.com/alturkovic/distributed-lock you can see that it is pretty close to what ShedLock offers but require an extra lock table if used with JDBC.

I'd rather like to start a discussion upon this to decide whether to actually add a refined issue. If you see a better place to post this, please tell me.

holgerstolzenberg avatar Feb 01 '22 11:02 holgerstolzenberg

Update:

For the moment I use a pseudo annotation:

package de.dehst.platform.waiting.area.service.core;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.core.annotation.AliasFor;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Inherited
@Retention(RUNTIME)
@Target(METHOD)
@SchedulerLock
public @interface DistributedLock {
  @AliasFor(annotation = SchedulerLock.class) String name();
}

That way it looks a bit cleaner at the places where it gets declared.

holgerstolzenberg avatar Feb 02 '22 07:02 holgerstolzenberg

JFYI We are using shedlock in production without @Scheduled annotation, because we have dynamic jobs. Works amazing.

Aloren avatar Feb 03 '22 19:02 Aloren

Thanks for feedback. The workaround with the pseudoanotation is a grat idea. I have to think about it. I do not want to ofically declare that it's possible to use it as a generic "lock".

I am afraid that there will be some new edgecases which will force me to bend the library.

Morover, I do not know how to call it. It's not a lock. If it's not available, the process does not wait but just skips the execution. Any ideas about the name?

lukas-krecan avatar Feb 03 '22 19:02 lukas-krecan

Having 'TryLock' in the name seems to be the most popular way to convey a lock does not wait. E.g. in java.util.concurrent.locks

EnTaroJankov avatar Mar 29 '22 22:03 EnTaroJankov

how about skip lock or no wait lock? https://dev.mysql.com/blog-archive/mysql-8-0-1-using-skip-locked-and-nowait-to-handle-hot-rows/

@lukas-krecan

KSH-code avatar Feb 09 '23 06:02 KSH-code

@lukas-krecan Hi, is there any support plan about MySQL nowait Option?

pkgonan avatar Jun 30 '23 07:06 pkgonan

No, as I understand it nowait can be used only in selects for update. ShedLock only uses INSERT and UPDATE

lukas-krecan avatar Jun 30 '23 07:06 lukas-krecan