Interrupt all messaging sessions when the app starts shutting down.

This makes it more likely that connections will be closed cleanly.
However, the interrupt() method is currently ineffective for incoming
sessions as it won't interrupt a blocking read, e.g. when the packet
reader is waiting for a packet.
This commit is contained in:
akwizgran
2014-11-06 08:24:08 +00:00
parent 852a618cb3
commit 1f4d801162
5 changed files with 22 additions and 3 deletions

View File

@@ -0,0 +1,6 @@
package org.briarproject.api.event;
/** An event that is broadcast when the app is shutting down. */
public class ShutdownEvent extends Event {
}

View File

@@ -19,6 +19,8 @@ import javax.inject.Inject;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.system.Clock;
@@ -30,6 +32,7 @@ class LifecycleManagerImpl implements LifecycleManager {
private final Clock clock;
private final DatabaseComponent db;
private final EventBus eventBus;
private final Collection<Service> services;
private final Collection<ExecutorService> executors;
private final Semaphore startStopSemaphore = new Semaphore(1);
@@ -38,9 +41,10 @@ class LifecycleManagerImpl implements LifecycleManager {
private final CountDownLatch shutdownLatch = new CountDownLatch(1);
@Inject
LifecycleManagerImpl(Clock clock, DatabaseComponent db) {
LifecycleManagerImpl(Clock clock, DatabaseComponent db, EventBus eventBus) {
this.clock = clock;
this.db = db;
this.eventBus = eventBus;
services = new CopyOnWriteArrayList<Service>();
executors = new CopyOnWriteArrayList<ExecutorService>();
}
@@ -111,6 +115,7 @@ class LifecycleManagerImpl implements LifecycleManager {
}
try {
LOG.info("Stopping services");
eventBus.broadcast(new ShutdownEvent());
for(Service s : services) {
boolean stopped = s.stop();
if(LOG.isLoggable(INFO)) {

View File

@@ -30,6 +30,7 @@ import org.briarproject.api.event.MessageToRequestEvent;
import org.briarproject.api.event.RemoteRetentionTimeUpdatedEvent;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.RemoteTransportsUpdatedEvent;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.messaging.Ack;
import org.briarproject.api.messaging.MessagingSession;
@@ -169,6 +170,8 @@ class DuplexOutgoingSession implements MessagingSession, EventListener {
(RemoteTransportsUpdatedEvent) e;
if(r.getContactId().equals(contactId))
dbExecutor.execute(new GenerateTransportAcks());
} else if(e instanceof ShutdownEvent) {
interrupt();
} else if(e instanceof TransportRemovedEvent) {
TransportRemovedEvent t = (TransportRemovedEvent) e;
if(t.getTransportId().equals(transportId)) interrupt();

View File

@@ -17,6 +17,7 @@ import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.messaging.Ack;
import org.briarproject.api.messaging.Message;
@@ -108,8 +109,7 @@ class IncomingSession implements MessagingSession, EventListener {
}
public void interrupt() {
// This won't interrupt a blocking read, but the read will throw an
// exception when the transport connection is closed
// FIXME: This won't interrupt a blocking read
interrupted = true;
}
@@ -117,6 +117,8 @@ class IncomingSession implements MessagingSession, EventListener {
if(e instanceof ContactRemovedEvent) {
ContactRemovedEvent c = (ContactRemovedEvent) e;
if(c.getContactId().equals(contactId)) interrupt();
} else if(e instanceof ShutdownEvent) {
interrupt();
} else if(e instanceof TransportRemovedEvent) {
TransportRemovedEvent t = (TransportRemovedEvent) e;
if(t.getTransportId().equals(transportId)) interrupt();

View File

@@ -21,6 +21,7 @@ import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.messaging.Ack;
import org.briarproject.api.messaging.MessagingSession;
@@ -121,6 +122,8 @@ class SimplexOutgoingSession implements MessagingSession, EventListener {
if(e instanceof ContactRemovedEvent) {
ContactRemovedEvent c = (ContactRemovedEvent) e;
if(c.getContactId().equals(contactId)) interrupt();
} else if(e instanceof ShutdownEvent) {
interrupt();
} else if(e instanceof TransportRemovedEvent) {
TransportRemovedEvent t = (TransportRemovedEvent) e;
if(t.getTransportId().equals(transportId)) interrupt();