Ejemplo n.º 1
0
void ThriftServer::stopListening() {
  auto sockets = getSockets();
  std::atomic<size_t> remaining(1 + sockets.size());
  folly::Baton<> done;

  auto defer_wait = folly::makeGuard([&] { done.wait(); });
  auto maybe_post = [&] { --remaining ? void() : done.post(); };
  maybe_post();
  for (auto& socket : sockets) {
    // Stop accepting new connections
    auto eb = socket->getEventBase();
    eb->runInEventBaseThread(
        [socket = std::move(socket), g = folly::makeGuard(maybe_post)] {
          socket->pauseAccepting();

          // Close the listening socket
          // This will also cause the workers to stop
          socket->stopAccepting();
        });
  }

  if (stopWorkersOnStopListening_) {
    // Wait for any tasks currently running on the task queue workers to
    // finish, then stop the task queue workers. Have to do this now, so
    // there aren't tasks completing and trying to write to i/o thread
    // workers after we've stopped the i/o workers.
    threadManager_->join();
  }
}
Ejemplo n.º 2
0
bool EventBase::runInEventBaseThread(const Cob& fn) {
  // Short-circuit if we are already in our event base
  if (inRunningEventBaseThread()) {
    runInLoop(fn);
    return true;
  }

  Cob* fnCopy;
  // Allocate a copy of the function so we can pass it to the other thread
  // The other thread will delete this copy once the function has been run
  try {
    fnCopy = new Cob(fn);
  } catch (const std::bad_alloc& ex) {
    LOG(ERROR) << "failed to allocate tr::function copy "
               << "for runInEventBaseThread()";
    return false;
  }

  if (!runInEventBaseThread(&EventBase::runTr1FunctionPtr, fnCopy)) {
    delete fnCopy;
    return false;
  }

  return true;
}
Ejemplo n.º 3
0
uint32_t PooledRequestChannel::sendRequestImpl(
    RpcKind rpcKind,
    RpcOptions& options,
    std::unique_ptr<RequestCallback> cob,
    std::unique_ptr<ContextStack> ctx,
    std::unique_ptr<folly::IOBuf> buf,
    std::shared_ptr<transport::THeader> header) {
  auto executor = executor_.lock();
  if (!executor) {
    throw std::logic_error("IO executor already destroyed.");
  }
  auto evb = executor->getEventBase();

  evb->runInEventBaseThread([this,
                             keepAlive = getKeepAliveToken(evb),
                             options = std::move(options),
                             rpcKind,
                             cob = std::move(cob),
                             ctx = std::move(ctx),
                             buf = std::move(buf),
                             header = std::move(header)]() mutable {
    switch (rpcKind) {
      case RpcKind::SINGLE_REQUEST_NO_RESPONSE:
        impl(*keepAlive)
            .sendOnewayRequest(
                options,
                std::move(cob),
                std::move(ctx),
                std::move(buf),
                std::move(header));
        break;
      case RpcKind::SINGLE_REQUEST_SINGLE_RESPONSE:
        impl(*keepAlive)
            .sendRequest(
                options,
                std::move(cob),
                std::move(ctx),
                std::move(buf),
                std::move(header));
        break;
      case RpcKind::SINGLE_REQUEST_STREAMING_RESPONSE:
        impl(*keepAlive)
            .sendStreamRequest(
                options,
                std::move(cob),
                std::move(ctx),
                std::move(buf),
                std::move(header));
        break;
      default:
        folly::assume_unreachable();
        break;
    };
  });
  return 0;
}
Ejemplo n.º 4
0
void ThriftServer::updateTLSCert() {
  forEachWorker([&](wangle::Acceptor* acceptor) {
    if (!acceptor) {
      return;
    }
    auto evb = acceptor->getEventBase();
    if (!evb) {
      return;
    }
    evb->runInEventBaseThread(
        [acceptor] { acceptor->resetSSLContextConfigs(); });
  });
}
Ejemplo n.º 5
0
void AsyncLoadHandler2::async_eb_onewaySleep(
  std::unique_ptr<HandlerCallbackBase> callback,
  int64_t microseconds) {
  auto callbackp = callback.release();
  // May leak if task never finishes
  auto eb = callbackp->getEventBase();
  eb->runInEventBaseThread([=]() {
    eb->tryRunAfterDelay([=](){
      delete callbackp;
    },
    microseconds / Util::US_PER_MS);
  });
}
Ejemplo n.º 6
0
void ThriftServer::updateTicketSeeds(wangle::TLSTicketKeySeeds seeds) {
  forEachWorker([&](wangle::Acceptor* acceptor) {
    if (!acceptor) {
      return;
    }
    auto evb = acceptor->getEventBase();
    if (!evb) {
      return;
    }
    evb->runInEventBaseThread([acceptor, seeds] {
      acceptor->setTLSTicketSecrets(
          seeds.oldSeeds, seeds.currentSeeds, seeds.newSeeds);
    });
  });
}
Ejemplo n.º 7
0
void RequestChannel::sendRequestAsync(
    apache::thrift::RpcOptions& rpcOptions,
    std::unique_ptr<apache::thrift::RequestCallback> callback,
    std::unique_ptr<apache::thrift::ContextStack> ctx,
    std::unique_ptr<folly::IOBuf> buf,
    std::shared_ptr<apache::thrift::transport::THeader> header,
    RpcKind kind) {
  auto eb = getEventBase();
  if (!eb || eb->isInEventBaseThread()) {
    switch (kind) {
      case RpcKind::SINGLE_REQUEST_NO_RESPONSE:
        // Calling asyncComplete before sending because
        // sendOnewayRequest moves from ctx and clears it.
        ctx->asyncComplete();
        sendOnewayRequest(
            rpcOptions,
            std::move(callback),
            std::move(ctx),
            std::move(buf),
            std::move(header));
        break;
      case RpcKind::SINGLE_REQUEST_SINGLE_RESPONSE:
        sendRequest(
            rpcOptions,
            std::move(callback),
            std::move(ctx),
            std::move(buf),
            std::move(header));
        break;
      case RpcKind::SINGLE_REQUEST_STREAMING_RESPONSE:
        sendStreamRequest(
            rpcOptions,
            std::move(callback),
            std::move(ctx),
            std::move(buf),
            std::move(header));
        break;
      default:
        folly::assume_unreachable();
        break;
    }

  } else {
    switch (kind) {
      case RpcKind::SINGLE_REQUEST_NO_RESPONSE:
        eb->runInEventBaseThread([this,
                                  rpcOptions,
                                  callback = std::move(callback),
                                  ctx = std::move(ctx),
                                  buf = std::move(buf),
                                  header = std::move(header)]() mutable {
          // Calling asyncComplete before sending because
          // sendOnewayRequest moves from ctx and clears it.
          ctx->asyncComplete();
          sendOnewayRequest(
              rpcOptions,
              std::move(callback),
              std::move(ctx),
              std::move(buf),
              std::move(header));
        });
        break;
      case RpcKind::SINGLE_REQUEST_SINGLE_RESPONSE:
        eb->runInEventBaseThread([this,
                                  rpcOptions,
                                  callback = std::move(callback),
                                  ctx = std::move(ctx),
                                  buf = std::move(buf),
                                  header = std::move(header)]() mutable {
          sendRequest(
              rpcOptions,
              std::move(callback),
              std::move(ctx),
              std::move(buf),
              std::move(header));
        });
        break;
      case RpcKind::SINGLE_REQUEST_STREAMING_RESPONSE:
        eb->runInEventBaseThread([this,
                                  rpcOptions,
                                  callback = std::move(callback),
                                  ctx = std::move(ctx),
                                  buf = std::move(buf),
                                  header = std::move(header)]() mutable {
          sendStreamRequest(
              rpcOptions,
              std::move(callback),
              std::move(ctx),
              std::move(buf),
              std::move(header));
        });
        break;
      default:
        folly::assume_unreachable();
        break;
    }
  }
}