fix some race conditions (#5220)
* fix memory leak * race condition fixes and change log * race condition fixes and change log
This commit is contained in:
parent
b9155721a7
commit
deeffe2253
|
@ -1177,7 +1177,14 @@ public class FhirContext {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (!myInitialized && !myInitializing) {
|
if (!myInitialized && !myInitializing) {
|
||||||
myInitializing = true;
|
myInitializing = true;
|
||||||
|
try {
|
||||||
scanResourceTypes(toElementList(myResourceTypesToScan));
|
scanResourceTypes(toElementList(myResourceTypesToScan));
|
||||||
|
} catch (Exception e) {
|
||||||
|
ourLog.error("Failed to initialize FhirContext", e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
myInitializing = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,14 +270,6 @@ public abstract class BaseApp {
|
||||||
|
|
||||||
// Actually execute the command
|
// Actually execute the command
|
||||||
command.run(parsedOptions);
|
command.run(parsedOptions);
|
||||||
|
|
||||||
myShutdownHookHasNotRun = true;
|
|
||||||
runCleanupHookAndUnregister();
|
|
||||||
|
|
||||||
if (!HapiSystemProperties.isTestModeEnabled()) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
if (!HapiSystemProperties.isTestModeEnabled()) {
|
if (!HapiSystemProperties.isTestModeEnabled()) {
|
||||||
LogbackUtil.loggingConfigOff();
|
LogbackUtil.loggingConfigOff();
|
||||||
|
@ -296,6 +288,13 @@ public abstract class BaseApp {
|
||||||
ourLog.error("Error during execution: ", t);
|
ourLog.error("Error during execution: ", t);
|
||||||
runCleanupHookAndUnregister();
|
runCleanupHookAndUnregister();
|
||||||
exitDueToException(new CommandFailureException("Error: " + t, t));
|
exitDueToException(new CommandFailureException("Error: " + t, t));
|
||||||
|
} finally {
|
||||||
|
myShutdownHookHasNotRun = true;
|
||||||
|
runCleanupHookAndUnregister();
|
||||||
|
|
||||||
|
if (!HapiSystemProperties.isTestModeEnabled()) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,7 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param theFhirContext
|
* @param theFhirContext The context
|
||||||
* The context
|
|
||||||
*/
|
*/
|
||||||
public RestfulClientFactory(FhirContext theFhirContext) {
|
public RestfulClientFactory(FhirContext theFhirContext) {
|
||||||
myContext = theFhirContext;
|
myContext = theFhirContext;
|
||||||
|
@ -142,13 +141,10 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
/**
|
/**
|
||||||
* Instantiates a new client instance
|
* Instantiates a new client instance
|
||||||
*
|
*
|
||||||
* @param theClientType
|
* @param theClientType The client type, which is an interface type to be instantiated
|
||||||
* The client type, which is an interface type to be instantiated
|
* @param theServerBase The URL of the base for the restful FHIR server to connect to
|
||||||
* @param theServerBase
|
|
||||||
* The URL of the base for the restful FHIR server to connect to
|
|
||||||
* @return A newly created client
|
* @return A newly created client
|
||||||
* @throws ConfigurationException
|
* @throws ConfigurationException If the interface type is not an interface
|
||||||
* If the interface type is not an interface
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized <T extends IRestfulClient> T newClient(Class<T> theClientType, String theServerBase) {
|
public synchronized <T extends IRestfulClient> T newClient(Class<T> theClientType, String theServerBase) {
|
||||||
|
@ -281,13 +277,8 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONCE:
|
case ONCE:
|
||||||
if (myValidatedServerBaseUrls.contains(serverBase)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (myValidatedServerBaseUrls) {
|
synchronized (myValidatedServerBaseUrls) {
|
||||||
if (!myValidatedServerBaseUrls.contains(serverBase)) {
|
if (myValidatedServerBaseUrls.add(serverBase)) {
|
||||||
myValidatedServerBaseUrls.add(serverBase);
|
|
||||||
validateServerBase(serverBase, theHttpClient, theClient);
|
validateServerBase(serverBase, theHttpClient, theClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,20 +387,13 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
String serverBase = normalizeBaseUrlForMap(theServerBase);
|
String serverBase = normalizeBaseUrlForMap(theServerBase);
|
||||||
if (myValidatedServerBaseUrls.contains(serverBase)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (myValidatedServerBaseUrls) {
|
|
||||||
myValidatedServerBaseUrls.add(serverBase);
|
myValidatedServerBaseUrls.add(serverBase);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the http client for the given server base
|
* Get the http client for the given server base
|
||||||
*
|
*
|
||||||
* @param theServerBase
|
* @param theServerBase the server base
|
||||||
* the server base
|
|
||||||
* @return the http client
|
* @return the http client
|
||||||
*/
|
*/
|
||||||
protected abstract IHttpClient getHttpClient(String theServerBase);
|
protected abstract IHttpClient getHttpClient(String theServerBase);
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 5220
|
||||||
|
title: "Fixed a race condition in RestfulClientFactory that could cause validateInitialized() to deadlock.
|
||||||
|
Fixed a race condition in FhirContext initialization that could produce a 'this.myNameToResourceType is null' NPE.
|
||||||
|
Fixed a shutdown hook memory leak in BaseApp that happened when the command threw an exception;
|
||||||
|
this memory leak only affects code that calls App.main repeatedly which is probably only in test code."
|
|
@ -113,7 +113,7 @@ public class ClientThreadedCapabilitiesTest {
|
||||||
} else {
|
} else {
|
||||||
// metadata request must always be first
|
// metadata request must always be first
|
||||||
if (counter.get() == 0) {
|
if (counter.get() == 0) {
|
||||||
fail("A non-metadata request was executed before metadata request");
|
fail("A non-metadata request was executed before metadata request: " + theRequest.getUri() + " counter: " + counter.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue