source: simplerunner/src/main/java/geniusweb/simplerunner/Runner.java@ 52

Last change on this file since 52 was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 4.1 KB
Line 
1package geniusweb.simplerunner;
2
3import java.util.List;
4import java.util.logging.Level;
5
6import com.fasterxml.jackson.core.JsonProcessingException;
7import com.fasterxml.jackson.databind.ObjectMapper;
8
9import geniusweb.events.ProtocolEvent;
10import geniusweb.protocol.CurrentNegoState;
11import geniusweb.protocol.NegoProtocol;
12import geniusweb.protocol.NegoSettings;
13import geniusweb.protocol.NegoState;
14import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
15import tudelft.utilities.logging.Reporter;
16
17/**
18 * A simple tool to run a negotiation stand-alone, without starting the servers.
19 * All referred files and classes need to be stored locally (or be in the
20 * dependency list if you use maven).
21 * <p>
22 * <em>IMPORTANT</em> SimpleRunner has a number of restrictions, compared to a
23 * run using a runserver and partyserver
24 * <ul>
25 * <li>With stand-alone runner, your parties are run together in a single
26 * classloader. The main implication is that there may arise version conflicts
27 * between parties.
28 * <li>Stand-alone runner does NOT enforce the time deadline. Parties may
29 * continue running indefinitely and thus bog down the JVM and stalling
30 * tournaments.
31 * </ul>
32 */
33public class Runner implements Runnable {
34 private final static ObjectMapper jackson = new ObjectMapper();
35
36 private final NegoSettings settings;
37 private final NegoProtocol protocol;
38 private final ClassPathConnectionFactory connectionfactory;
39 protected final Reporter log;
40 private boolean properlyStopped = false;
41 private final int LOOPTIME = 200;// ms
42 private final int FINALWAITTIME = 5000;// ms
43 private long maxruntime;
44
45 /**
46 *
47 * @param settings the {@link NegoSettings}
48 * @param connectionfactory the {@link ProtocolToPartyConnFactory}
49 * @param logger the {@link Reporter} to log problems
50 * @param maxruntime limit in millisecs. Ignored if 0
51 */
52 public Runner(NegoSettings settings,
53 ClassPathConnectionFactory connectionfactory, Reporter logger,
54 long maxruntime) {
55 if (settings == null || connectionfactory == null) {
56 throw new NullPointerException("Arguments must be not null");
57 }
58 this.settings = settings;
59 this.log = logger;
60 this.protocol = settings.getProtocol(log);
61 this.connectionfactory = connectionfactory;
62 this.maxruntime = maxruntime;
63 }
64
65 /**
66 *
67 * @return true if the runner has finished
68 */
69 public boolean isProperlyStopped() {
70 return properlyStopped;
71 }
72
73 @Override
74 public void run() {
75 protocol.addListener(evt -> handle(evt));
76 protocol.start(connectionfactory);
77 long remainingtime = maxruntime;
78 while (!properlyStopped && (maxruntime == 0 || remainingtime > 0)) {
79 try {
80 Thread.sleep(LOOPTIME);
81 remainingtime -= LOOPTIME;
82 } catch (InterruptedException e) {
83 e.printStackTrace();
84 }
85 }
86 log.log(Level.INFO, "Waiting for connection closure");
87
88 remainingtime = FINALWAITTIME;
89 while (remainingtime > 0
90 && !connectionfactory.getOpenConnections().isEmpty()) {
91 try {
92 Thread.sleep(LOOPTIME);
93 remainingtime -= LOOPTIME;
94 } catch (InterruptedException e) {
95 e.printStackTrace();
96 }
97 }
98 List<BasicConnection> openconn = connectionfactory.getOpenConnections();
99 if (!openconn.isEmpty())
100 log.log(Level.WARNING, "Connections " + openconn
101 + " did not close properly at end of run");
102 log.log(Level.INFO, "end run");
103 }
104
105 private void handle(ProtocolEvent evt) {
106 if (evt instanceof CurrentNegoState && ((CurrentNegoState) evt)
107 .getState().isFinal(System.currentTimeMillis())) {
108 stop();
109 }
110 }
111
112 protected void stop() {
113 logFinal(Level.INFO, protocol.getState());
114 properlyStopped = true;
115 }
116
117 /**
118 * Separate so that we can intercept this when mocking, as this will crash
119 * on mocks because {@link #jackson} can not handle mocks.
120 *
121 * @param level the log {@link Level}
122 * @param state the {@link NegoState} to log
123 */
124 protected void logFinal(Level level, NegoState state) {
125 try {
126 log.log(level, "protocol ended normally: "
127 + jackson.writeValueAsString(protocol.getState()));
128 } catch (JsonProcessingException e) {
129 e.printStackTrace();
130 }
131 }
132
133 /**
134 * @return protocol that runs/ran the session.
135 */
136 public NegoProtocol getProtocol() {
137 return protocol;
138 }
139}
Note: See TracBrowser for help on using the repository browser.