private SubServicesBundle doGetSubServiceBundle(String routerID) { /* Ensure we have a PathServiceBundle, even an empty one, to synchronize on. */ SubServicesBundle ssb = null; synchronized (subServices) { ssb = subServices.get(routerID); if (ssb == null) { ssb = new SubServicesBundle(); ssb.pathService = null; ssb.timestampLoaded = System.currentTimeMillis(); ssb.reloadInProgress = false; subServices.put(routerID, ssb); } } /* * Synchronize access to the bundle only, to prevent blocking requests to other graphs. * Check for first-time loading, no background reload is possible since no older version is * available. */ synchronized (ssb) { if (ssb.pathService == null) { SubServicesBundle newSsb = loadSubServices(routerID); ssb.pathService = newSsb.pathService; ssb.patchService = newSsb.patchService; ssb.context = newSsb.context; ssb.timestampLoaded = System.currentTimeMillis(); return ssb; } } /* Here background reload becomes possible. */ boolean reload = false; synchronized (ssb) { if (checkReload(routerID, ssb.timestampLoaded) && !ssb.reloadInProgress) { if (!asyncReload) { LOG.info("Reloading modified graph '" + routerID + "'"); // Sync reload: remove old version before loading new one, in synchronized // block. ssb.pathService = null; ssb.patchService = null; ssb.context.close(); ssb.context = null; SubServicesBundle newSsb = loadSubServices(routerID); ssb.pathService = newSsb.pathService; ssb.patchService = newSsb.patchService; ssb.context = newSsb.context; ssb.timestampLoaded = System.currentTimeMillis(); } else { reload = true; ssb.reloadInProgress = true; } } } if (reload) { // Async reload: load new version but keep old one while not ready for other // requests. SubServicesBundle newSsb = loadSubServices(routerID); synchronized (ssb) { LOG.info("Async reloading modified graph '" + routerID + "'"); ssb.pathService = newSsb.pathService; ssb.patchService = newSsb.patchService; ssb.context.close(); ssb.context = newSsb.context; ssb.reloadInProgress = false; ssb.timestampLoaded = System.currentTimeMillis(); } } return ssb; }