From d8abf544d25970c449a254986ee07456dd677625 Mon Sep 17 00:00:00 2001 From: Zhengchao Liu Date: Tue, 29 Jun 2021 17:49:25 -0700 Subject: [PATCH] add handle to publish finish event when exception thrown Summary: If the handler throws without returning a future, the finish event will not be published. This diff adds the `LiveRequest` to publish finish event in its destructor. Reviewed By: chadaustin Differential Revision: D29332452 fbshipit-source-id: 880a4b67ba47b737063a3955c9f4bdbf605f1a43 --- eden/fs/nfs/Nfsd3.cpp | 47 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/eden/fs/nfs/Nfsd3.cpp b/eden/fs/nfs/Nfsd3.cpp index 45be6a8378..58d9eb77ee 100644 --- a/eden/fs/nfs/Nfsd3.cpp +++ b/eden/fs/nfs/Nfsd3.cpp @@ -1721,6 +1721,39 @@ constexpr auto kNfs3dHandlers = [] { return handlers; }(); +namespace { +struct LiveRequest { + LiveRequest( + std::shared_ptr> traceBus, + std::atomic& traceDetailedArguments, + HandlerEntry& handlerEntry, + folly::io::Cursor& deser, + uint32_t xid, + uint32_t procNumber) + : traceBus_{std::move(traceBus)}, xid_{xid}, procNumber_{procNumber} { + if (traceDetailedArguments.load(std::memory_order_acquire)) { + traceBus_->publish(NfsTraceEvent::start( + xid, procNumber, handlerEntry.formatArgs(deser))); + } else { + traceBus_->publish(NfsTraceEvent::start(xid, procNumber)); + } + } + + LiveRequest(LiveRequest&& that) noexcept = default; + LiveRequest& operator=(LiveRequest&&) = delete; + + ~LiveRequest() { + if (traceBus_) { + traceBus_->publish(NfsTraceEvent::finish(xid_, procNumber_)); + } + } + + std::shared_ptr> traceBus_; + uint32_t xid_; + uint32_t procNumber_; +}; +} // namespace + ImmediateFuture Nfsd3ServerProcessor::dispatchRpc( folly::io::Cursor deser, folly::io::QueueAppender ser, @@ -1753,16 +1786,12 @@ ImmediateFuture Nfsd3ServerProcessor::dispatchRpc( "{}({})", handlerEntry.name, handlerEntry.formatArgs(deser)); - if (traceDetailedArguments_.load(std::memory_order_acquire)) { - traceBus_->publish( - NfsTraceEvent::start(xid, procNumber, handlerEntry.formatArgs(deser))); - } else { - traceBus_->publish(NfsTraceEvent::start(xid, procNumber)); - } + + auto liveRequest = LiveRequest{ + traceBus_, traceDetailedArguments_, handlerEntry, deser, xid, procNumber}; + return (this->*handlerEntry.handler)(std::move(deser), std::move(ser), xid) - .ensure([this, xid, procNumber]() { - traceBus_->publish(NfsTraceEvent::finish(xid, procNumber)); - }); + .ensure([liveRequest = std::move(liveRequest)]() {}); } void Nfsd3ServerProcessor::onSocketClosed() {