From 20708bc1563813e5104ce9812f05cd8cd446be1b Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Fri, 18 Nov 2016 10:48:20 -0200 Subject: [PATCH] Introduce a @Scheduler annotation and make sure work is offloaded to an executor, so exceptions can be caught. --- .../briarproject/api/system/Scheduler.java | 25 +++++++++++++++ .../briarproject/feed/FeedManagerImpl.java | 9 +++--- .../briarproject/plugins/PluginsModule.java | 3 +- .../src/org/briarproject/plugins/Poller.java | 31 +++++++++++-------- .../org/briarproject/system/SystemModule.java | 3 ++ .../TransportKeyManagerFactoryImpl.java | 3 +- .../transport/TransportKeyManagerImpl.java | 3 +- 7 files changed, 57 insertions(+), 20 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/system/Scheduler.java diff --git a/briar-api/src/org/briarproject/api/system/Scheduler.java b/briar-api/src/org/briarproject/api/system/Scheduler.java new file mode 100644 index 0000000000..0b1e225da2 --- /dev/null +++ b/briar-api/src/org/briarproject/api/system/Scheduler.java @@ -0,0 +1,25 @@ +package org.briarproject.api.system; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Annotation for injecting a scheduled executor service + * that can be used to schedule the execution of tasks. + * <p> + * The service should <b>only</b> be used for running tasks on other executors + * at scheduled times. + * No significant work should be run by the service itself! + */ +@Qualifier +@Target({FIELD, METHOD, PARAMETER}) +@Retention(RUNTIME) +public @interface Scheduler { +} \ No newline at end of file diff --git a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java index b2229a60cd..55a413cde3 100644 --- a/briar-core/src/org/briarproject/feed/FeedManagerImpl.java +++ b/briar-core/src/org/briarproject/feed/FeedManagerImpl.java @@ -29,6 +29,7 @@ import org.briarproject.api.feed.FeedManager; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.lifecycle.IoExecutor; +import org.briarproject.api.system.Scheduler; import org.briarproject.api.plugins.TorConstants; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.GroupId; @@ -74,7 +75,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { private static final int CONNECT_TIMEOUT = 60 * 1000; // Milliseconds - private final ScheduledExecutorService feedExecutor; + private final ScheduledExecutorService scheduler; private final Executor ioExecutor; private final DatabaseComponent db; private final ContactGroupFactory contactGroupFactory; @@ -92,13 +93,13 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { Clock clock; @Inject - FeedManagerImpl(ScheduledExecutorService feedExecutor, + FeedManagerImpl(@Scheduler ScheduledExecutorService scheduler, @IoExecutor Executor ioExecutor, DatabaseComponent db, ContactGroupFactory contactGroupFactory, ClientHelper clientHelper, IdentityManager identityManager, BlogManager blogManager, SocketFactory torSocketFactory) { - this.feedExecutor = feedExecutor; + this.scheduler = scheduler; this.ioExecutor = ioExecutor; this.db = db; this.contactGroupFactory = contactGroupFactory; @@ -132,7 +133,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { }); } }; - feedExecutor.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL, + scheduler.scheduleWithFixedDelay(fetcher, FETCH_DELAY_INITIAL, FETCH_INTERVAL, FETCH_UNIT); } diff --git a/briar-core/src/org/briarproject/plugins/PluginsModule.java b/briar-core/src/org/briarproject/plugins/PluginsModule.java index fc58bc4045..d7e6925e55 100644 --- a/briar-core/src/org/briarproject/plugins/PluginsModule.java +++ b/briar-core/src/org/briarproject/plugins/PluginsModule.java @@ -8,6 +8,7 @@ import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionRegistry; import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.system.Clock; +import org.briarproject.api.system.Scheduler; import java.security.SecureRandom; import java.util.concurrent.Executor; @@ -37,7 +38,7 @@ public class PluginsModule { @Provides @Singleton Poller providePoller(@IoExecutor Executor ioExecutor, - ScheduledExecutorService scheduler, + @Scheduler ScheduledExecutorService scheduler, ConnectionManager connectionManager, ConnectionRegistry connectionRegistry, PluginManager pluginManager, SecureRandom random, Clock clock, EventBus eventBus) { diff --git a/briar-core/src/org/briarproject/plugins/Poller.java b/briar-core/src/org/briarproject/plugins/Poller.java index 20643e43e5..a904bbfe6d 100644 --- a/briar-core/src/org/briarproject/plugins/Poller.java +++ b/briar-core/src/org/briarproject/plugins/Poller.java @@ -18,6 +18,7 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.simplex.SimplexPlugin; import org.briarproject.api.system.Clock; +import org.briarproject.api.system.Scheduler; import java.security.SecureRandom; import java.util.HashMap; @@ -48,7 +49,8 @@ class Poller implements EventListener { private final Map<TransportId, PollTask> tasks; // Locking: lock @Inject - Poller(@IoExecutor Executor ioExecutor, ScheduledExecutorService scheduler, + Poller(@IoExecutor Executor ioExecutor, + @Scheduler ScheduledExecutorService scheduler, ConnectionManager connectionManager, ConnectionRegistry connectionRegistry, PluginManager pluginManager, SecureRandom random, Clock clock) { @@ -135,13 +137,14 @@ class Poller implements EventListener { private void reschedule(TransportId t) { Plugin p = pluginManager.getPlugin(t); - if (p.shouldPoll()) schedule(p, p.getPollingInterval(), false); + if (p != null && p.shouldPoll()) + schedule(p, p.getPollingInterval(), false); } private void pollNow(TransportId t) { Plugin p = pluginManager.getPlugin(t); // Randomise next polling interval - if (p.shouldPoll()) schedule(p, 0, true); + if (p != null && p.shouldPoll()) schedule(p, 0, true); } private void schedule(Plugin p, int delay, boolean randomiseNext) { @@ -152,24 +155,25 @@ class Poller implements EventListener { try { PollTask scheduled = tasks.get(t); if (scheduled == null || due < scheduled.due) { - PollTask task = new PollTask(p, due, randomiseNext); + final PollTask task = new PollTask(p, due, randomiseNext); tasks.put(t, task); - scheduler.schedule(task, delay, MILLISECONDS); + scheduler.schedule(new Runnable() { + @Override + public void run() { + ioExecutor.execute(task); + } + }, delay, MILLISECONDS); } } finally { lock.unlock(); } } + @IoExecutor private void poll(final Plugin p) { - ioExecutor.execute(new Runnable() { - @Override - public void run() { - TransportId t = p.getId(); - if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t); - p.poll(connectionRegistry.getConnectedContacts(t)); - } - }); + TransportId t = p.getId(); + if (LOG.isLoggable(INFO)) LOG.info("Polling plugin " + t); + p.poll(connectionRegistry.getConnectedContacts(t)); } private class PollTask implements Runnable { @@ -185,6 +189,7 @@ class Poller implements EventListener { } @Override + @IoExecutor public void run() { lock.lock(); try { diff --git a/briar-core/src/org/briarproject/system/SystemModule.java b/briar-core/src/org/briarproject/system/SystemModule.java index 8893a86ab0..40ca8037c9 100644 --- a/briar-core/src/org/briarproject/system/SystemModule.java +++ b/briar-core/src/org/briarproject/system/SystemModule.java @@ -2,6 +2,7 @@ package org.briarproject.system; import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.system.Clock; +import org.briarproject.api.system.Scheduler; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -17,6 +18,7 @@ public class SystemModule { public static class EagerSingletons { @Inject + @Scheduler ScheduledExecutorService scheduledExecutorService; } @@ -33,6 +35,7 @@ public class SystemModule { @Provides @Singleton + @Scheduler ScheduledExecutorService provideScheduledExecutorService( LifecycleManager lifecycleManager) { lifecycleManager.registerForShutdown(scheduler); diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java b/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java index dbc05778ba..55818bfdcc 100644 --- a/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java +++ b/briar-core/src/org/briarproject/transport/TransportKeyManagerFactoryImpl.java @@ -5,6 +5,7 @@ import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.system.Clock; +import org.briarproject.api.system.Scheduler; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; @@ -23,7 +24,7 @@ class TransportKeyManagerFactoryImpl implements @Inject TransportKeyManagerFactoryImpl(DatabaseComponent db, CryptoComponent crypto, @DatabaseExecutor Executor dbExecutor, - ScheduledExecutorService scheduler, Clock clock) { + @Scheduler ScheduledExecutorService scheduler, Clock clock) { this.db = db; this.crypto = crypto; this.dbExecutor = dbExecutor; diff --git a/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java b/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java index 3afd0ef928..72d0e444db 100644 --- a/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java +++ b/briar-core/src/org/briarproject/transport/TransportKeyManagerImpl.java @@ -9,6 +9,7 @@ import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.Transaction; import org.briarproject.api.system.Clock; +import org.briarproject.api.system.Scheduler; import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.TransportKeys; import org.briarproject.transport.ReorderingWindow.Change; @@ -48,7 +49,7 @@ class TransportKeyManagerImpl implements TransportKeyManager { private final Map<ContactId, MutableTransportKeys> keys; TransportKeyManagerImpl(DatabaseComponent db, CryptoComponent crypto, - Executor dbExecutor, ScheduledExecutorService scheduler, + Executor dbExecutor, @Scheduler ScheduledExecutorService scheduler, Clock clock, TransportId transportId, long maxLatency) { this.db = db; this.crypto = crypto; -- GitLab