Added WriteProxy with creation method in Client, added caches to LocalDb

This commit is contained in:
Kai S. K. Engelbart 2020-02-06 21:03:08 +01:00
parent 6bbd6936e0
commit 0646445d3c
5 changed files with 155 additions and 13 deletions

View File

@ -21,7 +21,7 @@ import envoy.client.util.EnvoyLog;
public class Cache<T> implements Consumer<T> { public class Cache<T> implements Consumer<T> {
private final Queue<T> elements = new LinkedList<>(); private final Queue<T> elements = new LinkedList<>();
private Consumer<T> processor; private transient Consumer<T> processor;
private static final Logger logger = EnvoyLog.getLogger(Cache.class.getSimpleName()); private static final Logger logger = EnvoyLog.getLogger(Cache.class.getSimpleName());
@ -54,5 +54,6 @@ public class Cache<T> implements Consumer<T> {
public void relay() { public void relay() {
if (processor == null) throw new IllegalStateException("Processor is not defined"); if (processor == null) throw new IllegalStateException("Processor is not defined");
elements.forEach(processor::accept); elements.forEach(processor::accept);
elements.clear();
} }
} }

View File

@ -3,7 +3,9 @@ package envoy.client.data;
import java.util.*; import java.util.*;
import envoy.data.IdGenerator; import envoy.data.IdGenerator;
import envoy.data.Message;
import envoy.data.User; import envoy.data.User;
import envoy.event.MessageStatusChangeEvent;
/** /**
* Stores information about the current {@link User} and their {@link Chat}s. * Stores information about the current {@link User} and their {@link Chat}s.
@ -22,6 +24,8 @@ public abstract class LocalDb {
protected Map<String, User> users = new HashMap<>(); protected Map<String, User> users = new HashMap<>();
protected List<Chat> chats = new ArrayList<>(); protected List<Chat> chats = new ArrayList<>();
protected IdGenerator idGenerator; protected IdGenerator idGenerator;
protected Cache<Message> messageCache;
protected Cache<MessageStatusChangeEvent> statusCache;
/** /**
* Initializes a storage space for a user-specific list of chats. * Initializes a storage space for a user-specific list of chats.
@ -115,4 +119,28 @@ public abstract class LocalDb {
* @since Envoy v0.3-alpha * @since Envoy v0.3-alpha
*/ */
public boolean hasIdGenerator() { return idGenerator != null; } public boolean hasIdGenerator() { return idGenerator != null; }
/**
* @return the offline message cache
* @since Envoy v0.3-alpha
*/
public Cache<Message> getMessageCache() { return messageCache; }
/**
* @param messageCache the offline message cache to set
* @since Envoy v0.3-alpha
*/
public void setMessageCache(Cache<Message> messageCache) { this.messageCache = messageCache; }
/**
* @return the offline status cache
* @since Envoy v0.3-alpha
*/
public Cache<MessageStatusChangeEvent> getStatusCache() { return statusCache; }
/**
* @param statusCache the offline status cache to set
* @since Envoy v0.3-alpha
*/
public void setStatusCache(Cache<MessageStatusChangeEvent> statusCache) { this.statusCache = statusCache; }
} }

View File

@ -40,18 +40,18 @@ public class PersistentLocalDb extends LocalDb {
* Constructs an empty local database. To serialize any chats to the file * Constructs an empty local database. To serialize any chats to the file
* system, call {@link PersistentLocalDb#initializeUserStorage()}. * system, call {@link PersistentLocalDb#initializeUserStorage()}.
* *
* @param localDBDir the directory in which to store users and chats * @param localDbDir the directory in which to store users and chats
* @throws IOException if the PersistentLocalDb could not be initialized * @throws IOException if the PersistentLocalDb could not be initialized
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public PersistentLocalDb(File localDBDir) throws IOException { public PersistentLocalDb(File localDbDir) throws IOException {
this.localDBDir = localDBDir; localDBDir = localDbDir;
// Initialize local database directory // Initialize local database directory
if (localDBDir.exists() && !localDBDir.isDirectory()) if (localDbDir.exists() && !localDbDir.isDirectory())
throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); throw new IOException(String.format("LocalDbDir '%s' is not a directory!", localDbDir.getAbsolutePath()));
usersFile = new File(localDBDir, "users.db"); usersFile = new File(localDbDir, "users.db");
idGeneratorFile = new File(localDBDir, "id_generator.db"); idGeneratorFile = new File(localDbDir, "id_generator.db");
} }
/** /**

View File

@ -118,6 +118,17 @@ public class Client implements Closeable {
return cache; return cache;
} }
/**
* Creates a new write proxy that uses this client to communicate with the
* server.
*
* @param localDb the local database that the write proxy will use to access
* caches
* @return a new write proxy
* @since Envoy Client v0.3-alpha
*/
public WriteProxy createWriteProxy(LocalDb localDb) { return new WriteProxy(this, localDb); }
/** /**
* Sends a message to the server. The message's status will be incremented once * Sends a message to the server. The message's status will be incremented once
* it was delivered successfully. * it was delivered successfully.

View File

@ -0,0 +1,102 @@
package envoy.client.net;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import envoy.client.data.LocalDb;
import envoy.client.util.EnvoyLog;
import envoy.data.Message;
import envoy.event.MessageStatusChangeEvent;
/**
* Implements methods to send {@link Message}s and
* {@link MessageStatusChangeEvent}s to the server or cache them inside a
* {@link LocalDb} depending on the online status.<br>
* <br>
* Project: <strong>envoy-client</strong><br>
* File: <strong>WriteProxy.java</strong><br>
* Created: <strong>6 Feb 2020</strong><br>
*
* @author Kai S. K. Engelbart
* @since Envoy v0.3-alpha
*/
public class WriteProxy {
private final Client client;
private final LocalDb localDb;
private static final Logger logger = EnvoyLog.getLogger(WriteProxy.class.getSimpleName());
/**
* Initializes a write proxy using a client and a local database. The
* corresponding cache processors are injected into the caches.
*
* @param client the client used to send messages and message status change
* events
* @param localDb the local database used to cache messages and message status
* change events
* @since Envoy v0.3-alpha
*/
public WriteProxy(Client client, LocalDb localDb) {
this.client = client;
this.localDb = localDb;
// Initialize cache processors for messages and message status change events
localDb.getMessageCache().setProcessor(msg -> {
try {
client.sendMessage(msg);
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not send cached message", e);
}
});
localDb.getStatusCache().setProcessor(evt -> {
try {
client.sendEvent(evt);
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not send cached message status change event", e);
}
});
}
/**
* Sends cached {@link Message}s and {@link MessageStatusChangeEvent}s to the
* server.
*
* @since Envoy v0.3-alpha
*/
public void flushCache() {
// Send messages
localDb.getMessageCache().relay();
// Send message status change events
localDb.getStatusCache().relay();
}
/**
* Delivers a message to the server if online. Otherwise the message is cached
* inside the local database.
*
* @param message the message to send
* @throws IOException if the message could not be sent
* @since Envoy v0.3-alpha
*/
public void writeMessage(Message message) throws IOException {
if (client.isOnline()) client.sendMessage(message);
else localDb.getMessageCache().accept(message);
}
/**
* Delivers a message status change event to the server if online. Otherwise the
* event is cached inside the local database.
*
* @param evt the event to send
* @throws IOException if the event could not be sent
* @since Envoy v0.3-alpha
*/
public void writeMessageStatusChangeEvent(MessageStatusChangeEvent evt) throws IOException {
if (client.isOnline()) client.sendEvent(evt);
else localDb.getStatusCache().accept(evt);
}
}