package com.xxl.job.core.rpc.netcom.jetty.server;

import com.xxl.job.core.registry.RegistHelper;
import com.xxl.job.core.thread.ExecutorRegistryThread;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.util.thread.ExecutorThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * rpc jetty server
 * @author xuxueli 2015-11-19 22:29:03
 */
public class JettyServer {
	private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);

	private Server server;
	private Thread thread;
	public void start(final int port, final String ip, final String appName, final RegistHelper registHelper) throws Exception {
		thread = new Thread(new Runnable() {
			@Override
			public void run() {
				server = new Server();
				server.setThreadPool(new ExecutorThreadPool(200, 200, 30000));	// 非阻塞
				
				// connector
				SelectChannelConnector connector = new SelectChannelConnector();
				connector.setPort(port);
				connector.setMaxIdleTime(30000);
				server.setConnectors(new Connector[] { connector });
				
				// handler
				HandlerCollection handlerc =new HandlerCollection();  
				handlerc.setHandlers(new Handler[]{new JettyServerHandler()});
				server.setHandler(handlerc);

				try {
					server.start();
					logger.info(">>>>>>>>>>>> xxl-job jetty server start success at port:{}.", port);
					ExecutorRegistryThread.getInstance().start(port, ip, appName, registHelper);
					server.join();	// block until thread stopped
					logger.info(">>>>>>>>>>> xxl-rpc server start success, netcon={}, port={}", JettyServer.class.getName(), port);
				} catch (Exception e) {
					logger.error("", e);
				} finally {
					server.destroy();
				}
			}
		});
		thread.setDaemon(true);	// daemon, service jvm, user thread leave >>> daemon leave >>> jvm leave
		thread.start();
	}

	public void destroy() {
		if (server != null) {
			try {
				server.destroy();
			} catch (Exception e) {
				logger.error("", e);
			}
		}
		if (thread.isAlive()) {
			thread.interrupt();
		}
		logger.info(">>>>>>>>>>> xxl-rpc server destroy success, netcon={}", JettyServer.class.getName());
	}

}
