Allow event executor tasks to be attached to transactions.

This commit is contained in:
akwizgran
2018-11-12 14:48:01 +00:00
parent 0d0197fd2d
commit d603607a90
9 changed files with 213 additions and 86 deletions

View File

@@ -0,0 +1,20 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.EventExecutor;
/**
* An action that's taken when a {@link Transaction} is committed.
*/
public interface CommitAction {
void accept(Visitor visitor);
interface Visitor {
@EventExecutor
void visit(EventAction a);
@EventExecutor
void visit(TaskAction a);
}
}

View File

@@ -0,0 +1,24 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event;
/**
* A {@link CommitAction} that broadcasts an event.
*/
public class EventAction implements CommitAction {
private final Event event;
EventAction(Event event) {
this.event = event;
}
public Event getEvent() {
return event;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -0,0 +1,24 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.EventExecutor;
/**
* A {@link CommitAction} that submits a task to the {@link EventExecutor}.
*/
public class TaskAction implements CommitAction {
private final Runnable task;
TaskAction(Runnable task) {
this.task = task;
}
public Runnable getTask() {
return task;
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}

View File

@@ -1,13 +1,15 @@
package org.briarproject.bramble.api.db;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventExecutor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
import static java.util.Collections.emptyList;
/**
* A wrapper around a database transaction. Transactions are not thread-safe.
*/
@@ -17,7 +19,7 @@ public class Transaction {
private final Object txn;
private final boolean readOnly;
private List<Event> events = null;
private List<CommitAction> actions = null;
private boolean committed = false;
public Transaction(Object txn, boolean readOnly) {
@@ -42,19 +44,27 @@ public class Transaction {
/**
* Attaches an event to be broadcast when the transaction has been
* committed.
* committed. The event will be broadcast on the {@link EventExecutor}.
*/
public void attach(Event e) {
if (events == null) events = new ArrayList<>();
events.add(e);
if (actions == null) actions = new ArrayList<>();
actions.add(new EventAction(e));
}
/**
* Returns any events attached to the transaction.
* Attaches a task to be executed when the transaction has been
* committed. The task will be run on the {@link EventExecutor}.
*/
public List<Event> getEvents() {
if (events == null) return Collections.emptyList();
return events;
public void attach(Runnable r) {
if (actions == null) actions = new ArrayList<>();
actions.add(new TaskAction(r));
}
/**
* Returns any actions attached to the transaction.
*/
public List<CommitAction> getActions() {
return actions == null ? emptyList() : actions;
}
/**

View File

@@ -11,8 +11,9 @@ 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.
* Annotation for injecting the executor for broadcasting events and running
* tasks that need to run in a defined order with respect to 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