-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use IOThreadPoolExecutor to create Proxygen worker threads.
Summary: Make `RequestWorkerThread` no longer inherit from `WorkerThread` so it can be managed by a `folly::Executor`. Introduce `RequestWorkerThreadNoExecutor` that behaves the same way that `RequestWorkerThread` previously did. Reviewed By: dddmello, mjoras Differential Revision: D45195785 fbshipit-source-id: 45e5ff6470b5bcdbb6bcbccecb509f7942c88f10
- Loading branch information
1 parent
86a686a
commit d608c1a
Showing
7 changed files
with
258 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#include <proxygen/lib/services/RequestWorkerThreadNoExecutor.h> | ||
|
||
#include <folly/io/async/EventBaseManager.h> | ||
#include <proxygen/lib/services/ServiceWorker.h> | ||
|
||
namespace proxygen { | ||
|
||
static const uint32_t requestIdBits = 56; | ||
static const uint64_t requestIdMask = ((1ULL << requestIdBits) - 1); | ||
|
||
RequestWorkerThreadNoExecutor::RequestWorkerThreadNoExecutor( | ||
FinishCallback& callback, uint8_t threadId, const std::string& evbName) | ||
: WorkerThread(folly::EventBaseManager::get(), evbName), | ||
nextRequestId_(static_cast<uint64_t>(threadId) << requestIdBits), | ||
callback_(callback) { | ||
} | ||
|
||
RequestWorkerThreadNoExecutor::~RequestWorkerThreadNoExecutor() { | ||
// It is important to reset the underlying event base in advance of this | ||
// class' destruction as it may be that there are functions awaiting | ||
// execution that possess a reference to this class. | ||
resetEventBase(); | ||
} | ||
|
||
uint8_t RequestWorkerThreadNoExecutor::getWorkerId() const { | ||
return static_cast<uint8_t>(nextRequestId_ >> requestIdBits); | ||
} | ||
|
||
uint64_t RequestWorkerThreadNoExecutor::nextRequestId() { | ||
uint64_t requestId = getRequestWorkerThreadNoExecutor()->nextRequestId_; | ||
getRequestWorkerThreadNoExecutor()->nextRequestId_ = | ||
(requestId & ~requestIdMask) | ((requestId + 1) & requestIdMask); | ||
return requestId; | ||
} | ||
|
||
void RequestWorkerThreadNoExecutor::flushStats() { | ||
CHECK(getEventBase()->isInEventBaseThread()); | ||
for (auto& p : serviceWorkers_) { | ||
p.second->flushStats(); | ||
} | ||
} | ||
|
||
void RequestWorkerThreadNoExecutor::setup() { | ||
WorkerThread::setup(); | ||
callback_.workerStarted(this); | ||
} | ||
|
||
void RequestWorkerThreadNoExecutor::cleanup() { | ||
WorkerThread::cleanup(); | ||
callback_.workerFinished(this); | ||
} | ||
|
||
} // namespace proxygen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
#include <map> | ||
#include <proxygen/lib/services/WorkerThread.h> | ||
#include <wangle/acceptor/LoadShedConfiguration.h> | ||
|
||
namespace proxygen { | ||
|
||
class Service; | ||
class ServiceWorker; | ||
|
||
/** | ||
* RequestWorkerThreadNoExecutor extends WorkerThread, and also contains a list | ||
* of ServiceWorkers running in this thread. | ||
*/ | ||
class RequestWorkerThreadNoExecutor : public WorkerThread { | ||
public: | ||
class FinishCallback { | ||
public: | ||
virtual ~FinishCallback() noexcept = default; | ||
virtual void workerStarted(RequestWorkerThreadNoExecutor*) = 0; | ||
virtual void workerFinished(RequestWorkerThreadNoExecutor*) = 0; | ||
}; | ||
|
||
/** | ||
* Create a new RequestWorkerThreadNoExecutor. | ||
* | ||
* @param proxygen The object to notify when this worker finishes. | ||
* @param threadId A unique ID for this worker. | ||
* @param evbName The event base will ne named to this name (thread name) | ||
*/ | ||
RequestWorkerThreadNoExecutor(FinishCallback& callback, | ||
uint8_t threadId, | ||
const std::string& evbName = std::string()); | ||
|
||
/** | ||
* Reset the underlying event base prior to WorkerThread destruction. | ||
*/ | ||
~RequestWorkerThreadNoExecutor() override; | ||
|
||
/** | ||
* Return a unique 64bit identifier. | ||
*/ | ||
static uint64_t nextRequestId(); | ||
|
||
/** | ||
* Return unique 8bit worker ID. | ||
*/ | ||
[[nodiscard]] uint8_t getWorkerId() const; | ||
|
||
static RequestWorkerThreadNoExecutor* getRequestWorkerThreadNoExecutor() { | ||
auto* self = dynamic_cast<RequestWorkerThreadNoExecutor*>( | ||
WorkerThread::getCurrentWorkerThread()); | ||
CHECK_NOTNULL(self); | ||
return self; | ||
} | ||
|
||
/** | ||
* Track the ServiceWorker objects in-use by this worker. | ||
*/ | ||
void addServiceWorker(Service* service, ServiceWorker* sw) { | ||
CHECK(serviceWorkers_.find(service) == serviceWorkers_.end()); | ||
serviceWorkers_[service] = sw; | ||
} | ||
|
||
/** | ||
* For a given service, returns the ServiceWorker associated with this | ||
* RequestWorkerThreadNoExecutor | ||
*/ | ||
ServiceWorker* getServiceWorker(Service* service) const { | ||
auto it = serviceWorkers_.find(service); | ||
CHECK(it != serviceWorkers_.end()); | ||
return it->second; | ||
} | ||
|
||
/** | ||
* Get/set the worker thread's bound load shed configuration instance. | ||
* Used by derivative classes. Updates are propagated seamlessly via | ||
* the use of swapping such that threads will automatically see updated | ||
* fields on update. | ||
*/ | ||
[[nodiscard]] std::shared_ptr<const wangle::LoadShedConfiguration> | ||
getLoadShedConfig() const { | ||
return loadShedConfig_; | ||
} | ||
void setLoadShedConfig( | ||
std::shared_ptr<const wangle::LoadShedConfiguration> loadShedConfig) { | ||
loadShedConfig_.swap(loadShedConfig); | ||
} | ||
|
||
/** | ||
* Flush any thread-local stats being tracked by our ServiceWorkers. | ||
* | ||
* This must be invoked from within worker's thread. | ||
*/ | ||
void flushStats(); | ||
|
||
private: | ||
void setup() override; | ||
void cleanup() override; | ||
|
||
// The next request id within this thread. The id has its highest byte set to | ||
// the thread id, so is unique across the process. | ||
uint64_t nextRequestId_; | ||
|
||
// The ServiceWorkers executing in this worker | ||
folly::F14ValueMap<Service*, ServiceWorker*> serviceWorkers_; | ||
|
||
// Every worker instance has their own version of load shed config. | ||
// This enables every request worker thread, and derivative there of, | ||
// to both access and update this field in a thread-safe way. | ||
std::shared_ptr<const wangle::LoadShedConfiguration> loadShedConfig_{nullptr}; | ||
|
||
FinishCallback& callback_; | ||
}; | ||
|
||
} // namespace proxygen |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters