Commit 8405118b authored by Yicheng Wang's avatar Yicheng Wang Committed by Facebook GitHub Bot

Adding AcceptInfo into connectionAccepted of AsyncSocket callback

Summary:
AsyncServerSocket works like this:
1) a socket is accepted from the fd
2) the socket is pushed into the socket queue
3) the connectionAccepted() callback is called with the socket is dequeued

Things happening before connectionAccepted() are like black box to us currently. For example the time taken for a socket to sit in the socket queue is completely unknown. Adding this AcceptInfo into the callback could allow us to pass more information to downstream for instrumenting.

This diff only pass timestamp of before the socket is being pushed into the queue.

Reviewed By: yfeldblum

Differential Revision: D31633582

fbshipit-source-id: 66072955318388c2410b48313d3d54078edce478
parent 3e26416d
......@@ -89,7 +89,7 @@ AtomicNotificationQueueTaskStatus AsyncServerSocket::NewConnMessage::operator()(
acceptor.connectionEventCallback_->onConnectionDequeuedByAcceptorCallback(
fd, clientAddr);
}
acceptor.callback_->connectionAccepted(fd, clientAddr);
acceptor.callback_->connectionAccepted(fd, clientAddr, {timeBeforeEnqueue});
return AtomicNotificationQueueTaskStatus::CONSUMED;
}
......@@ -1066,11 +1066,13 @@ void AsyncServerSocket::dispatchSocket(
NetworkSocket socket, SocketAddress&& address) {
uint32_t startingIndex = callbackIndex_;
auto timeBeforeEnqueue = std::chrono::steady_clock::now();
// Short circuit if the callback is in the primary EventBase thread
CallbackInfo* info = nextCallback();
if (info->eventBase == nullptr || info->eventBase == this->eventBase_) {
info->callback->connectionAccepted(socket, address);
info->callback->connectionAccepted(socket, address, {timeBeforeEnqueue});
return;
}
......@@ -1079,9 +1081,10 @@ void AsyncServerSocket::dispatchSocket(
auto queueTimeout = *queueTimeout_;
std::chrono::steady_clock::time_point deadline;
if (queueTimeout.count() != 0) {
deadline = std::chrono::steady_clock::now() + queueTimeout;
deadline = timeBeforeEnqueue + queueTimeout;
}
NewConnMessage msg{socket, std::move(address), deadline};
NewConnMessage msg{socket, std::move(address), deadline, timeBeforeEnqueue};
// Loop until we find a free queue to write to
while (true) {
......
......@@ -50,6 +50,11 @@
#define SO_NO_TRANSPARENT_TLS 200
#endif
// TODO(yichengfb): remove this
// For temporarily marking the new interface of
// folly::AsyncServerSocket::AcceptCallback::connectionAccepted()
#define FOLLY_ASYNCSERVERSOCKET_ACCEPTINFO_DEFINED 1
namespace folly {
/**
......@@ -140,6 +145,10 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
class AcceptCallback {
public:
struct AcceptInfo {
std::chrono::steady_clock::time_point timeBeforeEnqueue;
};
virtual ~AcceptCallback() = default;
/**
......@@ -157,9 +166,14 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
* @param clientAddr A reference to a SocketAddress struct containing the
* client's address. This struct is only guaranteed to
* remain valid until connectionAccepted() returns.
* @param info A simple structure that contains auxiliary information
* about this accepted socket, for example, when it's
* getting pushed into the waiting queue.
*/
virtual void connectionAccepted(
NetworkSocket fd, const SocketAddress& clientAddr) noexcept = 0;
NetworkSocket fd,
const SocketAddress& clientAddr,
AcceptInfo info) noexcept = 0;
/**
* acceptError() is called if an error occurs while accepting.
......@@ -789,6 +803,7 @@ class AsyncServerSocket : public DelayedDestruction, public AsyncSocketBase {
NetworkSocket fd;
SocketAddress clientAddr;
std::chrono::steady_clock::time_point deadline;
std::chrono::steady_clock::time_point timeBeforeEnqueue;
bool isExpired() const {
return deadline.time_since_epoch().count() != 0 &&
......
......@@ -182,7 +182,8 @@ class TestAcceptCallback : public AsyncServerSocket::AcceptCallback {
void connectionAccepted(
NetworkSocket fd,
const folly::SocketAddress& clientAddr) noexcept override {
const folly::SocketAddress& clientAddr,
AcceptInfo /* info */) noexcept override {
events_.emplace_back(fd, clientAddr);
if (connectionAcceptedFn_) {
......
......@@ -63,7 +63,8 @@ class SSLServerAcceptCallbackBase : public AsyncServerSocket::AcceptCallback {
void connectionAccepted(
folly::NetworkSocket fd,
const SocketAddress& clientAddr) noexcept override {
const SocketAddress& clientAddr,
AcceptInfo /* info */) noexcept override {
if (socket_) {
socket_->detachEventBase();
}
......
......@@ -223,7 +223,8 @@ class ZeroCopyTestServer : public folly::AsyncServerSocket::AcceptCallback {
void connectionAccepted(
folly::NetworkSocket fd,
const folly::SocketAddress& /* unused */) noexcept override {
const folly::SocketAddress& /* unused */,
AcceptInfo /* info */) noexcept override {
auto client = std::make_shared<ZeroCopyTestAsyncSocket>(
nullptr, evb_, fd, numLoops_, bufferSize_, zeroCopy_);
clients_[client.get()] = client;
......
......@@ -50,7 +50,8 @@ class AcceptCallback : public folly::AsyncServerSocket::AcceptCallback {
void connectionAccepted(
folly::NetworkSocket fdNetworkSocket,
const folly::SocketAddress& clientAddr) noexcept override {
const folly::SocketAddress& clientAddr,
AcceptInfo /* info */) noexcept override {
VLOG(5) << "Connection accepted from: " << clientAddr.describe();
// unregister handlers while in the callback
socket_->pauseAccepting();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment