mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 05:39:53 +01:00
Start plugins asynchronously.
This allows the lifecycle manager to continue starting other services while plugins are starting, and allows the plugin manager to stop each plugin as soon as it has started.
This commit is contained in:
@@ -53,20 +53,20 @@ class LifecycleManagerImpl implements LifecycleManager {
|
|||||||
@Override
|
@Override
|
||||||
public void registerService(Service s) {
|
public void registerService(Service s) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Registering service " + s.getClass().getName());
|
LOG.info("Registering service " + s.getClass().getSimpleName());
|
||||||
services.add(s);
|
services.add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerClient(Client c) {
|
public void registerClient(Client c) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Registering client " + c.getClass().getName());
|
LOG.info("Registering client " + c.getClass().getSimpleName());
|
||||||
clients.add(c);
|
clients.add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerForShutdown(ExecutorService e) {
|
public void registerForShutdown(ExecutorService e) {
|
||||||
LOG.info("Registering executor");
|
LOG.info("Registering executor " + e.getClass().getSimpleName());
|
||||||
executors.add(e);
|
executors.add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,8 @@ class LifecycleManagerImpl implements LifecycleManager {
|
|||||||
c.createLocalState(txn);
|
c.createLocalState(txn);
|
||||||
duration = System.currentTimeMillis() - start;
|
duration = System.currentTimeMillis() - start;
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Starting client " + c.getClass().getName()
|
LOG.info("Starting client "
|
||||||
|
+ c.getClass().getSimpleName()
|
||||||
+ " took " + duration + " ms");
|
+ " took " + duration + " ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ class LifecycleManagerImpl implements LifecycleManager {
|
|||||||
s.startService();
|
s.startService();
|
||||||
duration = System.currentTimeMillis() - start;
|
duration = System.currentTimeMillis() - start;
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Starting service " + s.getClass().getName()
|
LOG.info("Starting service " + s.getClass().getSimpleName()
|
||||||
+ " took " + duration + " ms");
|
+ " took " + duration + " ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,13 +141,17 @@ class LifecycleManagerImpl implements LifecycleManager {
|
|||||||
s.stopService();
|
s.stopService();
|
||||||
long duration = System.currentTimeMillis() - start;
|
long duration = System.currentTimeMillis() - start;
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Stopping service " + s.getClass().getName()
|
LOG.info("Stopping service " + s.getClass().getSimpleName()
|
||||||
+ " took " + duration + " ms");
|
+ " took " + duration + " ms");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ExecutorService e : executors) e.shutdownNow();
|
for (ExecutorService e : executors) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info(executors.size() + " executors shut down");
|
LOG.info("Stopping executor "
|
||||||
|
+ e.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
e.shutdownNow();
|
||||||
|
}
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
db.close();
|
db.close();
|
||||||
long duration = System.currentTimeMillis() - start;
|
long duration = System.currentTimeMillis() - start;
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
private final Map<TransportId, Plugin> plugins;
|
private final Map<TransportId, Plugin> plugins;
|
||||||
private final List<SimplexPlugin> simplexPlugins;
|
private final List<SimplexPlugin> simplexPlugins;
|
||||||
private final List<DuplexPlugin> duplexPlugins;
|
private final List<DuplexPlugin> duplexPlugins;
|
||||||
|
private final Map<TransportId, CountDownLatch> startLatches;
|
||||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -80,69 +81,64 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
plugins = new ConcurrentHashMap<TransportId, Plugin>();
|
plugins = new ConcurrentHashMap<TransportId, Plugin>();
|
||||||
simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>();
|
simplexPlugins = new CopyOnWriteArrayList<SimplexPlugin>();
|
||||||
duplexPlugins = new CopyOnWriteArrayList<DuplexPlugin>();
|
duplexPlugins = new CopyOnWriteArrayList<DuplexPlugin>();
|
||||||
|
startLatches = new ConcurrentHashMap<TransportId, CountDownLatch>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startService() throws ServiceException {
|
public void startService() throws ServiceException {
|
||||||
if (used.getAndSet(true)) throw new IllegalStateException();
|
if (used.getAndSet(true)) throw new IllegalStateException();
|
||||||
Collection<SimplexPluginFactory> simplexFactories =
|
// Instantiate the simplex plugins and start them asynchronously
|
||||||
pluginConfig.getSimplexFactories();
|
|
||||||
Collection<DuplexPluginFactory> duplexFactories =
|
|
||||||
pluginConfig.getDuplexFactories();
|
|
||||||
int numPlugins = simplexFactories.size() + duplexFactories.size();
|
|
||||||
CountDownLatch latch = new CountDownLatch(numPlugins);
|
|
||||||
// Instantiate and start the simplex plugins
|
|
||||||
LOG.info("Starting simplex plugins");
|
LOG.info("Starting simplex plugins");
|
||||||
for (SimplexPluginFactory f : simplexFactories) {
|
for (SimplexPluginFactory f : pluginConfig.getSimplexFactories()) {
|
||||||
TransportId t = f.getId();
|
TransportId t = f.getId();
|
||||||
SimplexPlugin s = f.createPlugin(new SimplexCallback(t));
|
SimplexPlugin s = f.createPlugin(new SimplexCallback(t));
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.warning("Could not create plugin for " + t);
|
LOG.warning("Could not create plugin for " + t);
|
||||||
latch.countDown();
|
|
||||||
} else {
|
} else {
|
||||||
plugins.put(t, s);
|
plugins.put(t, s);
|
||||||
simplexPlugins.add(s);
|
simplexPlugins.add(s);
|
||||||
ioExecutor.execute(new PluginStarter(s, latch));
|
CountDownLatch startLatch = new CountDownLatch(1);
|
||||||
|
startLatches.put(t, startLatch);
|
||||||
|
ioExecutor.execute(new PluginStarter(s, startLatch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Instantiate and start the duplex plugins
|
// Instantiate the duplex plugins and start them asynchronously
|
||||||
LOG.info("Starting duplex plugins");
|
LOG.info("Starting duplex plugins");
|
||||||
for (DuplexPluginFactory f : duplexFactories) {
|
for (DuplexPluginFactory f : pluginConfig.getDuplexFactories()) {
|
||||||
TransportId t = f.getId();
|
TransportId t = f.getId();
|
||||||
DuplexPlugin d = f.createPlugin(new DuplexCallback(t));
|
DuplexPlugin d = f.createPlugin(new DuplexCallback(t));
|
||||||
if (d == null) {
|
if (d == null) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.warning("Could not create plugin for " + t);
|
LOG.warning("Could not create plugin for " + t);
|
||||||
latch.countDown();
|
|
||||||
} else {
|
} else {
|
||||||
plugins.put(t, d);
|
plugins.put(t, d);
|
||||||
duplexPlugins.add(d);
|
duplexPlugins.add(d);
|
||||||
ioExecutor.execute(new PluginStarter(d, latch));
|
CountDownLatch startLatch = new CountDownLatch(1);
|
||||||
|
startLatches.put(t, startLatch);
|
||||||
|
ioExecutor.execute(new PluginStarter(d, startLatch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Wait for all the plugins to start
|
|
||||||
try {
|
|
||||||
latch.await();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new ServiceException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopService() throws ServiceException {
|
public void stopService() throws ServiceException {
|
||||||
CountDownLatch latch = new CountDownLatch(plugins.size());
|
CountDownLatch stopLatch = new CountDownLatch(plugins.size());
|
||||||
// Stop the simplex plugins
|
// Stop the simplex plugins
|
||||||
LOG.info("Stopping simplex plugins");
|
LOG.info("Stopping simplex plugins");
|
||||||
for (SimplexPlugin plugin : simplexPlugins)
|
for (SimplexPlugin s : simplexPlugins) {
|
||||||
ioExecutor.execute(new PluginStopper(plugin, latch));
|
CountDownLatch startLatch = startLatches.get(s.getId());
|
||||||
|
ioExecutor.execute(new PluginStopper(s, startLatch, stopLatch));
|
||||||
|
}
|
||||||
// Stop the duplex plugins
|
// Stop the duplex plugins
|
||||||
LOG.info("Stopping duplex plugins");
|
LOG.info("Stopping duplex plugins");
|
||||||
for (DuplexPlugin plugin : duplexPlugins)
|
for (DuplexPlugin d : duplexPlugins) {
|
||||||
ioExecutor.execute(new PluginStopper(plugin, latch));
|
CountDownLatch startLatch = startLatches.get(d.getId());
|
||||||
|
ioExecutor.execute(new PluginStopper(d, startLatch, stopLatch));
|
||||||
|
}
|
||||||
// Wait for all the plugins to stop
|
// Wait for all the plugins to stop
|
||||||
try {
|
try {
|
||||||
latch.await();
|
stopLatch.await();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new ServiceException(e);
|
throw new ServiceException(e);
|
||||||
}
|
}
|
||||||
@@ -182,11 +178,11 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
private class PluginStarter implements Runnable {
|
private class PluginStarter implements Runnable {
|
||||||
|
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch startLatch;
|
||||||
|
|
||||||
private PluginStarter(Plugin plugin, CountDownLatch latch) {
|
private PluginStarter(Plugin plugin, CountDownLatch startLatch) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.latch = latch;
|
this.startLatch = startLatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -212,7 +208,7 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown();
|
startLatch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,16 +216,21 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
private class PluginStopper implements Runnable {
|
private class PluginStopper implements Runnable {
|
||||||
|
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final CountDownLatch latch;
|
private final CountDownLatch startLatch, stopLatch;
|
||||||
|
|
||||||
private PluginStopper(Plugin plugin, CountDownLatch latch) {
|
private PluginStopper(Plugin plugin, CountDownLatch startLatch,
|
||||||
|
CountDownLatch stopLatch) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.latch = latch;
|
this.startLatch = startLatch;
|
||||||
|
this.stopLatch = stopLatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
// Wait for the plugin to finish starting
|
||||||
|
startLatch.await();
|
||||||
|
// Stop the plugin
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
plugin.stop();
|
plugin.stop();
|
||||||
long duration = System.currentTimeMillis() - start;
|
long duration = System.currentTimeMillis() - start;
|
||||||
@@ -237,10 +238,13 @@ class PluginManagerImpl implements PluginManager, Service {
|
|||||||
LOG.info("Stopping plugin " + plugin.getId()
|
LOG.info("Stopping plugin " + plugin.getId()
|
||||||
+ " took " + duration + " ms");
|
+ " took " + duration + " ms");
|
||||||
}
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOG.warning("Interrupted while waiting for plugin to start");
|
||||||
|
// This task runs on an executor, so don't reset the interrupt
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown();
|
stopLatch.countDown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user