Skip to content
This repository was archived by the owner on Sep 19, 2021. It is now read-only.

Commit 29c811d

Browse files
committed
Finish Integration With Relay
Added a system called the Timeline which allows work to be set to run at specific points in time. This allows work to be queued. To allow the relay server data to merge in with the server, a work item is set to run every minute. When it finishs, it sets itself to run again in a minute. When data needs to be sent to the relay, a work item is added to the timeline so that the current connection can be closed before sending data to the relay. The timeline allowed for the Hub to be removed as work items to handle connections could be added to the timeline. Closes #4.
1 parent 851e5cd commit 29c811d

4 files changed

Lines changed: 225 additions & 193 deletions

File tree

src/codeu/chat/ServerMain.java

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,30 +83,21 @@ private static void runServer(Uuid id,
8383

8484
final Server server = new Server(id, secret, relay);
8585

86-
LOG.info("Server object created.");
86+
LOG.info("Created server.");
8787

88-
final Runnable hub = new Hub(serverSource, new Hub.Handler() {
88+
while (true) {
8989

90-
@Override
91-
public void handle(Connection connection) throws Exception {
90+
try {
9291

93-
server.handleConnection(connection);
94-
95-
}
92+
LOG.info("Established connection...");
93+
final Connection connection = serverSource.connect();
94+
LOG.info("Connection established.");
9695

97-
@Override
98-
public void onException(Exception ex) {
99-
100-
System.out.println("ERROR: Exception during server tick. Check log for details.");
101-
LOG.error(ex, "Exception during server tick.");
96+
server.handleConnection(connection);
10297

98+
} catch (IOException ex) {
99+
LOG.error(ex, "Failed to establish connection.");
103100
}
104-
});
105-
106-
LOG.info("Starting hub...");
107-
108-
hub.run();
109-
110-
LOG.info("Hub exited.");
101+
}
111102
}
112103
}

src/codeu/chat/common/Hub.java

Lines changed: 0 additions & 147 deletions
This file was deleted.

src/codeu/chat/server/Server.java

Lines changed: 69 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@
3535
import codeu.chat.common.Uuids;
3636
import codeu.chat.util.Logger;
3737
import codeu.chat.util.Serializers;
38+
import codeu.chat.util.Timeline;
3839
import codeu.chat.util.connections.Connection;
3940

4041
public final class Server {
4142

4243
private final static Logger.Log LOG = Logger.newLog(Server.class);
4344

45+
private final Timeline timeline = new Timeline();
46+
4447
private final Uuid id;
4548
private final byte[] secret;
4649

@@ -58,20 +61,57 @@ public Server(Uuid id, byte[] secret, Relay relay) {
5861

5962
this.controller = new Controller(id, model);
6063
this.relay = relay;
61-
}
6264

63-
public void syncWithRelay(int maxReadSize) throws Exception {
64-
for (final Relay.Bundle bundle : relay.read(id, secret, lastSeen, maxReadSize)) {
65-
onBundle(bundle);
66-
lastSeen = bundle.id();
67-
}
65+
timeline.scheduleNow(new Runnable() {
66+
@Override
67+
public void run() {
68+
try {
69+
70+
LOG.info("Reading update from relay...");
71+
72+
for (final Relay.Bundle bundle : relay.read(id, secret, lastSeen, 32)) {
73+
onBundle(bundle);
74+
lastSeen = bundle.id();
75+
}
76+
77+
} catch (Exception ex) {
78+
79+
LOG.error(ex, "Failed to read update from relay.");
80+
81+
}
82+
83+
// Do this all again in 60 seconds
84+
timeline.scheduleIn(60000, this);
85+
}
86+
});
6887
}
6988

70-
public boolean handleConnection(Connection connection) throws Exception {
89+
public void handleConnection(final Connection connection) {
90+
timeline.scheduleNow(new Runnable() {
91+
@Override
92+
public void run() {
93+
try {
94+
95+
LOG.info("Handling connection...");
96+
97+
final boolean success = onMessage(
98+
connection.in(),
99+
connection.out());
100+
101+
LOG.info("Connection handled: %s", success ? "ACCEPTED" : "REJECTED");
102+
} catch (Exception ex) {
71103

72-
LOG.info("Handling new connection...");
104+
LOG.error(ex, "Exception while handling connection.");
73105

74-
return onMessage(connection.in(), connection.out());
106+
}
107+
108+
try {
109+
connection.close();
110+
} catch (Exception ex) {
111+
LOG.error(ex, "Exception while closing connection.");
112+
}
113+
}
114+
});
75115
}
76116

77117
private boolean onMessage(InputStream in, OutputStream out) throws IOException {
@@ -89,13 +129,10 @@ private boolean onMessage(InputStream in, OutputStream out) throws IOException {
89129
Serializers.INTEGER.write(out, NetworkCode.NEW_MESSAGE_RESPONSE);
90130
Serializers.nullable(Message.SERIALIZER).write(out, message);
91131

92-
// Unlike the other calls - we need to send something the result of this
93-
// call to the relay. Waiting until after the server has written back to
94-
// the client allows the client to get the response, but the network
95-
// connection has not been closed. However to wait after until the client-server
96-
// connection was closed before sending would be very complicated.
97-
98-
sendToRelay(author, conversation, message.id);
132+
timeline.scheduleNow(createSendToRelayEvent(
133+
author,
134+
conversation,
135+
message.id));
99136

100137
} else if (type == NetworkCode.NEW_USER_REQUEST) {
101138

@@ -252,16 +289,21 @@ private void onBundle(Relay.Bundle bundle) {
252289
}
253290
}
254291

255-
private void sendToRelay(Uuid userId, Uuid conversationId, Uuid messageId) {
256-
257-
final User user = view.findUser(userId);
258-
final Conversation conversation = view.findConversation(conversationId);
259-
final Message message = view.findMessage(messageId);
260-
261-
relay.write(id,
262-
secret,
263-
relay.pack(user.id, user.name, user.creation),
264-
relay.pack(conversation.id, conversation.title, conversation.creation),
265-
relay.pack(message.id, message.content, message.creation));
292+
private Runnable createSendToRelayEvent(final Uuid userId,
293+
final Uuid conversationId,
294+
final Uuid messageId) {
295+
return new Runnable() {
296+
@Override
297+
public void run() {
298+
final User user = view.findUser(userId);
299+
final Conversation conversation = view.findConversation(conversationId);
300+
final Message message = view.findMessage(messageId);
301+
relay.write(id,
302+
secret,
303+
relay.pack(user.id, user.name, user.creation),
304+
relay.pack(conversation.id, conversation.title, conversation.creation),
305+
relay.pack(message.id, message.content, message.creation));
306+
}
307+
};
266308
}
267309
}

0 commit comments

Comments
 (0)