Skip to content

Commit db4a1be

Browse files
Update after review
1 parent 2e336a1 commit db4a1be

File tree

3 files changed

+105
-106
lines changed

3 files changed

+105
-106
lines changed

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/LazyLoadingProxyFactory.java

+26-17
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.lang.reflect.Method;
2525
import java.util.concurrent.locks.Lock;
2626
import java.util.concurrent.locks.ReadWriteLock;
27-
import java.util.concurrent.locks.ReentrantLock;
2827
import java.util.concurrent.locks.ReentrantReadWriteLock;
2928
import java.util.function.Supplier;
3029

@@ -138,7 +137,8 @@ public Object createLazyLoadingProxy(MongoPersistentProperty property, DbRefReso
138137
}
139138

140139
return prepareProxyFactory(propertyType,
141-
() -> new LazyLoadingInterceptor(property, callback, source, exceptionTranslator)).getProxy(LazyLoadingProxy.class.getClassLoader());
140+
() -> new LazyLoadingInterceptor(property, callback, source, exceptionTranslator))
141+
.getProxy(LazyLoadingProxy.class.getClassLoader());
142142
}
143143

144144
/**
@@ -348,25 +348,26 @@ private void readObject(ObjectInputStream in) throws IOException {
348348
private Object resolve() {
349349

350350
lock.readLock().lock();
351-
if (resolved) {
351+
try {
352+
if (resolved) {
352353

353-
if (LOGGER.isTraceEnabled()) {
354-
LOGGER.trace(String.format("Accessing already resolved lazy loading property %s.%s",
355-
property.getOwner() != null ? property.getOwner().getName() : "unknown", property.getName()));
354+
if (LOGGER.isTraceEnabled()) {
355+
LOGGER.trace(String.format("Accessing already resolved lazy loading property %s.%s",
356+
property.getOwner() != null ? property.getOwner().getName() : "unknown", property.getName()));
357+
}
358+
return result;
356359
}
357-
return result;
360+
} finally {
361+
lock.readLock().unlock();
358362
}
359-
lock.readLock().unlock();
360-
361-
try {
362-
if (LOGGER.isTraceEnabled()) {
363-
LOGGER.trace(String.format("Resolving lazy loading property %s.%s",
364-
property.getOwner() != null ? property.getOwner().getName() : "unknown", property.getName()));
365-
}
366363

367-
lock.writeLock().lock();
368-
return callback.resolve(property);
364+
if (LOGGER.isTraceEnabled()) {
365+
LOGGER.trace(String.format("Resolving lazy loading property %s.%s",
366+
property.getOwner() != null ? property.getOwner().getName() : "unknown", property.getName()));
367+
}
369368

369+
try {
370+
return executeWhileLocked(lock.writeLock(), () -> callback.resolve(property));
370371
} catch (RuntimeException ex) {
371372

372373
DataAccessException translatedException = exceptionTranslator.translateExceptionIfPossible(ex);
@@ -377,8 +378,16 @@ private Object resolve() {
377378

378379
throw new LazyLoadingException("Unable to lazily resolve DBRef",
379380
translatedException != null ? translatedException : ex);
381+
}
382+
}
383+
384+
private static <T> T executeWhileLocked(Lock lock, Supplier<T> stuff) {
385+
386+
lock.lock();
387+
try {
388+
return stuff.get();
380389
} finally {
381-
lock.writeLock().unlock();
390+
lock.unlock();
382391
}
383392
}
384393
}

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/CursorReadingTask.java

+47-50
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,14 @@ public void run() {
8888
}
8989
} catch (InterruptedException e) {
9090

91-
lock.lock();
92-
state = State.CANCELLED;
93-
lock.unlock();
91+
doWhileLocked(lock, () -> state = State.CANCELLED);
9492
Thread.currentThread().interrupt();
9593
break;
9694
}
9795
}
9896
} catch (RuntimeException e) {
9997

100-
lock.lock();
101-
state = State.CANCELLED;
102-
lock.unlock();
103-
98+
doWhileLocked(lock, () -> state = State.CANCELLED);
10499
errorHandler.handleError(e);
105100
}
106101
}
@@ -116,43 +111,40 @@ public void run() {
116111
*/
117112
private void start() {
118113

119-
lock.lock();
120-
if (!State.RUNNING.equals(state)) {
121-
state = State.STARTING;
122-
}
123-
lock.unlock();
114+
doWhileLocked(lock, () -> {
115+
if (!State.RUNNING.equals(state)) {
116+
state = State.STARTING;
117+
}
118+
});
124119

125120
do {
126121

127-
boolean valid = false;
122+
// boolean valid = false;
128123

129-
lock.lock();
124+
boolean valid = executeWhileLocked(lock, () -> {
130125

131-
try {
132-
if (State.STARTING.equals(state)) {
126+
if (!State.STARTING.equals(state)) {
127+
return false;
128+
}
133129

134-
MongoCursor<T> cursor = execute(() -> initCursor(template, request.getRequestOptions(), targetType));
135-
valid = isValidCursor(cursor);
136-
if (valid) {
137-
this.cursor = cursor;
138-
state = State.RUNNING;
139-
} else if (cursor != null) {
140-
cursor.close();
141-
}
130+
MongoCursor<T> cursor = execute(() -> initCursor(template, request.getRequestOptions(), targetType));
131+
boolean isValid = isValidCursor(cursor);
132+
if (isValid) {
133+
this.cursor = cursor;
134+
state = State.RUNNING;
135+
} else if (cursor != null) {
136+
cursor.close();
142137
}
143-
} finally {
144-
lock.unlock();
145-
}
138+
return isValid;
139+
});
146140

147141
if (!valid) {
148142

149143
try {
150144
Thread.sleep(100);
151145
} catch (InterruptedException e) {
152146

153-
lock.lock();
154-
state = State.CANCELLED;
155-
lock.unlock();
147+
doWhileLocked(lock, () -> state = State.CANCELLED);
156148
Thread.currentThread().interrupt();
157149
}
158150
}
@@ -168,19 +160,15 @@ private void start() {
168160
@Override
169161
public void cancel() throws DataAccessResourceFailureException {
170162

171-
lock.lock();
172-
173-
try {
163+
doWhileLocked(lock, () -> {
174164

175165
if (State.RUNNING.equals(state) || State.STARTING.equals(state)) {
176166
this.state = State.CANCELLED;
177167
if (cursor != null) {
178168
cursor.close();
179169
}
180170
}
181-
} finally {
182-
lock.unlock();
183-
}
171+
});
184172
}
185173

186174
@Override
@@ -190,13 +178,7 @@ public boolean isLongLived() {
190178

191179
@Override
192180
public State getState() {
193-
194-
lock.lock();
195-
try {
196-
return state;
197-
} finally {
198-
lock.unlock();
199-
}
181+
return executeWhileLocked(lock, () -> state);
200182
}
201183

202184
@Override
@@ -232,16 +214,12 @@ private void emitMessage(Message<T, R> message) {
232214
@Nullable
233215
private T getNext() {
234216

235-
lock.lock();
236-
try{
217+
return executeWhileLocked(lock, () -> {
237218
if (State.RUNNING.equals(state)) {
238219
return cursor.tryNext();
239220
}
240-
} finally {
241-
lock.unlock();
242-
}
243-
244-
throw new IllegalStateException(String.format("Cursor %s is not longer open", cursor));
221+
throw new IllegalStateException(String.format("Cursor %s is not longer open", cursor));
222+
});
245223
}
246224

247225
private static boolean isValidCursor(@Nullable MongoCursor<?> cursor) {
@@ -278,4 +256,23 @@ private <V> V execute(Supplier<V> callback) {
278256
throw translated != null ? translated : e;
279257
}
280258
}
259+
260+
private static void doWhileLocked(Lock lock, Runnable action) {
261+
262+
executeWhileLocked(lock, () -> {
263+
action.run();
264+
return null;
265+
});
266+
}
267+
268+
@Nullable
269+
private static <T> T executeWhileLocked(Lock lock, Supplier<T> stuff) {
270+
271+
lock.lock();
272+
try {
273+
return stuff.get();
274+
} finally {
275+
lock.unlock();
276+
}
277+
}
281278
}

Diff for: spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainer.java

+32-39
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
import java.util.Map;
2121
import java.util.Optional;
2222
import java.util.concurrent.Executor;
23+
import java.util.concurrent.locks.Lock;
2324
import java.util.concurrent.locks.ReadWriteLock;
2425
import java.util.concurrent.locks.ReentrantReadWriteLock;
26+
import java.util.function.Supplier;
2527

2628
import org.apache.commons.logging.Log;
2729
import org.apache.commons.logging.LogFactory;
@@ -37,8 +39,7 @@
3739
/**
3840
* Simple {@link Executor} based {@link MessageListenerContainer} implementation for running {@link Task tasks} like
3941
* listening to MongoDB <a href="https://docs.mongodb.com/manual/changeStreams/">Change Streams</a> and tailable
40-
* cursors.
41-
* <br />
42+
* cursors. <br />
4243
* This message container creates long-running tasks that are executed on {@link Executor}.
4344
*
4445
* @author Christoph Strobl
@@ -113,8 +114,7 @@ public void stop(Runnable callback) {
113114
@Override
114115
public void start() {
115116

116-
lifecycleMonitor.writeLock().lock();
117-
try {
117+
doWhileLocked(lifecycleMonitor.writeLock(), () -> {
118118
if (!this.running) {
119119
subscriptions.values().stream() //
120120
.filter(it -> !it.isActive()) //
@@ -125,36 +125,23 @@ public void start() {
125125

126126
running = true;
127127
}
128-
} finally {
129-
lifecycleMonitor.writeLock().unlock();
130-
}
128+
});
131129
}
132130

133131
@Override
134132
public void stop() {
135133

136-
lifecycleMonitor.writeLock().lock();
137-
138-
try {
134+
doWhileLocked(lifecycleMonitor.writeLock(), () -> {
139135
if (this.running) {
140136
subscriptions.values().forEach(Cancelable::cancel);
141137
running = false;
142138
}
143-
} finally {
144-
lifecycleMonitor.writeLock().unlock();
145-
}
146-
139+
});
147140
}
148141

149142
@Override
150143
public boolean isRunning() {
151-
152-
lifecycleMonitor.writeLock().lock();
153-
try {
154-
return running;
155-
} finally {
156-
lifecycleMonitor.writeLock().unlock();
157-
}
144+
return executeWhileLocked(lifecycleMonitor.readLock(), () -> running);
158145
}
159146

160147
@Override
@@ -179,43 +166,32 @@ public <S, T> Subscription register(SubscriptionRequest<S, ? super T, ? extends
179166

180167
@Override
181168
public Optional<Subscription> lookup(SubscriptionRequest<?, ?, ?> request) {
182-
183-
subscriptionMonitor.readLock();
184-
try {
185-
return Optional.ofNullable(subscriptions.get(request));
186-
} finally {
187-
subscriptionMonitor.readLock().unlock();
188-
}
189-
169+
return executeWhileLocked(subscriptionMonitor.readLock(), () -> Optional.ofNullable(subscriptions.get(request)));
190170
}
191171

192172
public Subscription register(SubscriptionRequest request, Task task) {
193173

194-
Subscription subscription = new TaskSubscription(task);
195-
196-
this.subscriptionMonitor.writeLock().lock();
197-
try {
174+
return executeWhileLocked(this.subscriptionMonitor.writeLock(), () ->
175+
{
198176
if (subscriptions.containsKey(request)) {
199177
return subscriptions.get(request);
200178
}
201179

180+
Subscription subscription = new TaskSubscription(task);
202181
this.subscriptions.put(request, subscription);
203182

204183
if (this.isRunning()) {
205184
taskExecutor.execute(task);
206185
}
207186
return subscription;
208-
} finally {
209-
this.subscriptionMonitor.writeLock().unlock();
210-
}
187+
});
211188

212189
}
213190

214191
@Override
215192
public void remove(Subscription subscription) {
216193

217-
this.subscriptionMonitor.writeLock().lock();
218-
try {
194+
doWhileLocked(this.subscriptionMonitor.writeLock(), () -> {
219195

220196
if (subscriptions.containsValue(subscription)) {
221197

@@ -225,8 +201,25 @@ public void remove(Subscription subscription) {
225201

226202
subscriptions.values().remove(subscription);
227203
}
204+
});
205+
}
206+
207+
private static void doWhileLocked(Lock lock, Runnable action) {
208+
209+
executeWhileLocked(lock, () -> {
210+
action.run();
211+
return null;
212+
});
213+
}
214+
215+
@Nullable
216+
private static <T> T executeWhileLocked(Lock lock, Supplier<T> stuff) {
217+
218+
lock.lock();
219+
try {
220+
return stuff.get();
228221
} finally {
229-
this.subscriptionMonitor.writeLock().unlock();
222+
lock.unlock();
230223
}
231224
}
232225

0 commit comments

Comments
 (0)