/*------------------------------------------------------------------------------------------------- _______ __ _ _______ _______ ______ ______ |_____| | \ | | |______ | \ |_____] | | | \_| | ______| |_____/ |_____] Copyright (c) 2016, antsdb.com and/or its affiliates. All rights reserved. *-xguo0<@ This program is free software: you can redistribute it and/or modify it under the terms of the GNU GNU Lesser General Public License, version 3, as published by the Free Software Foundation. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/lgpl-3.0.en.html> -------------------------------------------------------------------------------------------------*/ package com.antsdb.saltedfish.server; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.StandardSocketOptions; import java.nio.channels.AsynchronousCloseException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import com.antsdb.saltedfish.sql.Orca; import com.antsdb.saltedfish.util.UberUtil; /** * * @author *-xguo0<@ */ public class SimpleSocketServer extends TcpServer implements Runnable { static Logger _log = UberUtil.getThisLogger(); private ServerSocketChannel serverChannel; private SaltedFish fish; private ExecutorService pool = Executors.newCachedThreadPool(new MyThreadFactory()); private static class MyThreadFactory implements ThreadFactory { private final static AtomicInteger _threadNumber = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { String name = "listener-" + _threadNumber.getAndIncrement(); Thread t = new Thread(r, name); t.setDaemon(true); t.setPriority(Thread.NORM_PRIORITY); return t; } } public SimpleSocketServer(SaltedFish fish) { this.fish = fish; } @Override public void start(int port) throws IOException { this.serverChannel = ServerSocketChannel.open(); _log.info("starting simple socket listener on port: {}", port); this.serverChannel.bind(new InetSocketAddress((InetAddress)null, port)); Thread thread = new Thread(this); thread.setName("fish listener"); thread.setDaemon(true); thread.start(); } @Override public void run() { try { for (;;) { SocketChannel channel = this.serverChannel.accept(); channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true); Orca orca = this.fish.getOrca(); if (orca == null) { channel.close(); continue; } if (orca.isClosed()) { channel.close(); continue; } this.pool.execute(new SimpleSocketWorker(this.fish, channel)); } } catch (AsynchronousCloseException ignored) {} catch (Exception x) { _log.warn("", x); } } @Override public void shutdown() { try { this.serverChannel.close(); } catch (IOException ignored) {} this.pool.shutdown(); } }