Skip to content

Commit a7b2f0a

Browse files
committed
Make import thread-safe to fix #60
1 parent 03467d2 commit a7b2f0a

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

src/main/java/fr/igred/omero/GatewayWrapper.java

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242

4343
import java.util.List;
4444
import java.util.concurrent.ExecutionException;
45+
import java.util.concurrent.atomic.AtomicInteger;
46+
import java.util.concurrent.locks.Lock;
47+
import java.util.concurrent.locks.ReentrantLock;
4548

4649

4750
/**
@@ -51,6 +54,12 @@
5154
*/
5255
public abstract class GatewayWrapper {
5356

57+
/** Number of requested import stores */
58+
private final AtomicInteger storeUses = new AtomicInteger(0);
59+
60+
/** Import store lock */
61+
private final Lock storeLock = new ReentrantLock(true);
62+
5463
/** Gateway linking the code to OMERO, only linked to one group. */
5564
private Gateway gateway;
5665

@@ -86,6 +95,35 @@ public Gateway getGateway() {
8695
}
8796

8897

98+
/**
99+
* Retrieves the shared import store in a thread-safe way.
100+
*
101+
* @throws DSOutOfServiceException If the connection is broken, or not logged in.
102+
*/
103+
private OMEROMetadataStoreClient getImportStoreLocked() throws DSOutOfServiceException {
104+
storeLock.lock();
105+
try {
106+
return gateway.getImportStore(ctx);
107+
} finally {
108+
storeLock.unlock();
109+
}
110+
}
111+
112+
113+
/**
114+
* Closes the import store in a thread-safe manner.
115+
*/
116+
private void closeImportStoreLocked() {
117+
if (storeLock.tryLock()) {
118+
try {
119+
gateway.closeImport(ctx, null);
120+
} finally {
121+
storeLock.unlock();
122+
}
123+
}
124+
}
125+
126+
89127
/**
90128
* Returns the current user.
91129
*
@@ -232,6 +270,8 @@ public void connect(LoginCredentials cred) throws ServiceException {
232270
public void disconnect() {
233271
if (isConnected()) {
234272
boolean sudo = ctx.isSudo();
273+
storeUses.set(0);
274+
closeImport();
235275
user = new ExperimenterWrapper(new ExperimenterData());
236276
ctx = new SecurityContext(-1);
237277
ctx.setExperimenter(user.asDataObject());
@@ -347,18 +387,30 @@ public AdminFacility getAdminFacility() throws ExecutionException {
347387
/**
348388
* Creates or recycles the import store.
349389
*
350-
* @return config.
390+
* @return See above.
351391
*
352392
* @throws ServiceException Cannot connect to OMERO.
353393
*/
354394
public OMEROMetadataStoreClient getImportStore() throws ServiceException {
355-
return ExceptionHandler.of(gateway, g -> g.getImportStore(ctx))
395+
storeUses.incrementAndGet();
396+
return ExceptionHandler.of(this, GatewayWrapper::getImportStoreLocked)
356397
.rethrow(DSOutOfServiceException.class, ServiceException::new,
357398
"Could not retrieve import store")
358399
.get();
359400
}
360401

361402

403+
/**
404+
* Closes the import store.
405+
*/
406+
public void closeImport() {
407+
int remainingStores = storeUses.decrementAndGet();
408+
if (remainingStores <= 0) {
409+
closeImportStoreLocked();
410+
}
411+
}
412+
413+
362414
/**
363415
* Finds objects on OMERO through a database query.
364416
*

src/main/java/fr/igred/omero/repository/GenericRepositoryObjectWrapper.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected static boolean importImages(GatewayWrapper client, DataObject target,
107107
ImportCandidates candidates = new ImportCandidates(reader, paths, handler);
108108
success = library.importCandidates(config, candidates);
109109
} finally {
110-
store.logout();
110+
client.closeImport();
111111
}
112112

113113
return success;
@@ -163,7 +163,7 @@ protected static List<Long> importImage(GatewayWrapper client, DataObject target
163163
} catch (Throwable e) {
164164
throw new OMEROServerError(e);
165165
} finally {
166-
store.logout();
166+
client.closeImport();
167167
}
168168

169169
List<Long> ids = new ArrayList<>(pixels.size());

src/test/java/fr/igred/omero/SudoTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ void sudoImport() throws Exception {
109109

110110
List<ImageWrapper> images = dataset.getImages(client3);
111111
assertEquals(1, images.size());
112+
assertEquals(client3.getId(), images.get(0).getOwner().getId());
113+
assertEquals(6L, images.get(0).getGroupId());
112114

113115
client4.delete(images.get(0));
114116
client4.delete(dataset);

0 commit comments

Comments
 (0)