Giter Site home page Giter Site logo

distributed-lock's Issues

Software license

I would love to use this library in one of our projects, but unfortunately there is no software license available in the repository. Therefore I can not use it. Would you be open to publishing this code under Apache 2.0, MIT or something similar?

Need a hand :) !

Hello!

I'm trying to use manually acquired and released locks, for a project that needs to release locks in other threads and async methods.
But, with the example code of acquiring :

@Qualifier("simpleMongoLock")
    @Autowired
    private final Lock lock;       
    private String acquireLock(String id) {
        final String token = lock.acquire(
                Collections.singletonList(id),
                "locks",
                LOCK_EXPIRATION
        );
        if (StringUtils.isEmpty(token)) {
            throw new IllegalStateException("Lock not acquired for id" + id);
        }
        return token;
    }

    public void releaseLock(String id, String token) {
        lock.release(
                Collections.singletonList(id),
                token,
                "locks"
        );
    }

And configuration :

import com.github.alturkovic.lock.mongo.configuration.EnableMongoDistributedLock;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableMongoDistributedLock
public class LockConfiguration {

}

I'm able to use distributed locking with annotations @MongoLocked, but not manually released, the lock never gets deleted from database, and even if it's expired, I'm not able to acquire it again !

And in the logs I see that when I try to release the lock just after acquiring it. The acquire is successful, but not the release!

c.g.a.lock.mongo.impl.SimpleMongoLock : Remove query did not affect any records for key

Does anybody ever tried this ?

Thank you!!

Spring Boot 2.2

Any plans to release a version that upgrades the Spring Boot dependency to 2.2?

Option not to throw exception on lock fail

Hi,

We have a use case where we run a cron on a Spring service spawned in multiple instances and we need to run it only on one instance. For this we use @RedisLocked and we expect that all of the locks will fail BUT the winning one. This is working now as expected, but the failing ones throw DistributedLockException in LockMethodInterceptor.invoke from method executeLockedMethod.

This is not the ideal case for us, as these exceptions are hard to catch in spring (@RedisLocked is on the same level as @Scheduled) and are not welcome in our usecase.

It would be nice to have an option on @RedisLocked annotation to suppress this exception and log it in warn instead. For example @RedisLocked(logFailedLock = true) or @RedisLocked(suppressFailure = true).

Cron is not the only usecase, this option can help any usecase that needs to lock across multiple instances without raising exceptions.

I am prepared to create PR for you.

Importing the whole library causes auto wiring issues in Spring Boot

The Problem
Using one of the out-of-the-box lock implementations, e.g. JDBC, BUT importing the whole library as per the readme, i.e.

<dependencies>
  <dependency>
    <groupId>com.github.alturkovic.distributed-lock</groupId>
    <artifactId>distributed-lock-redis</artifactId>
    <version>[insert latest version here]</version>
  </dependency>
</dependencies>

causes Spring Boot auto wiring issues during startup for the other implementations, e.g.1

"Spring Data MongoDB - Could not safely identify store assignment for repository candidate interface uk.co.news.applenews.respository.AppleNewsFailedReceiptRepository. If you want this repository to be a MongoDB repository, consider annotating your entities with one of these annotations: org.springframework.data.mongodb.core.mapping.Document (preferred), or consider extending one of the following types with your repository: org.springframework.data.mongodb.repository.MongoRepository."

and e.g.2

"Spring Data Redis - Could not safely identify store assignment for repository candidate interface uk.co.news.applenews.respository.AppleNewsFailedReceiptRepository. If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository."

Suggested Solution
Exclude the out-of-the-box lock implementations that aren't needed, e.g.

    implementation('com.github.alturkovic:distributed-lock:1.5.5'){
        exclude module: 'distributed-lock-example'
        exclude module: 'distributed-lock-mongo'
        exclude module: 'distributed-lock-redis'
    }

Wrong documentation

In the example of manual usage:

        lock.release(keys, token, storeId);

There should be

        lock.release(keys, storeId, token);

I tried to make PR, but it's too long way to do.

Allow re-entrant code within same Thread?

Currently a single Thread of execution cannot call the same @Locked method twice (or more) with the same parameter values. I think maybe this should be allowed as the Thread already 'owns' the first lock? Java's synchronized allows this.

It's happening to us where we override a @Locked method in a subclass and call super.method(), and it looks like distributed-lock's advice is run twice - first for the subclass's method call and then again when it calls its parent class's method with super.method().

Could we have retry and timeout added to simple locks for manual use

I used the following code stripped form the LockMethodInterceptor to get the retry/timeout functionality with a simple redis lock. It sure would be nice if it was part of the library.

`
private String getLockToken(List keys, String storeId, int retry, long timeOut, long expiration) {

    String token = null;
    try {
        token = constructRetryTemplate(retry, timeOut).execute(context -> {
            final String attemptedToken = lock.acquire(keys, storeId, expiration);

            if (StringUtils.isEmpty(attemptedToken)) {
                throw new LockNotAvailableException(
                        String.format("Lock not available for keys: %s in store %s", keys, storeId));
            }

            return attemptedToken;
        });
    } catch (final Exception e) {
        throw new DistributedLockException(String.format("Unable to acquire lock for keys: %s in store %s", keys, storeId), e);
    }
    return token;
}

private RetryTemplate constructRetryTemplate(int retryPeriodMs, long timeOutMs) {
    // how long to sleep between retries
    final FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
    fixedBackOffPolicy.setBackOffPeriod(retryPeriodMs);

    // when to timeout the whole operation
    final TimeoutRetryPolicy timeoutRetryPolicy = new TimeoutRetryPolicy();
    timeoutRetryPolicy.setTimeout(timeOutMs);

    // what exceptions to retry; only LockNotAvailableException, all other exceptions are unexpected and locking should fail
    final SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(Integer.MAX_VALUE, Collections.singletonMap(LockNotAvailableException.class, true));

    // combine policies
    final CompositeRetryPolicy compositeRetryPolicy = new CompositeRetryPolicy();
    compositeRetryPolicy.setPolicies(new RetryPolicy[]{timeoutRetryPolicy, simpleRetryPolicy});

    // construct the template
    final RetryTemplate retryTemplate = new RetryTemplate();
    retryTemplate.setRetryPolicy(compositeRetryPolicy);
    retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

    return retryTemplate;
  }

`

Would be nice to have Nullability annotations

For example I didn't realize that distributedLock.acquire(keyList, STORE_ID, expiration) could actually return null until it did.

Nullability annotations would make it nicer to work with this library from Kotlin, for example.

Of course not a deal breaker 😄 .

Null lock token versus LockNotAvailableException

Hi,

when acquiring a lock (manually), there seems to be some confusion as to what should happen when the lock is not acquired.

The documentation on the Lock interface states, that null will be returned from acquire(), but both implementations seem to be throwing an exception (LockNotAvailableException).

So I am not sure what to do: If I rely in the interface, my code will fail. If I rely on the implementation, it may change and fail, just in reverse.

Am I missing something?

JDBC lock not working with PSQL due to SQL syntax

Hi, the recent changes to the SQL query for MySql is causing PSQL syntax errors.

  public static final String ACQUIRE_FORMATTED_QUERY = "INSERT INTO `%s` (lock_key, token, expireAt) VALUES (?, ?, ?);";
  public static final String RELEASE_FORMATTED_QUERY = "DELETE FROM `%s` WHERE lock_key = ? AND token = ?;";
  public static final String DELETE_EXPIRED_FORMATTED_QUERY = "DELETE FROM `%s` WHERE expireAt < ?;";
  public static final String REFRESH_FORMATTED_QUERY = "UPDATE `%s` SET expireAt = ? WHERE lock_key = ? AND token = ?;";

It seems to be that the inclusion of " ` " is breaking PSQL syntax.

org.postgresql.util.PSQLException: ERROR: syntax error at or near "`"

Not too sure on a fix, but it looks like MySql and PSQL syntax are conflicting, would appreciate if you could look into this.
Thanks.

Unable to Pull New Version from Jitpack

Thanks for certifying the project on the latest version of the Spring Boot framework. Unfortunately, I am unable to pull the latest version for any of the packages. If I try to pull the following as specified by Jitpack, then I get an auth error.

<dependency>
    <groupId>com.github.alturkovic</groupId>
    <artifactId>distributed-lock</artifactId>
    <version>1.3.0</version>
</dependency>

I am still able to pull 1.2.2 without issue.

What is the reason behind only using JitPack?

I was about to start using this library for a project at the company I work for. But the first link on Google points to an issue in the Gradle repo where it is argued against using JitPack due to multiple security concerns. This is a show stopper for my company at least. And I imagine for many others as well. I can see that previous version were published on Maven Central. So the question is why stop using it?

Testing

Is there an easy way to test annotated methods in SpringBootTest?

I'd like to disable distributed-lock entirely, I tried with:

@Profile("!test")
@Configuration
@EnableJdbcDistributedLock
class DistributedLockConfiguration

But this fails at runtime

JDBC Manual Controlled Lock

Hi @alturkovic ,

Want to ask regarding the manually controlled locks, i saw the sample code as below but the method lock.acquire(keys, storeId, expiration, retry, timeout) is missing. I cant find acquire method with 5 params. Is it missing method on it ?

And May i know does it possible have dedicated method to check whether it is locked instead of use the lock.acquired method to check on return token value whether it is empty ? Appreciate your help. Thanks

@component
public class Example {

@Autowired
@Qualifier("simpleRedisLock")
private Lock lock;

// other fields...

private void manuallyLocked() {
    // code before locking...

    final String token = lock.acquire(keys, storeId, expiration, retry, timeout);

    // check if you acquired a token
    if (StringUtils.isEmpty(token)) {
        throw new IllegalStateException("Lock not acquired!");
    }

    // code after locking...

    lock.release(keys, token, storeId);

    // code after releasing the lock...
}

}

JDBC lock is not working with MySql due to wrong SQL syntax

I have created SQL table using the following script from the documentation:

CREATE TABLE lock (
    id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    lock_key varchar(255) UNIQUE,
    token varchar(255),
    expireAt TIMESTAMP,
    PRIMARY KEY(`id`)
);

After that I'm using the following code:

@JdbcLocked(prefix = "accountId", expression = "#accountId", storeId = "`lock`")

This result in the following exception:

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lock WHERE expireAt < '2022-08-21 19:20:56.016'' at line 1
	...
	com.github.alturkovic.lock.jdbc.service.SimpleJdbcLockSingleKeyService.acquire(SimpleJdbcLockSingleKeyService.java:51)
	at com.github.alturkovic.lock.jdbc.service.SimpleJdbcLockSingleKeyService$$FastClassBySpringCGLIB$$7d90f809.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	...

I manage to fix this in my code by overriding storeId:

@JdbcLocked(prefix = "accountId", expression = "#accountId", storeId = "`lock`")

In MySql 'lock' is keyword so if you are using this for table name you need to escape it. So every SQL query in SimpleJdbcLockSingleKeyService need to be scaped with `

like this:

  public static final String ACQUIRE_FORMATTED_QUERY = "INSERT INTO `%s` (lock_key, token, expireAt) VALUES (?, ?, ?);";
  public static final String RELEASE_FORMATTED_QUERY = "DELETE FROM `%s` WHERE lock_key = ? AND token = ?;";
  public static final String DELETE_EXPIRED_FORMATTED_QUERY = "DELETE FROM `%s` WHERE expireAt < ?;";
  public static final String REFRESH_FORMATTED_QUERY = "UPDATE `%s` SET expireAt = ? WHERE lock_key = ? AND token = ?;";

I will create a pull request for this

RedisLock throws RedisReadOnlyException when using RedisStaticMasterReplicaConfiguration and ReadFrom.REPLICA_PREFERRED

Hi!
I'm using a master/replica scheme with "read from replica" client property enabled.

var masterReplicaConfiguration =  new RedisStaticMasterReplicaConfiguration(masterNode.getHost(), masterNode.getPort());
redisProperties
    .getReplicas()
    .forEach(
        replica -> {
          RedisNode node = RedisNode.fromString(replica.getHost());
          masterReplicaConfiguration.addNode(node.getHost(), node.getPort());
        });

LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigBuilder =
    LettuceClientConfiguration.builder().readFrom(ReadFrom.REPLICA_PREFERRED);

It seems that "execute" is treated as a read operation by default, so it throws:

c.github.alturkovic.lock.exception.DistributedLockException: Unable to acquire lock with expression: #key
	at com.github.alturkovic.lock.advice.LockMethodInterceptor.executeLockedMethod(LockMethodInterceptor.java:77)
	at com.github.alturkovic.lock.advice.LockMethodInterceptor.invoke(LockMethodInterceptor.java:61)
	... 3 frames excluded
	...
Caused by: <#029e4a23> org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisReadOnlyException: READONLY You can't write against a read only replica. script: 15df23044ffd4f2723d9689555be4a5cccac4154, on @user_script:1.
	at o.s.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)

Potential problems with the algorithm

Hi!

Recently I decided to create a complete environment of Microservices architecture and implement some important concepts like Distributed Lock, with the goal to be a sandbox for everyone who wants to play with Microservices.

So, I created a repository simulating a Hotel Booking System.

After some researches I decided to use your lib to handle my distributed lock, but today one thread started around Distributed Lock Manager and I think your opinion will be really important for the community.

Here is the link: juliofalbo/complete-microservices-env#1

Thank you very much!

About throwing option added in recent PR

I was wondering why line 65 in the code block below is returning null instead of returning the result of the invocation.proceed() call.

} catch (DistributedLockException e) {
if (context.getLocked() != null && !context.getLocked().throwing()) {
log.warn("Cannot obtain lock for keys {} in store {}", context.getKeys(), context.getLocked().storeId(), e);
return null;
}
throw e;
} finally {

I assumed that the throwing option was added to call the target method rather than throwing a DistributedLockException when there's a problem with redis or a network failure, but seeing that it returns null, I'm wondering if my assumption is wrong.

More detailed examples

I'm trying to lock a couple of methods across jvm instances using Jdbc and Postgres.

So what I'm doing:

  • @EnableJdbcDistributedLock
  • creating the lock table:
CREATE TABLE lock
(
  id SERIAL,
  key VARCHAR(255) UNIQUE,
  token VARCHAR(255),
  expireAt TIMESTAMP
);
  • annotating my method with @JdbcLocked

But it doesn't work: Unable to acquire lock with expression: #executionPath.

I'd like to use simply the name of the method as a key, for start.
But I'm not really sure how to move from here 😅

Mongo distributed lock - expireAt not used

Hi,

Thanks for the implementation but I am wondering when the "expired" lock document are removed in the following code

final LockDocument doc = mongoTemplate.findAndModify(query, update, options, LockDocument.class, storeId);

Am I missing something?

By the way, I think I'll adapt your implementation to use ReactiveMongoTemplate.

Need a help

Dear Alen,

I've made a distributed-lock spring boot starter, replaced Lock implementation to redisson, but when i integrated it to my example project, it failed with an error which confused me a lot.
It seems that if LockBeanPostProcessor is instantiated before WebMvcAutoConfiguration, then this error would occur. And also, I've tried excluding AutoConfiguration from spring.factories files and using @EnableXXX, then it will be OK, i.e. LockBeanPostProcessor instance should be instantiated after WebMvcAutoConfiguration loaded.
From you doc, @EnableJdbcDistributedLock would be annotated in project, i wonder if this is the same situation.
I wanna if you could help me find a solution. Thx.

The components used
  • spring-boot-starter-web 2.3.7
  • redisson-spring-boot-starter 3.14.1
  • distributed-lock 1.4.0
The error before server started
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:637) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.7.RELEASE.jar:2.3.7.RELEASE]
	at cn.hrfax.redisson.RedissonApplication.main(RedissonApplication.java:17) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:652) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	... 20 common frames omitted
Caused by: java.lang.IllegalStateException: No ServletContext set
	at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:534) ~[spring-webmvc-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_261]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_261]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_261]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_261]
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	... 21 common frames omitted
Part of codes

image
image

Sincerely
Selwyn

`scriptExecutor` of `RedisTempate` is null

Hello,

I am getting this weird issue where scriptExecutor of RedisTempate when using the lock is null and hence creation of the lock is giving me a NPE. Here is how I create the lock

Lock Config

@Configuration
@EnableRedisDistributedLock
public class LockConfiguration {

    @Bean
    public Lock lock(@Value("${redis.lock.secret}") String secret) {
        return new SimpleRedisLock(() -> secret, new StringRedisTemplate());
    }
}

Cache Config

@Log4j2
@Configuration
public class CacheConfiguration {

    @Bean
    JedisConnectionFactory jedisConnectionFactory(@Value("${redis.host}") String host, @Value("${redis.port}") int port) {
        log.info("Connecting to Redis at: " + host);
        return new JedisConnectionFactory(new RedisStandaloneConfiguration(host, port));
    }

    /**
     * Configures template for serialization and deserialization of cache entries.
     * @return redis template
     */
    @Bean
    public RedisTemplate<String, List<String>> redisTemplate(@Value("${redis.host}") String host, @Value("${redis.port}") int port) {
        RedisTemplate<String, List<String>> template = new RedisTemplate<>();
        template.setValueSerializer(RedisSerializer.json());
        template.setKeySerializer(RedisSerializer.string());
        template.setConnectionFactory(jedisConnectionFactory(host, port));
        return template;
    }
}

Usage of lock

@Log4j2
@Repository
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class EventKeysCache {

    private final RedisTemplate<String, String> redisTemplate;
    private final StringRedisTemplate stringRedisTemplate;
    private final Lock lock;
    @Value("${redis.lock.expiration}")
    private Integer expiration;
    @Value("${redis.lock.secret}")
    private String lockSecret;
    @Value("${redis.lock.collection}")
    private String lockCollection;


    public void createLock(String eventFilter) {
        log.info("Creating lock for eventFilter: " + eventFilter);
        try {
            lock.acquire(Collections.singletonList(eventFilter), lockCollection, expiration);
        } catch (Exception e) {
            log.info("Failed to acquire lock for eventFilter: " + eventFilter + e.getMessage() + e.getStackTrace().toString());
        }
    }

    public void releaseLock(String eventFilter) {
        log.info("Releasing lock for eventFilter: " + eventFilter);
        lock.release(Collections.singletonList(eventFilter), lockCollection, lockSecret);
    }
}

Screen Shot 2022-04-29 at 1 51 38 PM

The weird thing is this was working before, so not sure what I could be doing wrong. Any help will be highly appreciated.

Thanks

Testing Annotated Locks

Hi,

I'm struggling to test the annotated locks. I've tried everything under the sun to get it to work but I cannot seem to get anything working.

It doesn't seem the annotation is working what so ever under test conditions (as evidenced by the fact, even when changing the storeId to one that doesn't exist nothing happens).

I've tried annotating the test class with @EnableJdbcDistributedLock even though my Application file already has this annotation. When the method is called it is not triggering the annotation at all.

I've tried annotating the method that I would like locked with both @Locked and @JdbcLocked of which neither made any difference.

I tried to create a very simple test to remove any doubt:

    @JdbcLocked(expression = "#p0")
    public void fakeMethod(UUID id) {
        log.debug("Fake method called! {}", id);
    }
    @Test
    public void simpleTest() {
        testService.fakeMethod(UUID.randomUUID());
    }

This should fail, since I don't even have a DB table available for this lock, yet it is not doing anything.

Any advice for testing the annotations would be greatly appreciated.

Spring Boot version 3.1.9 (tested with 3.1.5 too just in case)
Distributed Lock Version: 'com.github.alturkovic.distributed-lock:distributed-lock-jdbc:2.1.0'

Getting Started

Hi @alturkovic and co.,

Thank you for creating this project - I'm a recently graduated student and am looking to learn more about locks and concurrency for an upcoming project I'm doing. This has been very inspiring and cool!

I have been having some issues getting this setup and in understanding how to run the examples and test cases in the project.

I have cloned the repo, and attempted to use "mvn spring-boot:run" to run the examples but I get a host of errors. I am not sure exactly how to run the examples or test cases and would appreciate any guidance you might be able to give. I.e. does the project contain a dummy or example distributed system that this locking tool is used on?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.