- Timestamp:
- 11/28/19 14:41:10 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main/java/geniusweb/partiesserver/websocket/PartySocket.java
r4 r8 5 5 import java.net.URI; 6 6 import java.util.Date; 7 import java.util.List; 8 import java.util.concurrent.CopyOnWriteArrayList; 7 9 import java.util.logging.Level; 8 10 … … 23 25 import geniusweb.actions.Action; 24 26 import geniusweb.actions.PartyId; 25 import geniusweb.connection. DefaultConnection;27 import geniusweb.connection.ConnectionEnd; 26 28 import geniusweb.partiesserver.repository.RunningPartiesRepo; 27 29 import geniusweb.partiesserver.repository.RunningParty; 28 30 import geniusweb.party.Party; 29 import geniusweb.party.inform.Finished;30 31 import geniusweb.party.inform.Inform; 31 32 import geniusweb.party.inform.Settings; … … 41 42 */ 42 43 @ServerEndpoint("/party/{party}") 43 public class PartySocket extends DefaultConnection<Inform, Action> {44 public class PartySocket implements ConnectionEnd<Inform, Action> { 44 45 private final static ObjectMapper jackson = new ObjectMapper(); 45 46 private final Reporter log; 46 47 private final RunningPartiesRepo runningparties; 48 private final List<Listener<Inform>> listeners = new CopyOnWriteArrayList<Listener<Inform>>(); 47 49 48 50 // should all be final, except that we can only set them when start is … … 86 88 runningparties.removeListener(this); 87 89 session.close(new CloseReason(CloseCodes.GOING_AWAY, 88 " party died"));90 "detected that party vanished")); 89 91 } catch (IOException e) { 90 92 log.log(Level.WARNING, … … 131 133 party.inform(info); 132 134 } catch (Throwable e) { 133 // simple sandbox 134 log.log(Level.WARNING, "Party failed on inform:", e); 135 log.log(Level.WARNING, "Party failed on inform.", e); 136 // we don't use jackson.writeValueAsString(e) here because 137 // CloseReason has 123 char limit. 138 // The error will be too large to fit and will be truncated 139 // therefore we send a plain string and hope that enough 140 // will arrive at the other side (the protocol) 141 session.close(new CloseReason( 142 CloseReason.CloseCodes.CLOSED_ABNORMALLY, 143 "party threw exception: " + collectReasons(e))); 135 144 } 136 } // else dead but that's handled in the listener above 145 } // else party is dead but that's handled in the listener above 146 } 147 148 /** 149 * 150 * @param e an exception 151 * @return collect all reasons and sub-reasons 152 */ 153 private String collectReasons(Throwable e) { 154 String reason = ""; 155 do { 156 reason = reason + " : " + e.getClass().getSimpleName() + ":" 157 + e.getMessage(); 158 e = e.getCause(); 159 } while (e != null); 160 return reason; 137 161 } 138 162 … … 145 169 */ 146 170 private void sniff(Inform info, RunningParty party) throws IOException { 147 if (info instanceof Finished) { 148 session.close(new CloseReason(CloseCodes.GOING_AWAY, 149 "session reached agreement")); 150 } else if (info instanceof Settings) { 171 // do NOT sniff Finished messages and close sockets. Parties and their 172 // sockets need to stay running till all messages are handled 173 if (info instanceof Settings) { 151 174 Date end = ((Settings) info).getProgress().getTerminationTime(); 152 175 runningparties.replace(party.withEndTime(end)); … … 209 232 } 210 233 234 @Override 235 public void addListener(Listener<Inform> l) { 236 listeners.add(l); 237 } 238 239 @Override 240 public void removeListener(Listener<Inform> l) { 241 listeners.remove(l); 242 } 243 244 /** 245 * This should only be called by the owner of the listenable, not by 246 * listeners or others. Avoid calling this from synchronized blocks as a 247 * notified listener might immediately make more calls to you. 248 * <p> 249 * Any listeners that throw an exception will be intercepted and their 250 * stacktrace is printed. 251 * 252 * @param data information about the change. 253 */ 254 public void notifyListeners(Inform data) { 255 for (Listener<Inform> l : listeners) { 256 l.notifyChange(data); 257 } 258 } 259 211 260 }
Note:
See TracChangeset
for help on using the changeset viewer.