content: /*
   * Copyright (C) 2016-2023 ActionTech.
   * based on code by MyCATCopyrightHolder Copyright (c) 2013, OpenCloudDB/MyCAT.
   * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher.
   */
  package com.actiontech.dble.net.impl.aio;
  
  import com.actiontech.dble.DbleServer;
  import com.actiontech.dble.net.IOProcessor;
  import com.actiontech.dble.net.SocketConnector;
  import com.actiontech.dble.net.connection.AbstractConnection;
  import com.actiontech.dble.net.service.AbstractService;
  import com.actiontech.dble.net.service.AuthService;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import java.net.InetSocketAddress;
  import java.nio.channels.AsynchronousSocketChannel;
  import java.nio.channels.CompletionHandler;
  import java.util.concurrent.atomic.AtomicLong;
  
  /**
   * @author mycat
   */
  public final class AIOConnector implements SocketConnector,
          CompletionHandler<Void, AbstractService> {
      private static final Logger LOGGER = LoggerFactory.getLogger(AIOConnector.class);
      private static final ConnectIdGenerator ID_GENERATOR = new ConnectIdGenerator();
  
      public AIOConnector() {
  
      }
  
      @Override
      public void completed(Void result, AbstractService attachment) {
          finishConnect(attachment);
      }
  
      @Override
      public void failed(Throwable exc, AbstractService service) {
          service.getConnection().onConnectFailed(exc);
      }
  
      private void finishConnect(AbstractService service) {
          try {
              if (service.getConnection().finishConnect()) {
                  service.getConnection().setId(ID_GENERATOR.getId());
                  IOProcessor processor = DbleServer.getInstance().nextBackendProcessor();
                  service.getConnection().setProcessor(processor);
                  if (service instanceof AuthService) {
                      ((AuthService) service).register();
                  }
              }
          } catch (Exception e) {
              LOGGER.info("connect err ", e);
              service.getConnection().close(e.toString());
          }
      }
  
      @Override
      public void start() {
  
      }
  
      @Override
      public void postConnect(AbstractConnection c) {
          ((AsynchronousSocketChannel) c.getChannel()).connect(new InetSocketAddress(c.getHost(), c.getPort()), c.getService(), this);
      }
  
      /**
       * @author mycat
       */
      private static class ConnectIdGenerator {
  
          private AtomicLong connectId = new AtomicLong(0);
  
          private long getId() {
              return connectId.incrementAndGet();
          }
      }
  }
  