Skip to content

Commit 7f914b5

Browse files
committed
1.3.0
- CHANGE: Updated Java from 1.8 to 11 - CHANGE: Refactored lots of coupled code - CHANGE: Extracted lots of reusable components such as retriable locks for easier manual control of locks - BUGFIX: `LockBeanPostProcessor` will now fire after existing advisors to support transactional advisors
1 parent 9f8117b commit 7f914b5

File tree

66 files changed

+921
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+921
-432
lines changed

.idea/codeStyles/Project.xml

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.adoc

+14-1
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,22 @@ public class LockConfiguration {
124124

125125
Started tracking the changes since 1.2.0 so no changelogs available for earlier versions.
126126

127+
==== 1.3.0
128+
129+
- CHANGE: Updated Java from 1.8 to 11
130+
- CHANGE: Refactored lots of coupled code
131+
- CHANGE: Extracted lots of reusable components such as retriable locks for easier manual control of locks
132+
- BUGFIX: `LockBeanPostProcessor` will now fire after existing advisors to support transactional advisors
133+
127134
==== 1.2.2
135+
128136
- CHANGE: Removed explicit `ParameterNameDiscoverer` from `SpelKeyGenerator` which now uses the one provided by the `CachedExpressionEvaluator`
129137
- CHANGE: Used `AopUtils` once and passed the evaluated method to `SpelKeyGenerator` so it doesn't have to evaluate the same thing as `LockMethodInterceptor`
130138

131139
==== 1.2.1
132-
- FEATURE: Lock refreshing has been added. Check the 'Lock refresh' chapter for more details
140+
141+
- FEATURE: Lock refreshing has been added.
142+
Check the 'Lock refresh' chapter for more details
133143
- BUGFIX: `@RedisMultiLocked` was using `#executionPath` as prefix instead of an expression
134144
- BUGFIX: `@RedisMultiLocked` was using `expiration` and `timeout` in milliseconds instead of seconds
135145

@@ -169,6 +179,9 @@ Started tracking the changes since 1.2.0 so no changelogs available for earlier
169179

170180
|1.2.2
171181
|2.1.0.RELEASE
182+
183+
|1.3.0
184+
|2.2.7.RELEASE
172185
|===
173186

174187
=== Maven

distributed-lock-api/pom.xml

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ MIT License
4+
~
5+
~ Copyright (c) 2020 Alen Turkovic
6+
~
7+
~ Permission is hereby granted, free of charge, to any person obtaining a copy
8+
~ of this software and associated documentation files (the "Software"), to deal
9+
~ in the Software without restriction, including without limitation the rights
10+
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
~ copies of the Software, and to permit persons to whom the Software is
12+
~ furnished to do so, subject to the following conditions:
13+
~
14+
~ The above copyright notice and this permission notice shall be included in all
15+
~ copies or substantial portions of the Software.
16+
~
17+
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
~ SOFTWARE.
24+
-->
25+
226
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
327
xmlns="http://maven.apache.org/POM/4.0.0"
428
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -7,7 +31,7 @@
731
<parent>
832
<groupId>com.github.alturkovic</groupId>
933
<artifactId>distributed-lock</artifactId>
10-
<version>1.2.2</version>
34+
<version>1.3.0</version>
1135
</parent>
1236

1337
<artifactId>distributed-lock-api</artifactId>

distributed-lock-api/src/main/java/com/github/alturkovic/lock/Interval.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal

distributed-lock-api/src/main/java/com/github/alturkovic/lock/Lock.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -27,6 +27,7 @@
2727
import java.util.List;
2828

2929
public interface Lock {
30+
3031
/**
3132
* Try to acquire the lock.
3233
*

distributed-lock-api/src/main/java/com/github/alturkovic/lock/Locked.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -59,9 +59,9 @@
5959
String expression() default "#executionPath";
6060

6161
/**
62-
* Lock expiration interval. This indicates how long the lock should be considered and when it should be invalidated. If {@link #refresh()}
63-
* is positive, lock expiration will periodically be refreshed. This is useful for tasks that can occasionally hang for longer than their
64-
* expiration. This enables long-running task to keep the lock for a long time, but release it relatively quickly in case they fail.
62+
* Lock expiration interval. This indicates how long the lock should be considered locked after acquiring and when it should be invalidated.
63+
* If {@link #refresh() is positive, lock expiration will periodically be refreshed. This is useful for tasks that can occasionally hang for
64+
* longer than their expiration. This enables long-running task to keep the lock for a long time, but release it relatively quickly in case they fail.
6565
*/
6666
Interval expiration() default @Interval(value = "10", unit = TimeUnit.SECONDS);
6767

@@ -77,8 +77,8 @@
7777
Interval retry() default @Interval(value = "50");
7878

7979
/**
80-
* Lock refresh interval. How often should the lock be refreshed during method execution. If it is non-positive, lock will not be refreshed
81-
* during the execution and maximum time the lock can be held is defined by the {@link #expiration()} in this case.
80+
* Lock refresh interval indicated how often should the lock be refreshed during method execution. If it is non-positive, lock will not
81+
* be refreshed during the execution and maximum time the lock can be held is defined by the {@link #expiration()} in this case.
8282
*/
8383
Interval refresh() default @Interval(value = "0");
8484

distributed-lock-api/src/main/java/com/github/alturkovic/lock/exception/DistributedLockException.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal

distributed-lock-api/src/main/java/com/github/alturkovic/lock/key/KeyGenerator.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -31,6 +31,7 @@
3131
* Used to generate keys to lock.
3232
*/
3333
public interface KeyGenerator {
34+
3435
/**
3536
* Generate keys by evaluating the given expression.
3637
*

distributed-lock-core/pom.xml

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ MIT License
4+
~
5+
~ Copyright (c) 2020 Alen Turkovic
6+
~
7+
~ Permission is hereby granted, free of charge, to any person obtaining a copy
8+
~ of this software and associated documentation files (the "Software"), to deal
9+
~ in the Software without restriction, including without limitation the rights
10+
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
~ copies of the Software, and to permit persons to whom the Software is
12+
~ furnished to do so, subject to the following conditions:
13+
~
14+
~ The above copyright notice and this permission notice shall be included in all
15+
~ copies or substantial portions of the Software.
16+
~
17+
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
~ SOFTWARE.
24+
-->
25+
226
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
327
xmlns="http://maven.apache.org/POM/4.0.0"
428
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
@@ -7,7 +31,7 @@
731
<parent>
832
<groupId>com.github.alturkovic</groupId>
933
<artifactId>distributed-lock</artifactId>
10-
<version>1.2.2</version>
34+
<version>1.3.0</version>
1135
</parent>
1236

1337
<artifactId>distributed-lock-core</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Alen Turkovic
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package com.github.alturkovic.lock;
26+
27+
import java.util.List;
28+
import java.util.function.Supplier;
29+
import lombok.Data;
30+
import org.springframework.util.Assert;
31+
import org.springframework.util.StringUtils;
32+
33+
/**
34+
* An abstract lock used as a base for all locks that operate with only 1 key instead of multiple keys.
35+
*/
36+
@Data
37+
public abstract class AbstractSimpleLock implements Lock {
38+
private final Supplier<String> tokenSupplier;
39+
40+
@Override
41+
public String acquire(final List<String> keys, final String storeId, final long expiration) {
42+
Assert.isTrue(keys.size() == 1, "Cannot acquire lock for multiple keys with this lock");
43+
44+
final var token = tokenSupplier.get();
45+
if (StringUtils.isEmpty(token)) {
46+
throw new IllegalStateException("Cannot lock with empty token");
47+
}
48+
49+
return acquire(keys.get(0), storeId, token, expiration);
50+
}
51+
52+
@Override
53+
public boolean release(final List<String> keys, final String storeId, final String token) {
54+
Assert.isTrue(keys.size() == 1, "Cannot release lock for multiple keys with this lock");
55+
return release(keys.get(0), storeId, token);
56+
}
57+
58+
@Override
59+
public boolean refresh(final List<String> keys, final String storeId, final String token, final long expiration) {
60+
Assert.isTrue(keys.size() == 1, "Cannot refresh lock for multiple keys with this lock");
61+
return refresh(keys.get(0), storeId, token, expiration);
62+
}
63+
64+
protected abstract String acquire(String key, String storeId, String token, long expiration);
65+
protected abstract boolean release(String key, String storeId, String token);
66+
protected abstract boolean refresh(String key, String storeId, String token, long expiration);
67+
}

distributed-lock-core/src/main/java/com/github/alturkovic/lock/advice/LockBeanPostProcessor.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* MIT License
33
*
4-
* Copyright (c) 2018 Alen Turkovic
4+
* Copyright (c) 2020 Alen Turkovic
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -25,8 +25,9 @@
2525
package com.github.alturkovic.lock.advice;
2626

2727
import com.github.alturkovic.lock.Locked;
28-
import com.github.alturkovic.lock.converter.IntervalConverter;
28+
import com.github.alturkovic.lock.interval.IntervalConverter;
2929
import com.github.alturkovic.lock.key.KeyGenerator;
30+
import com.github.alturkovic.lock.retry.RetriableLockFactory;
3031
import lombok.AllArgsConstructor;
3132
import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor;
3233
import org.springframework.aop.support.DefaultPointcutAdvisor;
@@ -39,15 +40,16 @@
3940
*/
4041
@AllArgsConstructor
4142
public class LockBeanPostProcessor extends AbstractAdvisingBeanPostProcessor implements InitializingBean {
42-
private final IntervalConverter intervalConverter;
43-
private final LockTypeResolver lockTypeResolver;
4443
private final KeyGenerator keyGenerator;
44+
private final LockTypeResolver lockTypeResolver;
45+
private final IntervalConverter intervalConverter;
46+
private final RetriableLockFactory retriableLockFactory;
4547
private final TaskScheduler taskScheduler;
4648

4749
@Override
4850
public void afterPropertiesSet() {
49-
final AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(null, Locked.class, true);
50-
final LockMethodInterceptor interceptor = new LockMethodInterceptor(keyGenerator, lockTypeResolver, intervalConverter, taskScheduler);
51+
final var pointcut = new AnnotationMatchingPointcut(null, Locked.class, true);
52+
final var interceptor = new LockMethodInterceptor(keyGenerator, lockTypeResolver, intervalConverter, retriableLockFactory, taskScheduler);
5153

5254
this.advisor = new DefaultPointcutAdvisor(pointcut, interceptor);
5355
}

0 commit comments

Comments
 (0)