mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Broadcast events asynchronously.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
package org.briarproject.bramble.system;
|
||||
|
||||
import org.briarproject.bramble.api.event.EventExecutor;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.bramble.api.system.LocationUtils;
|
||||
import org.briarproject.bramble.api.system.ResourceProvider;
|
||||
import org.briarproject.bramble.api.system.SecureRandomProvider;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
@@ -32,6 +35,13 @@ public class AndroidSystemModule {
|
||||
return androidExecutor;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@EventExecutor
|
||||
Executor provideEventExecutor(AndroidExecutor androidExecutor) {
|
||||
return androidExecutor::runOnUiThread;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ResourceProvider provideResourceProvider(AndroidResourceProvider provider) {
|
||||
|
||||
@@ -16,7 +16,8 @@ public interface EventBus {
|
||||
void removeListener(EventListener l);
|
||||
|
||||
/**
|
||||
* Notifies all listeners of an event.
|
||||
* Asynchronously notifies all listeners of an event. Listeners are
|
||||
* notified on the {@link EventExecutor}.
|
||||
*/
|
||||
void broadcast(Event e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.briarproject.bramble.api.event;
|
||||
|
||||
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 the executor for broadcasting events. Also used for
|
||||
* annotating methods that should run on the event executor.
|
||||
* <p>
|
||||
* The contract of this executor is that tasks are run in the order they're
|
||||
* submitted, tasks are not run concurrently, and submitting a task will never
|
||||
* block. Tasks must not block. Tasks submitted during shutdown are discarded.
|
||||
*/
|
||||
@Qualifier
|
||||
@Target({FIELD, METHOD, PARAMETER})
|
||||
@Retention(RUNTIME)
|
||||
public @interface EventExecutor {
|
||||
}
|
||||
@@ -12,5 +12,6 @@ public interface EventListener {
|
||||
* Called when an event is broadcast. Implementations of this method must
|
||||
* not block.
|
||||
*/
|
||||
@EventExecutor
|
||||
void eventOccurred(Event e);
|
||||
}
|
||||
|
||||
@@ -160,13 +160,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
public void endTransaction(Transaction transaction) {
|
||||
try {
|
||||
T txn = txnClass.cast(transaction.unbox());
|
||||
if (!transaction.isCommitted()) db.abortTransaction(txn);
|
||||
if (transaction.isCommitted()) {
|
||||
for (Event e : transaction.getEvents()) eventBus.broadcast(e);
|
||||
} else {
|
||||
db.abortTransaction(txn);
|
||||
}
|
||||
} finally {
|
||||
if (transaction.isReadOnly()) lock.readLock().unlock();
|
||||
else lock.writeLock().unlock();
|
||||
}
|
||||
if (transaction.isCommitted())
|
||||
for (Event e : transaction.getEvents()) eventBus.broadcast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.briarproject.bramble.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.EventExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import static java.util.concurrent.Executors.newSingleThreadExecutor;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link EventExecutor} that uses a dedicated thread
|
||||
* to notify listeners of events. Applications may prefer to supply an
|
||||
* implementation that uses an existing thread, such as the UI thread.
|
||||
*/
|
||||
@Module
|
||||
public class DefaultEventExecutorModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@EventExecutor
|
||||
Executor provideEventExecutor() {
|
||||
return newSingleThreadExecutor(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
@@ -16,6 +17,11 @@ class EventBusImpl implements EventBus {
|
||||
|
||||
private final Collection<EventListener> listeners =
|
||||
new CopyOnWriteArrayList<>();
|
||||
private final Executor eventExecutor;
|
||||
|
||||
EventBusImpl(Executor eventExecutor) {
|
||||
this.eventExecutor = eventExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(EventListener l) {
|
||||
@@ -29,6 +35,8 @@ class EventBusImpl implements EventBus {
|
||||
|
||||
@Override
|
||||
public void broadcast(Event e) {
|
||||
for (EventListener l : listeners) l.eventOccurred(e);
|
||||
eventExecutor.execute(() -> {
|
||||
for (EventListener l : listeners) l.eventOccurred(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.briarproject.bramble.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventExecutor;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@@ -12,7 +15,7 @@ public class EventModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
EventBus provideEventBus() {
|
||||
return new EventBusImpl();
|
||||
EventBus provideEventBus(@EventExecutor Executor eventExecutor) {
|
||||
return new EventBusImpl(eventExecutor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.test;
|
||||
|
||||
import org.briarproject.bramble.BrambleJavaModule;
|
||||
import org.briarproject.bramble.battery.DefaultBatteryManagerModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.plugin.PluginModule;
|
||||
import org.briarproject.bramble.plugin.tor.BridgeTest;
|
||||
@@ -17,8 +18,9 @@ import dagger.Component;
|
||||
BrambleJavaModule.class,
|
||||
TestLifecycleModule.class,
|
||||
DefaultBatteryManagerModule.class,
|
||||
PluginModule.class, // needed for BackoffFactory
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
PluginModule.class, // needed for BackoffFactory
|
||||
SystemModule.class,
|
||||
})
|
||||
public interface BrambleJavaIntegrationTestComponent {
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||
import org.briarproject.bramble.crypto.CryptoModule;
|
||||
import org.briarproject.bramble.data.DataModule;
|
||||
import org.briarproject.bramble.db.DatabaseModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
@@ -46,6 +47,7 @@ import dagger.Component;
|
||||
FeedModule.class,
|
||||
DataModule.class,
|
||||
DatabaseModule.class,
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
IdentityModule.class,
|
||||
LifecycleModule.class,
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||
import org.briarproject.bramble.crypto.CryptoModule;
|
||||
import org.briarproject.bramble.data.DataModule;
|
||||
import org.briarproject.bramble.db.DatabaseModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
@@ -45,6 +46,7 @@ import dagger.Component;
|
||||
CryptoExecutorModule.class,
|
||||
DataModule.class,
|
||||
DatabaseModule.class,
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
ForumModule.class,
|
||||
GroupInvitationModule.class,
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||
import org.briarproject.bramble.crypto.CryptoModule;
|
||||
import org.briarproject.bramble.data.DataModule;
|
||||
import org.briarproject.bramble.db.DatabaseModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.sync.SyncModule;
|
||||
@@ -37,6 +38,7 @@ import dagger.Component;
|
||||
CryptoExecutorModule.class,
|
||||
DataModule.class,
|
||||
DatabaseModule.class,
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
ForumModule.class,
|
||||
IdentityModule.class,
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.briarproject.bramble.contact.ContactModule;
|
||||
import org.briarproject.bramble.crypto.CryptoModule;
|
||||
import org.briarproject.bramble.data.DataModule;
|
||||
import org.briarproject.bramble.db.DatabaseModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
@@ -46,6 +47,7 @@ import dagger.Component;
|
||||
CryptoModule.class,
|
||||
DataModule.class,
|
||||
DatabaseModule.class,
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
IdentityModule.class,
|
||||
LifecycleModule.class,
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||
import org.briarproject.bramble.crypto.CryptoModule;
|
||||
import org.briarproject.bramble.data.DataModule;
|
||||
import org.briarproject.bramble.db.DatabaseModule;
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule;
|
||||
import org.briarproject.bramble.event.EventModule;
|
||||
import org.briarproject.bramble.identity.IdentityModule;
|
||||
import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
@@ -63,6 +64,7 @@ import dagger.Component;
|
||||
CryptoExecutorModule.class,
|
||||
DataModule.class,
|
||||
DatabaseModule.class,
|
||||
DefaultEventExecutorModule.class,
|
||||
EventModule.class,
|
||||
ForumModule.class,
|
||||
GroupInvitationModule.class,
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.briarproject.bramble.api.system.Clock
|
||||
import org.briarproject.bramble.api.system.LocationUtils
|
||||
import org.briarproject.bramble.api.system.ResourceProvider
|
||||
import org.briarproject.bramble.battery.DefaultBatteryManagerModule
|
||||
import org.briarproject.bramble.event.DefaultEventExecutorModule
|
||||
import org.briarproject.bramble.network.JavaNetworkModule
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionModule
|
||||
import org.briarproject.bramble.plugin.tor.CircumventionProvider
|
||||
@@ -47,6 +48,7 @@ import javax.net.SocketFactory
|
||||
JavaSystemModule::class,
|
||||
CircumventionModule::class,
|
||||
DefaultBatteryManagerModule::class,
|
||||
DefaultEventExecutorModule::class,
|
||||
HeadlessBlogModule::class,
|
||||
HeadlessContactModule::class,
|
||||
HeadlessEventModule::class,
|
||||
|
||||
Reference in New Issue
Block a user