source: java/main/src/main/java/com/framsticks/hosting/Server.java @ 105

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

HIGHLIGHTS:

  • import refactorization: move Tree, Path, etc.

from core to structure package

  • initial serialization implementation
  • improve PrimeExperiment? test
  • many organizational changes and convenience improvements

CHANGELOG:
Make registry in AbstractTree? final.

Move most classes from core to structure package.

Minor changes.

Switch names of Future and FutureHandler?.

Rename ExceptionResultHandler? to ExceptionHandler?.

Rename ExceptionHandler? to ExceptionDispatcherHandler?.

Fix bug in ParamCandidate? cache.

Add missing synchronization to the BufferedDispatcher?.

Develop @Serialized support.

Rework serialization further.

Add serialization/deserialization interface to ValueParam?.

Move getStorageType and isNumeric from Param down to params hierarchy.

Minor changes.

Improve param type induction.

Add TestSerializedClass? for testing new serialization.

Add info files gor GenePool? and Population.

Add standard.expt exemplary netfile.

Add type name field to PropertiesObject?.

Use PropertiesObject? for PropertiesAccess? instead of ordinary map.

Hide getFramsClass is several more places.

More unification accross FramsClass?, Access and Path.

Add ParamCollection?.

Simplify interface for getting params from FramsClass?, Access
or Path.

Make Access.call() interface variadic.

Add arguments(args) convenience wrapper around new Object[] {args}.

Upgrade to apache.commons.lang version 3.1

Minor improvement with Response constructors.

Develop proper result printing in ClientAtServer?.

Add experimentNetsave to PrimeExperiment?.

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.params.ParamFlags;
8import com.framsticks.params.annotations.AutoAppendAnnotation;
9import com.framsticks.params.annotations.FramsClassAnnotation;
10import com.framsticks.params.annotations.ParamAnnotation;
11import com.framsticks.structure.Tree;
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.