- Timestamp:
- 11/28/19 14:41:10 (5 years ago)
- Location:
- src/main
- Files:
-
- 8 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/main/java/geniusweb/partiesserver/RunParty.java
r1 r8 60 60 String name = request.getPathInfo().substring(1); 61 61 log.log(Level.INFO, "request to run " + name); 62 62 System.setSecurityManager(new SimpleSecurityManager()); 63 63 AvailableParty party = AvailablePartiesRepo.instance().get(name); 64 64 if (party == null) { -
src/main/java/geniusweb/partiesserver/repository/AvailablePartiesRepo.java
r1 r8 12 12 * Stores all currently available parties that can be run. 13 13 */ 14 public class AvailablePartiesRepo extends DefaultListenable<String> implements Repository<String, AvailableParty> { 14 public class AvailablePartiesRepo extends DefaultListenable<String> 15 implements Repository<String, AvailableParty> { 15 16 private static final AvailablePartiesRepo instance = new AvailablePartiesRepo(); 16 17 … … 37 38 public void put(AvailableParty entity) { 38 39 availableParties.put(entity.getID(), entity); 39 notify Change(entity.getID());40 notifyListeners(entity.getID()); 40 41 } 41 42 … … 43 44 public void remove(String id) { 44 45 availableParties.remove(id); 45 notify Change(id);46 notifyListeners(id); 46 47 } 47 48 -
src/main/java/geniusweb/partiesserver/repository/RunningPartiesRepo.java
r1 r8 74 74 runningParties.put(id, newParty); 75 75 } 76 notify Change(id);76 notifyListeners(id); 77 77 } 78 78 … … 87 87 runningParties.put(id, newParty); 88 88 } 89 notify Change(id);89 notifyListeners(id); 90 90 91 91 } … … 125 125 } 126 126 } 127 notify Change(id);127 notifyListeners(id); 128 128 } 129 129 -
src/main/java/geniusweb/partiesserver/repository/RunningParty.java
r4 r8 9 9 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; 10 10 11 import geniusweb.actions.Action;12 11 import geniusweb.actions.PartyId; 13 12 import geniusweb.connection.DefaultConnection; 14 13 import geniusweb.partiesserver.RunningPartiesUpdater; 14 import geniusweb.partiesserver.websocket.PartySocket; 15 15 import geniusweb.party.Party; 16 16 import geniusweb.party.inform.Inform; … … 40 40 * set when someone contacts our socket. null if not set. 41 41 */ 42 private final transient DefaultConnection<Inform, Action>connection;42 private final transient PartySocket connection; 43 43 44 44 /** … … 58 58 */ 59 59 protected RunningParty(Party party, PartyId id, String name, Date start, 60 Date end, DefaultConnectionconn) {60 Date end, PartySocket conn) { 61 61 if (party == null || id == null || name == null || start == null 62 62 || end == null) { … … 101 101 * @param name The name, this should match the filename in the repo 102 102 * (without the .jar). 103 * @param maxRunTimeMS the maximum runtime for this party (ms). The {@link RunningPartiesUpdater} 104 * will keep an eye on the time and handle removal after time is up. 103 * @param maxRunTimeMS the maximum runtime for this party (ms). The 104 * {@link RunningPartiesUpdater} will keep an eye on the 105 * time and handle removal after time is up. 105 106 * 106 107 */ … … 212 213 */ 213 214 public void inform(Inform info) { 214 connection.notify Change(info);215 connection.notifyListeners(info); 215 216 } 216 217 … … 223 224 * @throws IllegalStateException if the party is already connected. 224 225 */ 225 public RunningParty withConnection( 226 DefaultConnection<Inform, Action> newconn) { 226 public RunningParty withConnection(PartySocket newconn) { 227 227 if (newconn == null) 228 228 throw new NullPointerException("newconn must be not null"); -
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.