Fix notifying the sender about a message delivery

This addresses bugs in two instances of delivery notification:
* the sender is online -> no event was sent
* the sender comes online later -> wrong status (SENT) was sent
This commit is contained in:
Kai S. K. Engelbart 2020-06-25 17:00:41 +02:00
parent 3ba5a0c64e
commit e1bfab814c
2 changed files with 37 additions and 21 deletions

View File

@ -109,14 +109,21 @@ public final class LoginCredentialProcessor implements ObjectProcessor<LoginCred
final var pendingMessages = PersistenceManager.getInstance().getPendingMessages(user); final var pendingMessages = PersistenceManager.getInstance().getPendingMessages(user);
logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "..."); logger.fine("Sending " + pendingMessages.size() + " pending messages to " + user + "...");
for (var msg : pendingMessages) { for (var msg : pendingMessages) {
final var msgCommon = msg.toCommon(); final var msgCommon = msg.toCommon();
if (msg.getStatus() == MessageStatus.SENT) { if (msg.getStatus() == MessageStatus.SENT) {
// Send the message
writeProxy.write(socketID, msgCommon); writeProxy.write(socketID, msgCommon);
msg.received(); msg.received();
if (connectionManager.isOnline(msg.getSender().getID()))
writeProxy.write(connectionManager.getSocketID(msg.getSender().getID()), new MessageStatusChange(msgCommon));
PersistenceManager.getInstance().updateMessage(msg); PersistenceManager.getInstance().updateMessage(msg);
// Notify the sender about the delivery
if (connectionManager.isOnline(msg.getSender().getID())) {
msgCommon.nextStatus();
writeProxy.write(connectionManager.getSocketID(msg.getSender().getID()), new MessageStatusChange(msgCommon));
}
} else writeProxy.write(socketID, new MessageStatusChange(msgCommon)); } else writeProxy.write(socketID, new MessageStatusChange(msgCommon));
} }
} }

View File

@ -1,21 +1,22 @@
package envoy.server.processors; package envoy.server.processors;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDateTime; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.persistence.EntityExistsException; import javax.persistence.EntityExistsException;
import envoy.data.Message; import envoy.data.Message;
import envoy.data.Message.MessageStatus; import envoy.data.Message.MessageStatus;
import envoy.event.MessageStatusChange;
import envoy.server.data.PersistenceManager; import envoy.server.data.PersistenceManager;
import envoy.server.net.ConnectionManager; import envoy.server.net.ConnectionManager;
import envoy.server.net.ObjectWriteProxy; import envoy.server.net.ObjectWriteProxy;
import envoy.util.EnvoyLog; import envoy.util.EnvoyLog;
/** /**
* This {@link ObjectProcessor} handles incoming {@link Message}s.<br> * This {@link ObjectProcessor} handles incoming {@link Message}s.
* <br> * <p>
* Project: <strong>envoy-server-standalone</strong><br> * Project: <strong>envoy-server-standalone</strong><br>
* File: <strong>MessageProcessor.java</strong><br> * File: <strong>MessageProcessor.java</strong><br>
* Created: <strong>30.12.2019</strong><br> * Created: <strong>30.12.2019</strong><br>
@ -26,6 +27,8 @@ import envoy.util.EnvoyLog;
*/ */
public class MessageProcessor implements ObjectProcessor<Message> { public class MessageProcessor implements ObjectProcessor<Message> {
private static final PersistenceManager persistenceManager = PersistenceManager.getInstance();
private static final ConnectionManager connectionManager = ConnectionManager.getInstance();
private static final Logger logger = EnvoyLog.getLogger(MessageProcessor.class); private static final Logger logger = EnvoyLog.getLogger(MessageProcessor.class);
@Override @Override
@ -35,26 +38,32 @@ public class MessageProcessor implements ObjectProcessor<Message> {
return; return;
} }
message.nextStatus(); message.nextStatus();
ConnectionManager connectionManager = ConnectionManager.getInstance();
sendToUser(connectionManager, message, writeProxy); // Convert to server message
final var serverMessage = new envoy.server.data.Message(message);
try { try {
PersistenceManager.getInstance().addMessage(new envoy.server.data.Message(message));
} catch (EntityExistsException e) {
logger.warning("Received a message with an id that already exists");
}
}
private void sendToUser(ConnectionManager connectionManager, Message message, ObjectWriteProxy writeProxy) { // Persist the message
if (connectionManager.isOnline(message.getRecipientID())) try { persistenceManager.addMessage(serverMessage);
// If recipient is online, send the message directly
writeProxy.write(connectionManager.getSocketID(message.getRecipientID()), message); // Send the message to the recipient if online
// Update the message status to RECEIVED if (connectionManager.isOnline(message.getRecipientID())) {
message.setReceivedDate(LocalDateTime.now()); writeProxy.write(connectionManager.getSocketID(message.getRecipientID()), message);
message.nextStatus();
// Increment status
message.nextStatus();
serverMessage.received();
persistenceManager.updateMessage(serverMessage);
// Notify the sender about the delivery
// Note that the exact time stamp might differ slightly
writeProxy.write(socketID, new MessageStatusChange(message));
}
} catch (EntityExistsException e) {
logger.log(Level.WARNING, "Received " + message + " with an ID that already exists!");
} catch (IOException e) { } catch (IOException e) {
logger.warning("Recipient online. Failed to send message" + message.getID()); logger.log(Level.WARNING, "Failed to deliver " + message + ":", e);
e.printStackTrace();
} }
} }