[101] | 1 | package com.framsticks.experiment; |
---|
| 2 | |
---|
[107] | 3 | import java.util.LinkedList; |
---|
| 4 | import java.util.List; |
---|
[101] | 5 | import java.util.Map; |
---|
| 6 | |
---|
[102] | 7 | import org.apache.logging.log4j.Level; |
---|
| 8 | import org.apache.logging.log4j.Logger; |
---|
| 9 | import org.apache.logging.log4j.LogManager; |
---|
| 10 | |
---|
[101] | 11 | import com.framsticks.params.EventListener; |
---|
[107] | 12 | import com.framsticks.params.MessageLogger; |
---|
[102] | 13 | import com.framsticks.params.ParamFlags; |
---|
[101] | 14 | import com.framsticks.params.SimpleUniqueList; |
---|
| 15 | import com.framsticks.params.annotations.AutoAppendAnnotation; |
---|
| 16 | import com.framsticks.params.annotations.FramsClassAnnotation; |
---|
| 17 | import com.framsticks.params.annotations.ParamAnnotation; |
---|
[102] | 18 | import com.framsticks.remote.RemoteTree; |
---|
[107] | 19 | import com.framsticks.structure.Path; |
---|
[105] | 20 | import com.framsticks.structure.messages.ListChange; |
---|
[107] | 21 | import com.framsticks.structure.messages.Message; |
---|
[105] | 22 | import com.framsticks.util.ExceptionHandler; |
---|
[102] | 23 | import com.framsticks.util.FramsticksException; |
---|
| 24 | import com.framsticks.util.dispatching.AbstractJoinable; |
---|
| 25 | import com.framsticks.util.dispatching.BufferedDispatcher; |
---|
| 26 | import com.framsticks.util.dispatching.Dispatcher; |
---|
| 27 | import com.framsticks.util.dispatching.DispatcherSetable; |
---|
| 28 | import com.framsticks.util.dispatching.Dispatching; |
---|
[107] | 29 | import com.framsticks.util.dispatching.Future; |
---|
| 30 | import com.framsticks.util.dispatching.FutureHandler; |
---|
[102] | 31 | import com.framsticks.util.dispatching.Joinable; |
---|
[101] | 32 | import com.framsticks.util.dispatching.JoinableCollection; |
---|
[102] | 33 | import com.framsticks.util.dispatching.JoinableParent; |
---|
| 34 | import com.framsticks.util.dispatching.JoinableState; |
---|
| 35 | import com.framsticks.util.dispatching.RunAt; |
---|
[101] | 36 | |
---|
| 37 | @FramsClassAnnotation |
---|
[105] | 38 | public class Experiment extends AbstractJoinable implements Dispatcher<Experiment>, DispatcherSetable<Experiment>, JoinableParent, ExceptionHandler { |
---|
[102] | 39 | private static final Logger log = LogManager.getLogger(Experiment.class); |
---|
[101] | 40 | |
---|
[102] | 41 | protected final JoinableCollection<Simulator> simulatorAsJoinables = new JoinableCollection<Simulator>().setObservableName("simulators"); |
---|
| 42 | |
---|
| 43 | protected final JoinableCollection<RemoteTree> simulatorCandidates = new JoinableCollection<RemoteTree>().setObservableName("candidates"); |
---|
| 44 | |
---|
[101] | 45 | protected final SimpleUniqueList<Simulator> simulators = new SimpleUniqueList<>(Simulator.class, 's'); |
---|
| 46 | |
---|
[102] | 47 | protected final SimpleUniqueList<Simulator> oldSimulators = new SimpleUniqueList<>(Simulator.class, 's'); |
---|
| 48 | |
---|
| 49 | protected final BufferedDispatcher<Experiment> bufferedDispatcher = new BufferedDispatcher<>(this); |
---|
| 50 | |
---|
[107] | 51 | protected SimulatorProvider simulatorProvider; |
---|
| 52 | |
---|
[102] | 53 | protected String expdef; |
---|
| 54 | |
---|
[107] | 55 | protected final MessageLogger messages = new MessageLogger(NetLoadSaveLogic.class); |
---|
[103] | 56 | |
---|
[102] | 57 | /** |
---|
| 58 | * |
---|
| 59 | */ |
---|
| 60 | public Experiment() { |
---|
| 61 | super(); |
---|
| 62 | bufferedDispatcher.setBuffer(false); |
---|
| 63 | |
---|
| 64 | Dispatching.dispatchLog(this, log, Level.DEBUG, "first task"); |
---|
| 65 | } |
---|
| 66 | |
---|
| 67 | /** |
---|
| 68 | * @return the simulatorCandidates |
---|
| 69 | */ |
---|
| 70 | public JoinableCollection<RemoteTree> getSimulatorCandidates() { |
---|
| 71 | return simulatorCandidates; |
---|
| 72 | } |
---|
| 73 | |
---|
[101] | 74 | @ParamAnnotation |
---|
| 75 | public Map<String, Simulator> getSimulators() { |
---|
| 76 | return simulators.getView(); |
---|
| 77 | } |
---|
| 78 | |
---|
[102] | 79 | @ParamAnnotation(id = "old_simulators") |
---|
| 80 | public Map<String, Simulator> getOldSimulators() { |
---|
| 81 | return oldSimulators.getView(); |
---|
| 82 | } |
---|
| 83 | |
---|
| 84 | /** |
---|
| 85 | * @return the dispatcher |
---|
| 86 | */ |
---|
| 87 | @Override |
---|
| 88 | public Dispatcher<Experiment> getDispatcher() { |
---|
| 89 | return bufferedDispatcher; |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | /** |
---|
| 93 | * @param dispatcher the dispatcher to set |
---|
| 94 | */ |
---|
| 95 | @Override |
---|
| 96 | public void setDispatcher(Dispatcher<Experiment> dispatcher) { |
---|
| 97 | bufferedDispatcher.setTargetDispatcher(dispatcher); |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | /** |
---|
[107] | 101 | * @return the simulatorProvider |
---|
| 102 | */ |
---|
| 103 | @ParamAnnotation(flags = ParamFlags.USERREADONLY) |
---|
| 104 | public SimulatorProvider getSimulatorProvider() { |
---|
| 105 | return simulatorProvider; |
---|
| 106 | } |
---|
| 107 | |
---|
| 108 | /** |
---|
| 109 | * @param simulatorProvider the simulatorProvider to set |
---|
| 110 | */ |
---|
| 111 | @AutoAppendAnnotation |
---|
| 112 | @ParamAnnotation |
---|
| 113 | public void setSimulatorProvider(SimulatorProvider simulatorProvider) { |
---|
| 114 | this.simulatorProvider = simulatorProvider; |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | /** |
---|
[102] | 118 | * @return the expdef |
---|
| 119 | */ |
---|
| 120 | @ParamAnnotation(flags = ParamFlags.USERREADONLY) |
---|
| 121 | public String getExpdef() { |
---|
| 122 | return expdef; |
---|
| 123 | } |
---|
| 124 | |
---|
| 125 | /** |
---|
| 126 | * @param expdef the expdef to set |
---|
| 127 | */ |
---|
| 128 | @ParamAnnotation |
---|
| 129 | public void setExpdef(String expdef) { |
---|
| 130 | this.expdef = expdef; |
---|
| 131 | } |
---|
| 132 | |
---|
[103] | 133 | |
---|
[101] | 134 | @ParamAnnotation(id = "simulators_changed") |
---|
| 135 | public void addSimulatorsListener(EventListener<ListChange> listener) { |
---|
| 136 | simulators.addListener(listener); |
---|
| 137 | } |
---|
| 138 | |
---|
| 139 | @ParamAnnotation(id = "simulators_changed") |
---|
| 140 | public void removeSimulatorsListener(EventListener<ListChange> listener) { |
---|
| 141 | simulators.removeListener(listener); |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | @AutoAppendAnnotation |
---|
| 145 | public void addSimulator(Simulator simulator) { |
---|
[107] | 146 | log.debug("add simulator {}", simulator); |
---|
[101] | 147 | simulators.add(simulator); |
---|
[102] | 148 | simulatorAsJoinables.add(simulator); |
---|
[103] | 149 | simulators.fireChildrenChange(simulator, ListChange.Action.Modify, "ready"); |
---|
[102] | 150 | |
---|
[107] | 151 | simulatorCandidates.remove(simulator.getRemoteTree()); |
---|
[101] | 152 | } |
---|
[102] | 153 | |
---|
| 154 | protected void removeSimulator(Simulator simulator) { |
---|
| 155 | simulatorAsJoinables.remove(simulator); |
---|
| 156 | simulators.remove(simulator); |
---|
| 157 | oldSimulators.add(simulator); |
---|
| 158 | } |
---|
| 159 | |
---|
| 160 | @ParamAnnotation(id = "old_simulators_changed") |
---|
| 161 | public void addOldSimulatorsListener(EventListener<ListChange> listener) { |
---|
| 162 | oldSimulators.addListener(listener); |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | @ParamAnnotation(id = "old_simulators_changed") |
---|
| 166 | public void removeOldSimulatorsListener(EventListener<ListChange> listener) { |
---|
| 167 | oldSimulators.removeListener(listener); |
---|
| 168 | } |
---|
| 169 | |
---|
| 170 | @Override |
---|
| 171 | public String getName() { |
---|
| 172 | return "experiment"; |
---|
| 173 | } |
---|
| 174 | |
---|
| 175 | @Override |
---|
| 176 | public void childChangedState(Joinable joinable, JoinableState state) { |
---|
| 177 | proceedToState(state); |
---|
| 178 | } |
---|
| 179 | |
---|
| 180 | @Override |
---|
| 181 | protected void joinableStart() { |
---|
| 182 | bufferedDispatcher.createThreadIfNeeded(); |
---|
| 183 | Dispatching.use(bufferedDispatcher, this); |
---|
| 184 | |
---|
| 185 | Dispatching.use(simulatorAsJoinables, this); |
---|
[107] | 186 | Dispatching.use(simulatorProvider, this); |
---|
[102] | 187 | Dispatching.use(simulatorCandidates, this); |
---|
[107] | 188 | |
---|
| 189 | tryProvideAllSimulators(Future.<List<Simulator>>doNothing(this)); |
---|
[102] | 190 | } |
---|
| 191 | |
---|
| 192 | @Override |
---|
| 193 | protected void joinableInterrupt() { |
---|
| 194 | |
---|
| 195 | Dispatching.drop(simulatorAsJoinables, this); |
---|
[107] | 196 | Dispatching.drop(simulatorProvider, this); |
---|
[102] | 197 | Dispatching.drop(simulatorCandidates, this); |
---|
| 198 | |
---|
[107] | 199 | Dispatching.drop(bufferedDispatcher, this); |
---|
| 200 | |
---|
[102] | 201 | finishJoinable(); |
---|
| 202 | } |
---|
| 203 | |
---|
| 204 | @Override |
---|
| 205 | protected void joinableFinish() { |
---|
| 206 | log.debug("finishing experiment {}", this); |
---|
| 207 | } |
---|
| 208 | |
---|
| 209 | @Override |
---|
| 210 | protected void joinableJoin() throws InterruptedException { |
---|
| 211 | |
---|
| 212 | Dispatching.join(simulatorAsJoinables); |
---|
[107] | 213 | Dispatching.join(simulatorProvider); |
---|
[102] | 214 | Dispatching.join(simulatorCandidates); |
---|
[107] | 215 | // Dispatching.join(bufferedDispatcher.getTargetDispatcher()); |
---|
[102] | 216 | } |
---|
| 217 | |
---|
| 218 | @Override |
---|
| 219 | public void handle(FramsticksException exception) { |
---|
| 220 | log.error("caught exception: ", exception); |
---|
| 221 | } |
---|
| 222 | |
---|
| 223 | @Override |
---|
| 224 | public boolean isActive() { |
---|
| 225 | return bufferedDispatcher.isActive(); |
---|
| 226 | } |
---|
| 227 | |
---|
| 228 | @Override |
---|
| 229 | public void dispatch(RunAt<? extends Experiment> runnable) { |
---|
| 230 | bufferedDispatcher.dispatch(runnable); |
---|
| 231 | } |
---|
| 232 | |
---|
[107] | 233 | // @ParamAnnotation(paramType = ProcedureParam.class) |
---|
| 234 | // public void connectToSimulator(String address) { |
---|
| 235 | // SimulatorConnector connector = new SimulatorConnector(); |
---|
| 236 | // connector.setAddress(address); |
---|
| 237 | // connector.attachTo(this); |
---|
| 238 | // } |
---|
| 239 | // |
---|
| 240 | |
---|
| 241 | public Simulator createSimulator(RemoteTree tree, Path path) { |
---|
| 242 | return new Simulator(this, tree, path); |
---|
[102] | 243 | } |
---|
| 244 | |
---|
[107] | 245 | public void tryProvideNextSimulator(final FutureHandler<Simulator> future) { |
---|
| 246 | log.debug("trying to provide next simulator"); |
---|
| 247 | simulatorProvider.provideSimulator(new SimulatorSpecification(this, expdef), new Future<Simulator>(future) { |
---|
| 248 | |
---|
| 249 | @Override |
---|
| 250 | protected void result(Simulator result) { |
---|
| 251 | assert isActive(); |
---|
| 252 | if (result != null) { |
---|
| 253 | addSimulator(result); |
---|
| 254 | } else { |
---|
| 255 | log.debug("no more simulators remaining"); |
---|
| 256 | } |
---|
| 257 | future.pass(result); |
---|
| 258 | |
---|
| 259 | } |
---|
| 260 | }); |
---|
| 261 | |
---|
| 262 | } |
---|
| 263 | |
---|
| 264 | public void tryProvideAllSimulators(final FutureHandler<List<Simulator>> future) { |
---|
| 265 | log.debug("trying to provide all simulators"); |
---|
| 266 | final List<Simulator> list = new LinkedList<>(); |
---|
| 267 | |
---|
| 268 | tryProvideNextSimulator(new Future<Simulator>(future) { |
---|
| 269 | |
---|
| 270 | @Override |
---|
| 271 | protected void result(Simulator result) { |
---|
| 272 | if (result == null) { |
---|
| 273 | future.pass(list); |
---|
| 274 | return; |
---|
| 275 | } |
---|
| 276 | list.add(result); |
---|
| 277 | tryProvideNextSimulator(this); |
---|
| 278 | } |
---|
| 279 | }); |
---|
| 280 | |
---|
| 281 | } |
---|
| 282 | |
---|
| 283 | @ParamAnnotation(id = "messages") |
---|
| 284 | public void addMessageListener(EventListener<Message> listener) { |
---|
| 285 | messages.add(listener); |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | @ParamAnnotation(id = "messages") |
---|
| 289 | public void removeMessageListener(EventListener<Message> listener) { |
---|
| 290 | messages.remove(listener); |
---|
| 291 | } |
---|
| 292 | |
---|
[101] | 293 | } |
---|