source: java/main/src/main/java/com/framsticks/util/dispatching/AbstractJoinable.java @ 102

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

HIGHLIGHTS:

for Joinables running

CHANGELOG:
Add WorkPackageLogic? and classes representing prime experiment state.

Add classes for PrimeExperiment? state.

Extract single netload routine in Simulator.

Working netload with dummy content in PrimeExperiment?.

More development with NetLoadSaveLogic? and PrimeExperiment?.

Improvement around prime.

Improve BufferedDispatcher?.isActive logic.

Add prime-all.xml configuration.

Manual connecting to existing simulators from GUI.

Guard in SimulatorConnector? against expdef mismatch.

Guard against empty target dispatcher in BufferedDispatcher?.

Make BufferedDispatcher? a Dispatcher (and Joinable).

Minor improvements.

Done StackedJoinable?, improve Experiment.

Develop StackedJoinable?.

Add StackedJoinable? utility joinables controller.

Add dependency on apache-commons-lang.

Add ready ListChange? on Simulators.

Improve hints in ListChange?.

Several improvements.

Found bug with dispatching in Experiment.

Minor improvements.

Fix bug with early finishing Server.

Many changes in Dispatching.

Fix bug with connection.

Do not obfuscate log with socket related exceptions.

Add SocketClosedException?.

Add SimulatorConnector?.

Work out conception of experiment composing of logics building blocks.

Rename SinkInterface? to Sink.

Move saving of Accesses into AccessOperations?.

Some improvements to Experiment.

Improve joinables.

Fix issue with joinables closing.

Add direct and managed consoles to popup menu.

File size: 5.2 KB
Line 
1package com.framsticks.util.dispatching;
2
3import java.util.Collections;
4import java.util.HashSet;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.Set;
8
9import javax.annotation.Nonnull;
10
11import org.apache.commons.collections.CollectionUtils;
12import org.apache.logging.log4j.Logger;
13import org.apache.logging.log4j.LogManager;
14
15import com.framsticks.util.FramsticksException;
16
17public abstract class AbstractJoinable implements Joinable {
18
19        private static final Logger log = LogManager.getLogger(AbstractJoinable.class);
20        private static final Logger reportLog = LogManager.getLogger(AbstractJoinable.class.getName() + ".Report");
21
22        protected final Set<JoinableParent> owners = new HashSet<JoinableParent>();
23        protected final Set<JoinableParent> joinableListeners = new HashSet<JoinableParent>();
24
25        protected static final Set<AbstractJoinable> joinablesRegistry = Collections.synchronizedSet(new HashSet<AbstractJoinable>());
26
27        protected JoinableState state = JoinableState.INITILIAZED;
28        protected JoinableParent parent;
29        protected Monitor monitor;
30
31        /**
32         *
33         */
34        public AbstractJoinable() {
35                joinablesRegistry.add(this);
36        }
37
38
39
40        public static void report() {
41                if (!reportLog.isDebugEnabled()) {
42                        return;
43                }
44                StringBuilder b = new StringBuilder();
45                synchronized (joinablesRegistry) {
46                        for (AbstractJoinable j : joinablesRegistry) {
47                                b.append("\n").append(j.getState()).append(" : ").append(j).append(" - ").append(j.getClass());
48                        }
49                }
50                reportLog.debug("state: {}", b);
51        }
52
53        private synchronized boolean changeState(JoinableState state) {
54                if (this.state.ordinal() >= state.ordinal()) {
55                        return false;
56                }
57                if (this.state.ordinal() + 1 != state.ordinal()) {
58                        throw new FramsticksException().msg("failed to change state").arg("from", this.state).arg("to", state).arg("joinable", this);
59                }
60                this.state = state;
61                log.debug("{} changed state to {}", this, state);
62
63
64                List<JoinableParent> parents = new LinkedList<>();
65                CollectionUtils.addAll(parents, joinableListeners.iterator());
66
67                for (JoinableParent p : parents) {
68                        if (p != null) {
69                                log.debug("{} is notifying parent {} about change to {}", this, p, state);
70                                Dispatching.childChangedState(p, this, state);
71                        }
72                }
73                this.notifyAll();
74
75                report();
76
77                return true;
78        }
79
80
81
82        protected final boolean startJoinable() {
83                if (changeState(JoinableState.RUNNING)) {
84                        joinableStart();
85                        return true;
86                }
87                return false;
88        }
89
90        protected final boolean interruptJoinable() {
91                if (changeState(JoinableState.FINISHING)) {
92                        joinableInterrupt();
93                        return true;
94                }
95                return false;
96        }
97
98        protected final boolean finishJoinable() {
99                if (changeState(JoinableState.JOINABLE)) {
100                        joinableFinish();
101                        return true;
102                }
103                return false;
104        }
105
106
107
108        @Override
109        public final void join() throws InterruptedException {
110                synchronized (this) {
111                        if (this.state.equals(JoinableState.JOINED)) {
112                                return;
113                        }
114                        if (!this.state.equals(JoinableState.JOINABLE)) {
115                                throw new InterruptedException();
116                        }
117                }
118                joinableJoin();
119                changeState(JoinableState.JOINED);
120                // synchronized (this) {
121                //      this.state = JoinableState.JOINED;
122                // }
123        }
124
125        protected final boolean proceedToState(JoinableState state) {
126                switch (state) {
127                        case RUNNING:
128                                return startJoinable();
129                        case FINISHING:
130                                return interruptJoinable();
131                        case JOINABLE:
132                                return finishJoinable();
133                        default: return false;
134                }
135        }
136
137        protected abstract void joinableStart();
138
139        protected abstract void joinableInterrupt();
140
141        protected abstract void joinableFinish();
142
143        protected abstract void joinableJoin() throws InterruptedException;
144
145        public final boolean use(@Nonnull JoinableParent owner) {
146                boolean start = false;
147                synchronized (this) {
148                        if (owners.contains(owner)) {
149                                throw new FramsticksException().msg("owner is already using that joinable").arg("joinable", this).arg("owner", owner);
150                        }
151                        start = owners.isEmpty();
152                        log.debug("{} is using {}", owner, this);
153                        owners.add(owner);
154                        joinableListeners.add(owner);
155                }
156                if (start) {
157                        assert monitor == null;
158                        monitor = owner.getMonitor();
159                        return this.startJoinable();
160                }
161                return false;
162        }
163
164        public final boolean drop(@Nonnull JoinableParent owner) {
165                boolean stop = false;
166                synchronized (this) {
167                        if (!owners.contains(owner)) {
168                                // log.error("owner {} is not owning that joinable {}", owner, this);
169                                // return false;
170                                throw new FramsticksException().msg("object is not owning that joinable").arg("joinable", this).arg("object", owner);
171                        }
172                        // assert owners.containsKey(owner);
173                        owners.remove(owner);
174                        stop = owners.isEmpty();
175                        log.debug("{} is droping {} (users remaining: {})", owner, this, owners);
176                }
177                if (stop) {
178                        Dispatching.dispatcherGuardedInvoke(this, new RunAt<Object>(ThrowExceptionHandler.getInstance()) {
179                                @Override
180                                protected void runAt() {
181                                        interruptJoinable();
182                                }
183                        });
184                        return true;
185                }
186                return stop;
187        }
188
189        /**
190         * @return the state
191         */
192        public JoinableState getState() {
193                return state;
194        }
195
196        protected boolean isInState(JoinableState state) {
197                return this.state.equals(state);
198        }
199
200        protected boolean isRunning() {
201                return state.equals(JoinableState.RUNNING);
202        }
203
204        @Override
205        public String toString() {
206                return getClass().getSimpleName() + "(" + getName() + ")";
207        }
208
209        // @Override
210        public Monitor getMonitor() {
211                return monitor;
212        }
213
214}
Note: See TracBrowser for help on using the repository browser.