pax_global_header 0000666 0000000 0000000 00000000064 12274461040 0014512 g ustar 00root root 0000000 0000000 52 comment=e6cb898455ebffa7113c0e88aa39c7664d9d238f
hawtdispatch-hawtdispatch-project-1.20/ 0000775 0000000 0000000 00000000000 12274461040 0020244 5 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/.gitignore 0000664 0000000 0000000 00000000145 12274461040 0022234 0 ustar 00root root 0000000 0000000 .classpath
.project
.settings
*.iml
*.ipr
*.iws
webgen/out
webgen/webgen.cache
target
.DS_Store
.idea hawtdispatch-hawtdispatch-project-1.20/build.gradle 0000664 0000000 0000000 00000002112 12274461040 0022517 0 ustar 00root root 0000000 0000000 subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile 'asm:asm-tree:3.1', 'org.osgi:org.osgi.core:4.2.0', 'org.osgi:org.osgi.compendium:4.2.0', 'log4j:log4j:1.2.14', 'org.fusesource.hawtbuf:hawtbuf:1.9'
testCompile 'junit:junit:4.7'
}
tasks.withType(Compile) {
options.encoding = 'UTF-8'
options.warnings = false
}
}
project(':hawtdispatch-example') {
dependencies {
compile project(':hawtdispatch-scala'), project(':hawtdispatch-transport'), 'org.scala-lang:scala-library:2.10.0', 'org.scala-lang:scala-compiler:2.10.0'
testCompile 'org.scalatest:scalatest_2.10.0:2.10.0'
}
}
project(':hawtdispatch-netty') {
dependencies {
compile 'io.netty:netty-transport:4.0.0.Beta1', project(':hawtdispatch')
}
}
project(':hawtdispatch-scala') {
dependencies {
compile 'iorg.scala-lang:scala-library:2.10.0', project(':hawtdispatch')
testCompile 'org.scalatest:scalatest_2.10.0:2.10.0'
}
}
project(':hawtdispatch-transport') {
dependencies {
compile project(':hawtdispatch')
}
}
hawtdispatch-hawtdispatch-project-1.20/changelog.md 0000664 0000000 0000000 00000022350 12274461040 0022517 0 ustar 00root root 0000000 0000000 # 
=============================================================================
## [HawtDispatch 1.19](http://hawtdispatch.fusesource.org/blog/releases/release-1-19.html), released 2014-01-23
* You can now configure the what cypher suites are enabled on a SSLTransport via the enabledCypherSuites property
* add gradle build script
* Fix range check on timeout, as it always evaluated to true
* Fixing bugs where the read/write rate limiting features of the tcp transport might not take effect.
## [HawtDispatch 1.18](http://hawtdispatch.fusesource.org/blog/releases/release-1-18.html), released 2013-10-11
* Do not even invoke getLocalHost() if not necessary
* propagate name resolution exceptions in the correct thread context
* Fixes issue #11 : Typo in TcpTransportServer
## [HawtDispatch 1.17](http://hawtdispatch.fusesource.org/blog/releases/release-1-17.html), released 2013-05-18
* Add a get method to Future objects.
* Fixing bug where SSL transports were not getting past the SSL handshake (on linux).
## [HawtDispatch 1.16](http://hawtdispatch.fusesource.org/blog/releases/release-1-16.html), released 2013-05-10
* Fixing invalid the metric duration value.
* Do a better job ignoring errors when JMX is not supported by the platform. (Android etc.)
* Fixes issue #9: HawtDispatch does not work on Android 4.0
## [HawtDispatch 1.15](http://hawtdispatch.fusesource.org/blog/releases/release-1-15.html), released 2013-04-19
* Also include info about how long the metric was monitored for.
* Expose dispatch queue profiling data via JMX.
## [HawtDispatch 1.14](http://hawtdispatch.fusesource.org/blog/releases/release-1-14.html), released 2013-04-09
* Fixes bug where you could end up in a CPU spin when the SSL session closed.
* Added a disabledCypherSuites property to the SSL transports to support disabling some of the supported cypher suites.
* Add a getThread() method to the ThreadDispatchQueue class.
## [HawtDispatch 1.13](http://hawtdispatch.fusesource.org/blog/releases/release-1-13.html), released 2012-12-23
* Upgrade to scala 2.10
* Avoid possible NPE.
* Setup the client SSL transports so that the internal session reuse strategy can be used.
## [HawtDispatch 1.12](http://hawtdispatch.fusesource.org/blog/releases/release-1-12.html), released 2012-09-20
* Custom dispatch sources will now return null after the event has been received to avoid accidentally double processing events.
* Make sure we only return false from the offer method when the transport is also full()
* Add a closeOnCancel option to disable closing the socket when the transport is stopped.
* Rename the SecuredTransport interface to SecuredSession and now both the SSLProtocolCodec and SslTransport implement it.
* You can now handle SSL/TLS encoding/decoding via a wrapping protocol codec. ProtocolCodec and Transport interfaces needs a couple of adjustments to properly support the co
* Better handling of getting the local host address.
* Protocol codec decoding optimizations.
* Move all the connect logic into the start method.
* Do host name resolutions on a blocking executor to avoid stalling the hawtdispatch threads.
* Resize the read buffer after reading from the channel if to avoid to avoid holding on to large buffers.
* Support changing the socket send/recv buffer size on started transports and servers.
* Do at least a non blocking select when we notice that another thread requested the NIO manager wakeup. This should allow us to pickup any new IO events that have occurred
* Dropped the continuations example, added a SSL transport client example
## [HawtDispatch 1.11](http://hawtdispatch.fusesource.org/blog/releases/release-1-11.html), released 2012-05-02
* Support buffer pooling in the abstract protocol codec.
* Adding a TransportAware interface which codecs can implement to be injected with their associated codec.
* Make it easy to configure the client auth mode on the ssl transport server.
* Fixes SSL transport bug where inbound data was not delivered after SSL handshake completed.
* Allow a SslTransportServer to be created just using the constructor.
## [HawtDispatch 1.10](http://hawtdispatch.fusesource.org/blog/releases/release-1-10.html), released 2012-04-06
* Fix assertion error message.
* Switch to using 'Task' abstract base instead of the Runnable interface, in many cases it improves perf by 20% since virtual invocations are cheaper then interface invocation
* Adding a UDP based transport.
* Support configuring the client auth mode.
## [HawtDispatch 1.9](http://hawtdispatch.fusesource.org/blog/releases/release-1-9.html), released 2012-02-27
* Fixes LOW priority global queue was being created with a high thread priority.
* Distribute work load spikes fairly to the worker threads.
* Support updating the transport's dispatch queue.
* Add assertion that catches the following error: queue.setTargetQueue(queue)
* Adding a SecureTransport interface and removing many of the leaky abstractions in the transport package.
## [HawtDispatch 1.8](http://hawtdispatch.fusesource.org/blog/releases/release-1-8.html), released 2012-01-30
* Fixes CPU spin that occurred when a peer disconnected while SSL handshake is in progress.
* Could not create a client initiated SSL connection.
## [HawtDispatch 1.7](http://hawtdispatch.fusesource.org/blog/releases/release-1-7.html), released 2012-01-13
* Cleaning up the transport interfaces. Added an abstract protocol codec that makes it easier to implement them.
## [HawtDispatch 1.6](http://hawtdispatch.fusesource.org/blog/releases/release-1-6.html), released 2011-12-19
* Support using a system property to configure the number of dispatch threads.
* Added a hawtdispatch-transport module which provides nice Transport abstraction for working with Sockets and HawtDispatch.
## [HawtDispatch 1.5](http://hawtdispatch.fusesource.org/blog/releases/release-1-5.html), released 2011-11-29
* HawtDispatch threads are now in a thread group. Setting the UnchaughtExceptionHandler on one of the HawtDispatch threads set the handler for all the threads in the pool.
* Pass an uncaught exceptions to the UncaughtExceptionHandler configured on the HawtDispatch threads.
* Added UDP example
* Fix race condition that was occurring when a serial dispatch queue was suspended.
* Switch to new scalate version which fixes build problems when on OS X Lion.
## [HawtDispatch 1.4](http://hawtdispatch.fusesource.org/blog/releases/release-1-4.html), released 2011-07-18
* Support ordered EventAggregators
## [HawtDispatch 1.3](http://hawtdispatch.fusesource.org/blog/releases/release-1-3.html), released 2011-06-01
* Added an assertExecuting method to the DispatchQueue interface.
* Protect against exceptions from the event dispatch source handlers.
* Upgrade to Scala 2.9.0-1
## [HawtDispatch 1.2](http://hawtdispatch.fusesource.org/blog/releases/release-1-2.html), released 2011-01-20
* Protect against exceptions from the event dispatch source handlers.
* Adding a new HawtServerSocketChannel and HawtSocketChannel which use scala continuations and hawtdispatch to implement NIO based sockets
* Enriching executors with a `runnable` - enriching dispatch queues with a `repeatAfter` method
* Trimming dead code.
* Inline the dispatch a bit.
* Making dispatch queue interface more consistent with java executors. renamed dispatchAsync to just plain execute, and renamed dispatchAfter to executeAfter
* Removing the Retained interface from the dispatch objects. It adds complexity and overhead without providing the much benefit due to the JVM's automatic GC
* Added scala type getter/setters for the a dispatch queue label.
* Protect against ConcurrentModificationException on the selector's selecteKeys.
* Enriched the DispatchSource objects
* Added some doco on the new `!!` method.
* Adjusted paul's auto reset method so that it also returns a future.
* Added await methods to the future since they are easier to spot than the apply methods.
* Support for function, !^, that wraps a partial function in a reset block, thus hiding shift/reset.
* OSGi integration, added activator so that started thread can be shutdown when the bundle is stopped. Also exposed the Dispatch interface
* Added OSGi metadata to the jars.
## [HawtDispatch 1.1](http://hawtdispatch.fusesource.org/blog/releases/release-1-1.html), released 2011-01-20
* Fix bug where the scala version of getCurrentThreadQueue was returning null
* A Future can trigger a callback once it's completed.
* Scala continuation support added.
* Built against Scala 2.8.1
* The maximum number of executions drained from a serial queue before checking
global queues for more work is now configurable via the `hawtdispatch.drains`
system property.
* createSerialQueue renamed to createQueue to make the API more consistent.
* Handling the case where a selector key is canceled during registration.
* Timer thread is more efficient now.
* Added a AggregatingExecutor to batch up executions
* You can now hook into getting profiling statistics of the dispatch queues
* Fixed the INTEGER_OR aggregator
* Scala usage simplification, import org.fusesource.hawtdispatch._ instead of
org.fusesource.hawtdispatch.ScalaDispatch._
* More test cases
* Add getThreadQueue method
## [HawtDispatch 1.0](http://hawtdispatch.fusesource.org/blog/releases/release-1-0.html), released 2010-07-22
* Initial release hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/ 0000775 0000000 0000000 00000000000 12274461040 0024360 5 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/pom.xml 0000775 0000000 0000000 00000013000 12274461040 0025672 0 ustar 00root root 0000000 0000000
*
* * @author Hiram Chirino */ public class CustomDispatchSourceJava { public static void main(String[] args) throws Exception { run(); } public static void run() throws Exception { final Semaphore done = new Semaphore(1-(1000*1000)); DispatchQueue queue = createQueue(); final CustomDispatchSource*
* * @author Hiram Chirino */ object CustomDispatchSourceScala { def main(args: Array[String]): Unit = { run } def run() = { val done = new Semaphore(1 - (1000 * 1000)) val queue = createQueue() val source = createSource(EventAggregators.INTEGER_ADD, queue) source.setEventHandler(^{ val count = source.getData() println("got: " + count) done.release(count.intValue) }); source.resume(); // Produce 1,000,000 concurrent merge events for (i <- 0 until 1000) { globalQueue { for (j <- 0 until 1000) { source.merge(1) } } } // Wait for all the event to arrive. done.acquire() } } EchoServer.scala 0000664 0000000 0000000 00000006555 12274461040 0041254 0 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example /** * Copyright (C) 2012 FuseSource, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtdispatch.example import java.io.{IOException} import java.net.{InetSocketAddress} import org.fusesource.hawtdispatch._ import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; /** * A simple echo server example. * * @author Hiram Chirino */ object EchoServer { var port=4444; def main(args:Array[String]):Unit = { run } def run() = { val server = new Server(port).start println("Press enter to shutdown."); System.in.read server.stop } class Server(val port: Int) { val channel = ServerSocketChannel.open(); channel.socket().bind(new InetSocketAddress(port)); channel.configureBlocking(false); val queue = createQueue("server") val accept_source = createSource(channel, SelectionKey.OP_ACCEPT, queue); accept_source.setEventHandler(^ { val socket = channel.accept(); try { socket.configureBlocking(false); new Session(socket).start() } catch { case e: Exception => socket.close } }); println("Listening on port: "+port); def start() = { accept_source.resume this } def stop() = { accept_source.cancel } accept_source.onCancel { channel.close(); println("Closed port: "+port); } } class Session(val channel: SocketChannel) { val buffer = ByteBuffer.allocate(1024); val queue = createQueue("session") val read_source = createSource(channel, SelectionKey.OP_READ, queue); val write_source = createSource(channel, SelectionKey.OP_WRITE, queue); val remote_address = channel.socket.getRemoteSocketAddress.toString def start() = { println("Accepted connection from: "+remote_address); read_source.resume } def close() = { read_source.cancel } read_source.onCancel { write_source.cancel } write_source.onCancel { channel.close println("Closed connection from: "+remote_address); } read_source.setEventHandler(^{ try { if (channel.read(buffer) == -1) { close } else { buffer.flip; if (buffer.remaining > 0) { read_source.suspend write_source.resume } else { buffer.clear } } } catch { case e:IOException => close } }) write_source.setEventHandler(^{ try { channel.write(buffer) if (buffer.remaining == 0) { buffer.clear write_source.suspend read_source.resume } } catch { case e:IOException => close } }) } } SSLClientExample.java 0000664 0000000 0000000 00000012145 12274461040 0042151 0 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example /** * Copyright (C) 2012 FuseSource, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtdispatch.example; import org.fusesource.hawtbuf.AsciiBuffer; import org.fusesource.hawtbuf.Buffer; import org.fusesource.hawtdispatch.Dispatch; import org.fusesource.hawtdispatch.Task; import org.fusesource.hawtdispatch.transport.AbstractProtocolCodec; import org.fusesource.hawtdispatch.transport.DefaultTransportListener; import org.fusesource.hawtdispatch.transport.SslTransport; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.net.URI; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; /** */ public class SSLClientExample { // A fake trust manager to accept self signed certs. static final TrustManager[] TRUST_ALL_CERTS = new TrustManager[]{ new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } } }; // A very simple codec that just passes along byte buffers.. // A more realistic example can be found at: // https://github.com/fusesource/stompjms/blob/master/stompjms-client/src/main/java/org/fusesource/stomp/codec/StompProtocolCodec.java private static class BufferProtocolCodec extends AbstractProtocolCodec { @Override protected void encode(Object value) throws IOException { Buffer buffer = (Buffer) value; nextWriteBuffer.write(buffer); } @Override protected Action initialDecodeAction() { return readCommand(); } protected Action readCommand() { return new Action() { public Object apply() throws IOException { int length = readBuffer.position() - readStart; if (length > 0) { int offset = readStart; readEnd = offset + length; readStart = readEnd; return new Buffer(readBuffer.array(), offset, length); } else { return null; } } }; } } public static void main(String[] args) throws Exception { // Setup an SSLContext that accepts self signed certs. SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, TRUST_ALL_CERTS, new SecureRandom()); final SslTransport client = new SslTransport(); client.setDispatchQueue(Dispatch.createQueue()); client.setSSLContext(sslContext); client.setBlockingExecutor(Executors.newCachedThreadPool()); client.setProtocolCodec(new BufferProtocolCodec()); client.connecting(new URI("ssl://localhost:61614"), null); final CountDownLatch done = new CountDownLatch(1); final Task onClose = new Task() { public void run() { System.out.println("Client closed."); done.countDown(); } }; client.setTransportListener(new DefaultTransportListener() { @Override public void onTransportConnected() { System.out.println("Connected"); client.resumeRead(); // Once we are connected send some data.. client.offer(new AsciiBuffer( "CONNECT\n" + "login:admin\n" + "passcode:password\n" + "\n\u0000\n" )); } // all we do is echo back the request, but change the frame, // command to RESPONSE. @Override public void onTransportCommand(Object command) { Buffer frame = (Buffer) command; System.out.println("Received :" + frame.ascii()); client.stop(onClose); } @Override public void onTransportFailure(IOException error) { System.out.println("Transport failure :" + error); client.stop(onClose); } }); client.start(Dispatch.NOOP); done.await(); } } UdpEchoServer.scala 0000664 0000000 0000000 00000011420 12274461040 0041710 0 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example /** * Copyright (C) 2012 FuseSource, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtdispatch.example import java.io.{IOException} import org.fusesource.hawtdispatch._ import java.nio.ByteBuffer import java.nio.channels.{DatagramChannel, SelectionKey, ServerSocketChannel, SocketChannel} import java.net.{SocketAddress, InetSocketAddress} import java.util.LinkedList /** * A udp echo server example. Concurrently reads and writes * packets by using 2 dispatch queues. Uses a custom dispatch * source to handle coalescing interaction events between * the sender and receiver queues. * * @author Hiram Chirino */ object UdpEchoServer { var port=4444; def main(args:Array[String]):Unit = { run } def run() = { val server = new Server(port) server.start println("Press enter to shutdown."); System.in.read server.close } class Server(val port: Int) { val channel = DatagramChannel.open(); channel.socket().bind(new InetSocketAddress(port)); channel.configureBlocking(false); println("Listening on port: "+port); object receiver { // All mutable state in this object is modified while executing // on this queue val queue = createQueue("receive") private var outbound = 0 private val outbound_max = 1024; val read_events = createSource(channel, SelectionKey.OP_READ, queue); read_events.onEvent { try { val buffer = ByteBuffer.allocate(1024); var address: SocketAddress = channel.receive(buffer); if( address!=null ) { buffer.flip; outbound += 1 sender.outbound_events.merge((buffer, address)) // stop receiving until the outbound is drained (aka: flow control) if ( outbound_max < outbound ) { read_events.suspend } } } catch { case e:IOException => close } } // outbound_ack_events is used to let the sender know when the sends complete val outbound_ack_events = createSource(EventAggregators.INTEGER_ADD, queue) outbound_ack_events.onEvent { outbound -= outbound_ack_events.getData() if(read_events.isSuspended) read_events.resume() } outbound_ack_events.resume(); } object sender { // All mutable state in this object is modified while executing // on this queue val queue = createQueue("send") // pick up outbound events private val outbound = new LinkedList[(ByteBuffer, SocketAddress)] // outbound_events is an event bridge between the receiver and the sender event queues // It will merge multiple events from the receiver queue into 1 event that gets delivered // to the sender queue val outbound_events = createSource(new ListEventAggregator[(ByteBuffer, SocketAddress)], queue) outbound_events.onEvent { for( value <- outbound_events.getData() ) { outbound.add(value) } drainOutbound } outbound_events.resume(); // We need to drain the list of outbound packets when socket reports it // can be written to. val write_events = createSource(channel, SelectionKey.OP_WRITE, queue); write_events.onEvent(drainOutbound) def drainOutbound:Unit = try { while(!outbound.isEmpty) { val (buffer, address) = outbound.peek(); channel.send(buffer, address) if(buffer.remaining()==0) { // Packet sent, let the receive know in case he stopped. receiver.outbound_ack_events.merge(1) outbound.poll() } else { // Could not complete the write, we may need // to resume the write source if(write_events.isSuspended) write_events.resume() return } } // Nothing left? then stop looking for write events if(!write_events.isSuspended) write_events.suspend } catch { case e:IOException => close } } def start() = { receiver.read_events.resume } def close() = { receiver.read_events.cancel sender.write_events.cancel channel.close } } } 0000775 0000000 0000000 00000000000 12274461040 0040176 5 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example/discovery EchoNetJava.java 0000664 0000000 0000000 00000034616 12274461040 0043202 0 ustar 00root root 0000000 0000000 hawtdispatch-hawtdispatch-project-1.20/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example/discovery /** * Copyright (C) 2012 FuseSource, Inc. * http://fusesource.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.hawtdispatch.example.discovery; import org.fusesource.hawtdispatch.*; import static org.fusesource.hawtdispatch.Dispatch.*; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.net.InetSocketAddress; import java.net.URI; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.ArrayList; import java.util.concurrent.TimeUnit; /** * An example of a networks of servers which advertise connection information to each other. */ public class EchoNetJava { public static void main(String[] args) throws Exception { run(); } public static void run() throws Exception { Server a = new Server(4444).start(); Server b = new Server(5555).start(); Server c = new Server(6666).start(); Thread.sleep(200); a.connect(3333); a.connect(b); b.connect(c); System.in.read(); } static class Server { final int port; final URI me; final ServerSocketChannel serverChannel; final ArrayList