/** {@inheritDoc} */ public void doReady() { channelService = txnProxy.getService(ChannelServiceImpl.class); acceptFuture = acceptor.accept(new AcceptorListener()); try { if (logger.isLoggable(Level.CONFIG)) { logger.log(Level.CONFIG, "listening on {0}", acceptor.getLocalAddress()); } } catch (IOException ioe) { throw new RuntimeException(ioe.getMessage(), ioe); } }
/** {@inheritDoc} */ public void doShutdown() { final IoFuture<?, ?> future = acceptFuture; acceptFuture = null; if (future != null) { future.cancel(true); } if (acceptor != null) { try { acceptor.close(); } catch (IOException e) { logger.logThrow(Level.FINEST, e, "closing acceptor throws"); // swallow exception } } if (asyncChannelGroup != null) { asyncChannelGroup.shutdown(); boolean groupShutdownCompleted = false; try { groupShutdownCompleted = asyncChannelGroup.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException e) { logger.logThrow(Level.FINEST, e, "shutdown acceptor interrupted"); Thread.currentThread().interrupt(); } if (!groupShutdownCompleted) { logger.log(Level.WARNING, "forcing async group shutdown"); try { asyncChannelGroup.shutdownNow(); } catch (IOException e) { logger.logThrow(Level.FINEST, e, "shutdown acceptor throws"); // swallow exception } } } logger.log(Level.FINEST, "acceptor shutdown"); if (exporter != null) { try { exporter.unexport(); logger.log(Level.FINEST, "client session server unexported"); } catch (RuntimeException e) { logger.logThrow(Level.FINEST, e, "unexport server throws"); // swallow exception } } for (ClientSessionHandler handler : handlers.values()) { handler.shutdown(); } handlers.clear(); flushContextsThread.interrupt(); }
/** * Returns the port this service is listening on for incoming client session connections. * * @return the port this service is listening on * @throws IOException if an IO problem occurs */ public int getListenPort() throws IOException { return ((InetSocketAddress) acceptor.getLocalAddress()).getPort(); }
/** * Constructs an instance of this class with the specified properties. * * @param properties service properties * @param systemRegistry system registry * @param txnProxy transaction proxy * @throws Exception if a problem occurs when creating the service */ public ClientSessionServiceImpl( Properties properties, ComponentRegistry systemRegistry, TransactionProxy txnProxy) throws Exception { super(properties, systemRegistry, txnProxy, logger); logger.log(Level.CONFIG, "Creating ClientSessionServiceImpl properties:{0}", properties); PropertiesWrapper wrappedProps = new PropertiesWrapper(properties); try { appPort = wrappedProps.getRequiredIntProperty(StandardProperties.APP_PORT, 1, 65535); /* * Get the property for controlling session event processing. */ eventsPerTxn = wrappedProps.getIntProperty( EVENTS_PER_TXN_PROPERTY, DEFAULT_EVENTS_PER_TXN, 1, Integer.MAX_VALUE); readBufferSize = wrappedProps.getIntProperty( READ_BUFFER_SIZE_PROPERTY, DEFAULT_READ_BUFFER_SIZE, 8192, Integer.MAX_VALUE); writeBufferSize = wrappedProps.getIntProperty( WRITE_BUFFER_SIZE_PROPERTY, DEFAULT_WRITE_BUFFER_SIZE, 8192, Integer.MAX_VALUE); /* * Export the ClientSessionServer. */ int serverPort = wrappedProps.getIntProperty(SERVER_PORT_PROPERTY, DEFAULT_SERVER_PORT, 0, 65535); serverImpl = new SessionServerImpl(); exporter = new Exporter<ClientSessionServer>(ClientSessionServer.class); try { int port = exporter.export(serverImpl, serverPort); serverProxy = exporter.getProxy(); if (logger.isLoggable(Level.CONFIG)) { logger.log(Level.CONFIG, "export successful. port:{0,number,#}", port); } } catch (Exception e) { try { exporter.unexport(); } catch (RuntimeException re) { } throw e; } /* * Get services and initialize service-related and other * instance fields. */ identityManager = systemRegistry.getComponent(IdentityCoordinator.class); flushContextsThread.start(); contextFactory = new ContextFactory(txnProxy); watchdogService = txnProxy.getService(WatchdogService.class); nodeMapService = txnProxy.getService(NodeMappingService.class); taskService = txnProxy.getService(TaskService.class); localNodeId = watchdogService.getLocalNodeId(); watchdogService.addRecoveryListener(new ClientSessionServiceRecoveryListener()); int acceptorBacklog = wrappedProps.getIntProperty(ACCEPTOR_BACKLOG_PROPERTY, DEFAULT_ACCEPTOR_BACKLOG); /* * Check service version. */ transactionScheduler.runTask( new AbstractKernelRunnable() { public void run() { checkServiceVersion(VERSION_KEY, MAJOR_VERSION, MINOR_VERSION); } }, taskOwner); /* * Store the ClientSessionServer proxy in the data store. */ transactionScheduler.runTask( new AbstractKernelRunnable() { public void run() { dataService.setServiceBinding( getClientSessionServerKey(localNodeId), new ManagedSerializable<ClientSessionServer>(serverProxy)); } }, taskOwner); /* * Listen for incoming client connections. */ InetSocketAddress listenAddress = new InetSocketAddress(appPort); AsynchronousChannelProvider provider = // TODO fetch from config AsynchronousChannelProvider.provider(); asyncChannelGroup = // TODO fetch from config provider.openAsynchronousChannelGroup(Executors.newCachedThreadPool()); acceptor = provider.openAsynchronousServerSocketChannel(asyncChannelGroup); try { acceptor.bind(listenAddress, acceptorBacklog); if (logger.isLoggable(Level.CONFIG)) { logger.log(Level.CONFIG, "bound to port:{0,number,#}", getListenPort()); } } catch (Exception e) { logger.logThrow(Level.WARNING, e, "acceptor failed to listen on {0}", listenAddress); try { acceptor.close(); } catch (IOException ioe) { logger.logThrow(Level.WARNING, ioe, "problem closing acceptor"); } throw e; } // TBD: listen for UNRELIABLE connections as well? } catch (Exception e) { if (logger.isLoggable(Level.CONFIG)) { logger.logThrow(Level.CONFIG, e, "Failed to create ClientSessionServiceImpl"); } doShutdown(); throw e; } }