source: java/main/src/main/java/com/framsticks/experiment/Simulator.java @ 103

Last change on this file since 103 was 103, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

  • add auto loading and saving algorithms between

frams files format and Java classes

  • respect ValueChange? events in GUI (do not reload object)
  • support results of procedures in Java server
  • make Experiment automatically convert between frams file and NetFile? object
  • add MessageLogger? (compatible with original frams server messages)
  • WorkPackageLogic? now validates results, is able to discard them, reschedule

whole package, or only uncomputed remainder

CHANGELOG:
Show just a short description in PrimeExperiment?.

Add primes_changed event to the PrimeExperiment?.

Make WorkPackageLogic? robust to frams server returning invalid results.

Add MessageLogger? to logics.

Add NetFile? interface. Support Messages from server.

Minor changes to connections.

Merge results in the PrimeExperiment?.

More netload class->file conversion to Simulator.

Move netsave parsing to Simulator.

Fix bug with inverted ordering of events firing in Experiment.

Minor changes.

Minor logging changes.

Use AccessOperations?.convert in NetLoadSaveLogic?

NetLoadSaveLogic? now encloses the conversion.

Use more generic AccessOperations? saveAll and loadAll in PrimePackage?.

Add Result class for enclosing of call invocations' results.

Improve feature request handling in Connections.

Use AccessOperations?.convert in RemoteTree? events parsing.

Minor change.

Add some information params to Java server root and CLI objects.

A draft implementation of loadAll algorithm.

That algorithm tries to load objects into a tree structure.

Add AccessOperationsTest? test.

Develop WorkPackageLogic?.

  • add state tracking fields
  • add work package generation

Add utility class SimplePrimitive?.

Meant for Java backend classes, enclose a single primitive value
and set of listeners.

Improve primitive value refresh in GUI.

When ValueChange? found in called event, do not reload whole
object, but only update GUI (no communication is performed).

Use ValueChange? in the TestClass? test.

Minor changes.

Sending all packages in PrimeExperiment? to the frams servers.

Develop AccessOperations?.loadComposites().

Remove addAccess from MultiParamLoader? interface.

There is now no default AccessProvider? in MultiParamLoader?.
User must explicitely set AccessStash? or Registry.

Improve saving algorithms in AccessOperations?.

File size: 7.2 KB
Line 
1package com.framsticks.experiment;
2
3import com.framsticks.communication.File;
4import com.framsticks.communication.queries.NeedFile;
5import com.framsticks.communication.queries.NeedFileAcceptor;
6import com.framsticks.core.ListChange;
7import com.framsticks.core.Path;
8import com.framsticks.core.Tree;
9import com.framsticks.core.ValueChange;
10import com.framsticks.params.AccessOperations;
11import com.framsticks.params.CastFailure;
12import com.framsticks.params.EventListener;
13import com.framsticks.params.FramsClass;
14import com.framsticks.params.UniqueObject;
15import com.framsticks.params.annotations.FramsClassAnnotation;
16import com.framsticks.params.annotations.ParamAnnotation;
17import com.framsticks.params.types.BooleanParam;
18import com.framsticks.params.types.EventParam;
19import com.framsticks.params.types.ProcedureParam;
20import com.framsticks.remote.RemoteTree;
21import com.framsticks.util.FramsticksException;
22import com.framsticks.util.dispatching.AbstractJoinable;
23import com.framsticks.util.dispatching.Dispatcher;
24import com.framsticks.util.dispatching.Dispatching;
25import com.framsticks.util.dispatching.ExceptionResultHandler;
26import com.framsticks.util.dispatching.Future;
27import com.framsticks.util.dispatching.FutureHandler;
28import com.framsticks.util.dispatching.Joinable;
29import com.framsticks.util.dispatching.JoinableParent;
30import com.framsticks.util.dispatching.JoinableState;
31import com.framsticks.util.dispatching.RunAt;
32import com.framsticks.util.dispatching.ThrowExceptionHandler;
33import com.framsticks.util.lang.Holder;
34import java.util.concurrent.atomic.AtomicInteger;
35import org.apache.logging.log4j.LogManager;
36import org.apache.logging.log4j.Logger;
37import static com.framsticks.core.TreeOperations.*;
38
39@FramsClassAnnotation
40public final class Simulator extends AbstractJoinable implements Dispatcher<Simulator>, JoinableParent, UniqueObject, ExceptionResultHandler {
41
42        private static final Logger log = LogManager.getLogger(Simulator.class);
43
44        protected String uid;
45
46        protected final RemoteTree remoteTree;
47        protected final Path simulatorPath;
48        protected final FramsClass simulatorClass;
49        protected final Experiment experiment;
50        protected final EventListener<ValueChange> runningListener;
51
52        /**
53         *
54         */
55        public Simulator(Experiment experiment, RemoteTree remoteTree, Path simulatorPath) {
56                super();
57                this.remoteTree = remoteTree;
58                this.simulatorPath = simulatorPath.assureResolved();
59                this.experiment = experiment;
60                this.simulatorClass = getFramsClass(simulatorPath);
61
62                assert remoteTree.isActive();
63                assert experiment.isActive();
64
65                log.info("simulator ready {}", this);
66
67                runningListener = new EventListener<ValueChange>() {
68                        @Override
69                        public void action(ValueChange argument) {
70                                try {
71                                        boolean running = simulatorClass.getParamEntry("running", BooleanParam.class).reassign(argument.value, null).getValue();
72                                        log.debug("running state of {} changed: {}", Simulator.this, running);
73                                        if (!running) {
74                                                Simulator.this.experiment.simulators.fireChildrenChange(Simulator.this, ListChange.Action.Modify, "ready", "stoped");
75                                        }
76                                } catch (CastFailure e) {
77                                        log.error("failure: ", e);
78                                }
79                        }
80                };
81
82                addListener(simulatorPath, simulatorClass.getParamEntry("running_changed", EventParam.class), runningListener, ValueChange.class, new FutureHandler<Void>(this) {
83                        @Override
84                        protected void result(Void result) {
85                                log.debug("running listener for {} registered", this);
86                        }
87                });
88        }
89
90        @ParamAnnotation
91        public String getAddress() {
92                return remoteTree.getAddress();
93        }
94
95        @Override
96        @ParamAnnotation
97        public String getName() {
98                return getAddress();
99        }
100
101        @Override
102        @ParamAnnotation
103        public String getUid() {
104                return uid;
105        }
106
107        @Override
108        public void setUid(String uid) {
109                this.uid = uid;
110        }
111
112        /**
113         * @return the tree
114         */
115        @ParamAnnotation
116        public RemoteTree getRemoteTree() {
117                return remoteTree;
118        }
119
120        /**
121         * @return the simulatorPath
122         */
123        public Path getSimulatorPath() {
124                return simulatorPath;
125        }
126
127        /**
128         * @return the simulatorClass
129         */
130        public FramsClass getSimulatorClass() {
131                return simulatorClass;
132        }
133
134        @Override
135        protected void joinableStart() {
136                Dispatching.use(remoteTree, this);
137        }
138
139        @Override
140        protected void joinableInterrupt() {
141                Dispatching.drop(remoteTree, this);
142
143        }
144
145        @Override
146        protected void joinableFinish() {
147
148        }
149
150        @Override
151        protected void joinableJoin() throws InterruptedException {
152                Dispatching.join(remoteTree);
153        }
154
155        @ParamAnnotation(paramType = ProcedureParam.class)
156        public void init() {
157        }
158
159        @ParamAnnotation(paramType = ProcedureParam.class)
160        public void start() {
161                log.debug("starting simulator {}", this);
162                call(simulatorPath, "start", new Object[] {}, Object.class, FutureHandler.doNothing(Object.class, this));
163        }
164
165        @ParamAnnotation(paramType = ProcedureParam.class)
166        public void stop() {
167                log.debug("stoping simulator {}", this);
168        }
169
170        @ParamAnnotation(paramType = ProcedureParam.class)
171        public void abort() {
172                assert isActive();
173                log.info("explicitly aborting {}", this);
174                experiment.removeSimulator(this);
175                interruptJoinable();
176        }
177
178        @Override
179        public void childChangedState(Joinable joinable, JoinableState state) {
180                proceedToState(state);
181        }
182
183        @Override
184        public void handle(FramsticksException exception) {
185                experiment.handle(new FramsticksException().msg("exception caught in simulator").arg("simulator", this).cause(exception));
186        }
187
188        @Override
189        public boolean isActive() {
190                return experiment.isActive();
191        }
192
193        @SuppressWarnings({ "rawtypes", "unchecked" })
194        @Override
195        public void dispatch(RunAt<? extends Simulator> runnable) {
196                experiment.dispatch((RunAt) runnable);
197        }
198
199        protected final AtomicInteger netloadIdCounter = new AtomicInteger();
200
201        public <N> void netload(final N net, final Future<Object> future) {
202                final String netloadId = "NetLoadSaveLogic" + netloadIdCounter.getAndIncrement();
203
204                final File file = AccessOperations.convert(File.class, net, getRemoteTree().getRegistry());
205                log.debug("uploading file {} to {} identified by {}", file, simulatorPath, netloadId);
206
207                final Holder<NeedFileAcceptor> acceptor = new Holder<>();
208                final Tree tree = simulatorPath.getTree();
209
210                acceptor.set(new NeedFileAcceptor() {
211
212                        @Override
213                        public boolean acceptNeed(NeedFile needFile) {
214                                if (!needFile.getDescription().equals(netloadId)) {
215                                        return false;
216                                }
217                                log.debug("accepting netload {}", netloadId);
218                                needFile.getFuture().pass(file);
219                                tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
220
221                                        @Override
222                                        protected void runAt() {
223                                                tree.removeNeedFileAcceptor(acceptor.get());
224                                        }
225                                });
226                                return true;
227                        }
228
229                });
230
231                simulatorPath.getTree().addNeedFileAcceptor(Integer.MIN_VALUE, acceptor.get());
232
233                call(simulatorPath, getFramsClass(simulatorPath).getParamEntry("netload_id", ProcedureParam.class), new Object[] { netloadId }, Object.class, new FutureHandler<Object>(future) {
234
235                        @Override
236                        protected void result(Object result) {
237                                log.debug("upload of {} done", file);
238                                future.pass(result);
239                        }
240                });
241
242        }
243
244        public <N> void netsave(Class<N> netJavaClass, final Future<N> futureNet) {
245                call(simulatorPath, getFramsClass(simulatorPath).getParamEntry("netsave", ProcedureParam.class), new Object[] { }, netJavaClass, new FutureHandler<N>(futureNet) {
246
247                        @Override
248                        protected void result(N net) {
249                                log.debug("download of {} done", net);
250                                futureNet.pass(net);
251                        }
252                });
253
254        }
255}
Note: See TracBrowser for help on using the repository browser.