void LibEventServerWithTakeover::stop() {
  if (m_delete_handle != nullptr) {
    afdt_close_server(m_delete_handle);
  }
  m_accept_sock = -1;
  LibEventServer::stop();
}
예제 #2
0
int TakeoverAgent::afdtRequest(String request, String* response) {
#ifdef _MSC_VER
  return -1;
#else
  Logger::Info("takeover: received request");
  if (request == s_ver_C_FD_REQ) {
    Logger::Info("takeover: request is a listen socket request");
    *response = P_VERSION C_FD_RESP;
    m_takeover_state = TakeoverState::Started;
    m_callback->onTakeoverRequest(RequestType::LISTEN_SOCKET);
    return m_sock;
  } else if (request == s_ver_C_TERM_REQ) {
    Logger::Info("takeover: request is a terminate request");
    // It is a little bit of a hack to use an AFDT request/response
    // to shut down our accept socket, but it has to be done from
    // within the main libevent thread.
    int ret;
    *response = P_VERSION C_TERM_BAD;
    if (m_callback->onTakeoverRequest(RequestType::TERMINATE) != 0) {
      return -1;
    }
    ret = afdt_close_server(m_delete_handle);
    if (ret < 0) {
      Logger::Error("Unable to close afdt server");
      return -1;
    }
    m_delete_handle = nullptr;
    m_takeover_state = TakeoverState::Complete;

    *response = P_VERSION C_TERM_OK;
    Logger::Info("takeover: notifying all listeners");
    for (auto listener : m_takeover_listeners) {
      listener->takeoverShutdown();
    }
    Logger::Info("takeover: notification complete");
    return -1;
  } else {
    Logger::Error("takeover: request is unrecognized");
    *response = P_VERSION C_UNKNOWN;
    return -1;
  }
#endif
}
예제 #3
0
void TakeoverAgent::stop() {
#ifndef _MSC_VER
  if (m_delete_handle != nullptr) {
    afdt_close_server(m_delete_handle);
  }

  // If we're doing takeover, we don't want to gracefully close the
  // socket. If the takeover was fully completed the socket should
  // already be closed. On the other hand if the takeover was started,
  // we don't want to call shutdown because the new server might be
  // listening on that socket and we would cause it to never work. To
  // be safe we close the socket so that if nobody else is listening
  // the OS starts rejecting requests but if somebody is listening we
  // let them receive the requests.
  if (m_takeover_state != TakeoverState::NotStarted) {
    m_callback->takeoverAborted();
  }
#endif
}
void LibEventServerWithTakeover::stop() {
  if (m_delete_handle != nullptr) {
    afdt_close_server(m_delete_handle);
  }

  // If we're doing takeover, we don't want to gracefully close the
  // socket. If the takeover was fully completed the socket should
  // already be closed. On the other hand if the takeover was started,
  // we don't want to call shutdown because the new server might be
  // listening on that socket and we would cause it to never work. To
  // be safe we close the socket so that if nobody else is listening
  // the OS starts rejecting requests but if somebody is listening we
  // let them receive the requests.
  if (m_takeover_state != TakeoverState::NotStarted &&
      m_accept_sock != -1) {
    close(m_accept_sock);
    m_accept_sock = -1;
  }

  LibEventServer::stop();
}
int LibEventServerWithTakeover::afdtRequest(String request, String* response) {
  Logger::Info("takeover: received request");
  if (request == P_VERSION C_FD_REQ) {
    Logger::Info("takeover: request is a listen socket request");
    int ret;
    *response = P_VERSION C_FD_RESP;
    // Make evhttp forget our copy of the accept socket so we don't accept any
    // more connections and drop them.  Keep the socket open until we get the
    // shutdown request so that we can still serve AFDT requests (if the new
    // server crashes or something).  The downside is that it will take the LB
    // longer to figure out that we are broken.
    ret = evhttp_del_accept_socket(m_server, m_accept_sock);
    if (ret < 0) {
      // This will fail if we get a second AFDT request, but the spurious
      // log message is not too harmful.
      Logger::Error("Unable to delete accept socket");
    }
    m_takeover_state = TakeoverState::Started;
    return m_accept_sock;
  } else if (request == P_VERSION C_TERM_REQ) {
    Logger::Info("takeover: request is a terminate request");
    // It is a little bit of a hack to use an AFDT request/response
    // to shut down our accept socket, but it has to be done from
    // within the main libevent thread.
    int ret;
    *response = P_VERSION C_TERM_BAD;
    ret = close(m_accept_sock);
    if (ret < 0) {
      Logger::Error("Unable to close accept socket");
      return -1;
    }
    m_accept_sock = -1;

    // Close SSL server
    if (m_server_ssl) {
      assert(m_accept_sock_ssl > 0);
      ret = evhttp_del_accept_socket(m_server_ssl, m_accept_sock_ssl);
      if (ret < 0) {
        Logger::Error("Unable to delete accept socket for SSL in evhttp");
        return -1;
      }
      ret = close(m_accept_sock_ssl);
      if (ret < 0) {
        Logger::Error("Unable to close accept socket for SSL");
        return -1;
      }
    }

    ret = afdt_close_server(m_delete_handle);
    if (ret < 0) {
      Logger::Error("Unable to close afdt server");
      return -1;
    }
    m_delete_handle = nullptr;
    m_takeover_state = TakeoverState::Complete;

    *response = P_VERSION C_TERM_OK;
    Logger::Info("takeover: notifying all listeners");
    for (std::set<TakeoverListener*>::iterator it =
           m_takeover_listeners.begin();
         it != m_takeover_listeners.end(); ++it) {
      (*it)->takeoverShutdown(this);
    }
    Logger::Info("takeover: notification complete");
    return -1;
  } else {
    Logger::Info("takeover: request is unrecognize");
    *response = P_VERSION C_UNKNOWN;
    return -1;
  }
}