- Timestamp:
- 06/22/20 16:08:10 (4 years ago)
- Location:
- src/main
- Files:
-
- 12 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main/java/geniusweb/partiesserver/RunningPartiesUpdater.java
r4 r16 12 12 * 13 13 * This object keeps the {@link RunningPartiesRepo} up to date. Main job is to 14 * remove parties that have been timed out. When a party times out, 15 * it calls {@link Party#terminate()} but that might fail to stop a party. 16 * In the end, the protocol should close the connection after the deadline. Start and run only once. 14 * remove parties that have been timed out. When a party times out, it calls 15 * {@link Party#terminate()} but that might fail to stop a party. In the end, 16 * the protocol should close the connection after the deadline. Start and run 17 * only once. 17 18 */ 18 19 public class RunningPartiesUpdater implements Runnable { … … 23 24 * when a negotiation runs out of time, the protocol may want to inform all 24 25 * parties about the failed session. If the parties are all killed at that 25 * moment, this is impossible. Therefore we wait KILL_DELAY extra time before26 * really killing the parties.26 * moment, this is impossible. Therefore we wait KILL_DELAY extra time 27 * before really killing the parties. 27 28 */ 28 29 private static final long KILL_DELAY = 2000; … … 31 32 * @param repo the {@link RunningPartiesRepo} that must be updated 32 33 * automatically 33 * @param period the period with which to check time-out (ms). Recommended 1000.34 * After constructing you can run this in separate thread or just35 * call {@link #run()}34 * @param period the period with which to check time-out (ms). Recommended 35 * 1000. After constructing you can run this in separate 36 * thread or just call {@link #run()} 36 37 * 37 38 */ … … 53 54 } 54 55 } catch (InterruptedException e) { 55 System.err.println("ERROR: RunningPartiesUpdater was interrupted!"); 56 System.err 57 .println("ERROR: RunningPartiesUpdater was interrupted!"); 56 58 } 57 59 } 58 60 59 61 /** 60 * Called when some file that may be relevant has changed. Synchronized to avoid 61 * weird states if filesystem changes rapidly. We ignore everything but jar 62 * files. 62 * Removes parties when they ran out of time. Called when some file that may 63 * be relevant has changed, and periodically every {@link #period}. 64 * Synchronized to avoid weird states if filesystem changes rapidly. We 65 * ignore everything but jar files. 63 66 */ 64 67 void update() { … … 66 69 long now = System.currentTimeMillis(); 67 70 if (now >= party.getEndDate().getTime() + KILL_DELAY) { 71 log.log(Level.WARNING, 72 "party " + party.getID() + " still running " 73 + KILL_DELAY / 1000 74 + "s after deadline. Removed now."); 68 75 running.remove(party.getID()); 69 log.log(Level.WARNING, "party " + party.getID() + " still running 2s after deadline. Removed now."); 76 try { 77 Thread.sleep(20); 78 } catch (InterruptedException e) { 79 } 70 80 } 71 81 } -
src/main/java/geniusweb/partiesserver/websocket/PartySocket.java
r9 r16 44 44 public class PartySocket implements ConnectionEnd<Inform, Action> { 45 45 private final static ObjectMapper jackson = new ObjectMapper(); 46 private static final int MAX_MESSAGE_SIZE = 20 * 1024 * 1024; 47 46 48 private final Reporter log; 47 49 private final RunningPartiesRepo runningparties; 48 50 private final List<Listener<Inform>> listeners = new CopyOnWriteArrayList<Listener<Inform>>(); 49 private static final int MAX_MESSAGE_SIZE = 20 * 1024 * 1024;51 private final ActiveThreads threads; 50 52 51 53 // should all be final, except that we can only set them when start is … … 66 68 this.runningparties = parties; 67 69 this.log = reporter; 70 this.threads = new ActiveThreads(log); 68 71 } 69 72 … … 128 131 throw new IllegalStateException("Unexpected change of session ID"); 129 132 } 133 if (!threads.isEmpty()) { 134 log.log(Level.WARNING, "Party " + partyID 135 + " is still busy with previous message"); 136 } 130 137 Inform info = jackson.readValue(informmessage, Inform.class); 131 138 RunningParty party = runningparties.get(partyID); … … 135 142 log.log(Level.FINE, "Inform " + partyID + ": " + info); 136 143 try { 144 threads.add(); 137 145 party.inform(info); 146 threads.remove(); 138 147 } catch (Throwable e) { 139 log.log(Level.WARNING, "Party failed on inform.", e); 140 e.printStackTrace(); 141 // severe as someone wants to debug that. Not severe for us 142 // we don't use jackson.writeValueAsString(e) here because 143 // CloseReason has 123 char limit. 144 // The error will be too large to fit and will be truncated 145 // therefore we send a plain string and hope that enough 146 // will arrive at the other side (the protocol) 148 threads.remove(); 149 if (e instanceof ThreadDeath) 150 /* 151 * ThreadDeath always prints stacktrace anwyay, stacktrace 152 * is useless because it contains the thrower's stacktrace 153 * instead of a useful message. 154 */ 155 log.log(Level.WARNING, 156 "Party was killed while handling inform."); 157 else 158 log.log(Level.WARNING, "Party failed on inform.", e); 159 /* 160 * severe as someone wants to debug that. Not severe for us we 161 * don't use jackson.writeValueAsString(e) here because 162 * CloseReason has 123 char limit. The error will be too large 163 * to fit and will be truncated therefore we send a plain string 164 * and hope that enough will arrive at the other side (the 165 * protocol) 166 */ 147 167 session.close(new CloseReason( 148 168 CloseReason.CloseCodes.CLOSED_ABNORMALLY, … … 186 206 public void onClose() throws IOException { 187 207 log.log(Level.INFO, "socket closed to " + partyID); 188 /* 189 * for now just kill the party. Maybe we can do something with reconnect 190 * but that will be complex. 191 */ 208 if (!threads.isEmpty()) { 209 log.log(Level.WARNING, "Party " + partyID 210 + " failed to terminate. Trying to kill the remaining threads."); 211 threads.killall(); 212 } 192 213 runningparties.remove(partyID); 193 214 outstream.stop();
Note:
See TracChangeset
for help on using the changeset viewer.