source: java/main/src/main/java/com/framsticks/hosting/Server.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: 4.8 KB
Line 
1package com.framsticks.hosting;
2
3import org.apache.logging.log4j.Level;
4import org.apache.logging.log4j.Logger;
5import org.apache.logging.log4j.LogManager;
6
7import com.framsticks.core.Tree;
8import com.framsticks.params.ParamFlags;
9import com.framsticks.params.annotations.AutoAppendAnnotation;
10import com.framsticks.params.annotations.FramsClassAnnotation;
11import com.framsticks.params.annotations.ParamAnnotation;
12import com.framsticks.util.FramsticksException;
13import com.framsticks.util.dispatching.AbstractJoinable;
14import com.framsticks.util.dispatching.Dispatching;
15import com.framsticks.util.dispatching.Joinable;
16import com.framsticks.util.dispatching.JoinableCollection;
17import com.framsticks.util.dispatching.JoinableParent;
18import com.framsticks.util.dispatching.JoinableState;
19import com.framsticks.util.dispatching.RunAt;
20import com.framsticks.util.dispatching.ThrowExceptionHandler;
21
22import java.io.IOException;
23import java.net.InetSocketAddress;
24import java.net.ServerSocket;
25import java.net.Socket;
26import java.util.TimerTask;
27
28import com.framsticks.util.dispatching.Thread;
29
30@FramsClassAnnotation
31public class Server extends AbstractJoinable implements JoinableParent {
32
33        private final static Logger log = LogManager.getLogger(Server.class);
34
35        protected int port;
36
37        protected ServerSocket acceptSocket;
38        protected Tree hosted;
39        protected final JoinableCollection<ClientAtServer> clients = new JoinableCollection<ClientAtServer>(JoinableCollection.FinishPolicy.Never);
40
41        public static class Accept {
42        };
43
44        protected Thread<Accept> acceptThread = new Thread<>();
45
46        /**
47         *
48         */
49        public Server() {
50                log.debug("created server");
51                port = 9009;
52        }
53
54        /**
55         * @return the port
56         */
57        @ParamAnnotation
58        public int getPort() {
59                return port;
60        }
61
62        /**
63         * @param port the port to set
64         */
65        @ParamAnnotation(flags = ParamFlags.USERREADONLY)
66        public void setPort(int port) {
67                this.port = port;
68        }
69
70
71        /**
72         * @return the hosted
73         */
74        public Tree getHosted() {
75                return hosted;
76        }
77
78        @AutoAppendAnnotation
79        public void setHosted(Tree hosted) {
80                if (this.hosted != null) {
81                        throw new FramsticksException().msg("hosted tree is already set").arg("current", this.hosted);
82                }
83                this.hosted = hosted;
84                acceptThread.setName(hosted.getName() + " acceptor");
85                clients.setObservableName(hosted.getName() + " clients");
86        }
87
88        @Override
89        public void childChangedState(Joinable joinable, JoinableState state) {
90                proceedToState(state);
91        }
92
93        @Override
94        @ParamAnnotation
95        public String getName() {
96                return hosted != null ? hosted.getName() : "server";
97        }
98
99        protected void acceptNext() {
100                if (!isRunning()) {
101                        log.debug("server is not in running state, aborting accepting");
102                        return;
103                }
104                acceptThread.dispatch(new RunAt<Accept>(hosted) {
105                        @Override
106                        protected void runAt() {
107                                try {
108                                        log.debug("accepting");
109                                        final Socket socket = acceptSocket.accept();
110                                        assert socket != null;
111                                        log.debug("accepted socket: {}", socket.getInetAddress().getHostAddress());
112                                        hosted.dispatch(new RunAt<Tree>(this) {
113                                                @Override
114                                                protected void runAt() {
115                                                        ClientAtServer client = new ClientAtServer(Server.this, socket);
116                                                        clients.add(client);
117                                                        log.info("client connected: {}", client);
118                                                }
119                                        });
120                                } catch (IOException e) {
121                                        log.log((isRunning() ? Level.ERROR : Level.DEBUG), "failed to accept socket: {}", e);
122                                }
123                                acceptNext();
124                        }
125                });
126        }
127
128        protected void tryBind(int when) {
129                Dispatching.getTimer().schedule(new TimerTask() {
130
131                        @Override
132                        public void run() {
133                                acceptThread.dispatch(new RunAt<Accept>(ThrowExceptionHandler.getInstance()) {
134                                        @Override
135                                        protected void runAt() {
136                                                try {
137                                                        acceptSocket.bind(new InetSocketAddress(port));
138                                                        log.debug("started accepting on port {}", port);
139                                                        acceptNext();
140                                                        return;
141                                                } catch (IOException e) {
142                                                        log.warn("failed to accept on port {} (repeating): ", port, e);
143                                                }
144                                                tryBind(1000);
145                                        }
146                                });
147                        }
148
149                }, when);
150        }
151
152
153        @Override
154        protected void joinableStart() {
155                Dispatching.use(acceptThread, this);
156                Dispatching.use(hosted, this);
157                Dispatching.use(clients, this);
158                try {
159                        acceptSocket = new ServerSocket();
160                        acceptSocket.setReuseAddress(true);
161                } catch (IOException e) {
162                        throw new FramsticksException().msg("failed to create server socket").cause(e);
163                }
164                tryBind(0);
165        }
166
167        @Override
168        protected void joinableInterrupt() {
169                Dispatching.drop(acceptThread, this);
170                Dispatching.drop(hosted, this);
171                Dispatching.drop(clients, this);
172
173                try {
174                        acceptSocket.close();
175                } catch (IOException e) {
176                        log.debug("exception caught during socket closing: ", e);
177                }
178
179                finishJoinable();
180        }
181
182        @Override
183        protected void joinableFinish() {
184
185        }
186
187        @Override
188        protected void joinableJoin() throws InterruptedException {
189                Dispatching.join(acceptThread);
190                Dispatching.join(hosted);
191                Dispatching.join(clients);
192        }
193
194}
Note: See TracBrowser for help on using the repository browser.