refactor: Extract helpers to eliminate duplicated HTTP handler boilerplate in TaskResource#27224
Merged
amitkdutta merged 1 commit intoprestodb:masterfrom Feb 27, 2026
Merged
Conversation
Contributor
Reviewer's GuideRefactors TaskResource HTTP handlers by extracting shared helper utilities for Thrift/JSON response handling and asynchronous "fire-and-forget" operations, thereby reducing duplicated boilerplate while preserving existing behavior. Sequence diagram for executeAndRespond-based HTTP handlerssequenceDiagram
actor Client
participant HttpServer
participant TaskResource
participant CallbackRequestHandler
participant Executor
participant EventBase
participant TaskManager
participant ResponseHandler
Client->>HttpServer: HTTP request to abortResults / acknowledgeResults / removeRemoteSource
HttpServer->>TaskResource: route to handler method
TaskResource->>TaskResource: executeAndRespond(httpSrvCpuExecutor_, workFn)
TaskResource-->>HttpServer: CallbackRequestHandler
Client->>CallbackRequestHandler: HTTP request handling callback
CallbackRequestHandler->>Executor: folly::via(executor, workFn)
Executor->>TaskManager: workFn (e.g. abortResults / acknowledgeResults / removeRemoteSource)
TaskManager-->>Executor: workFn completed
Executor->>EventBase: via(EventBase keepAlive)
EventBase->>CallbackRequestHandler: thenValue
CallbackRequestHandler->>CallbackRequestHandler: check handlerState.requestExpired()
alt not expired
CallbackRequestHandler->>ResponseHandler: http::sendOkResponse
else expired
CallbackRequestHandler-->>ResponseHandler: no response
end
Executor->>CallbackRequestHandler: thenError(std::exception)
CallbackRequestHandler->>CallbackRequestHandler: check handlerState.requestExpired()
alt not expired
CallbackRequestHandler->>ResponseHandler: http::sendErrorResponse(e.what())
else expired
CallbackRequestHandler-->>ResponseHandler: no response
end
Class diagram for TaskResource and extracted HTTP helper utilitiesclassDiagram
class TaskResource {
- taskManager_ : TaskManager
- httpSrvCpuExecutor_ : folly_Executor
+ registerUris(server : HttpServer) : void
+ abortResults(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ acknowledgeResults(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ removeRemoteSource(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ createOrUpdateTaskImpl(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ deleteTask(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ getTaskStatus(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
+ getTaskInfo(message : HTTPMessage, pathMatch : vector_string) : RequestHandler*
}
class TaskManager {
+ abortResults(taskId : TaskId, destination : long) : void
+ acknowledgeResults(taskId : TaskId, bufferId : long, token : long) : void
+ removeRemoteSource(taskId : TaskId, remoteId : string) : void
+ deleteTask(taskId : TaskId, abort : bool, summarize : bool) : unique_ptr_TaskInfo
+ updateOrCreateTask(...) : unique_ptr_TaskInfo
+ getTaskStatus(...) : unique_ptr_TaskStatus
+ getTaskInfo(...) : unique_ptr_TaskInfo
}
class TaskResourceHelpers {
+ shouldUseThrift(message : HTTPMessage) : bool
+ sendPrestoResponse_T_ThriftT(downstream : ResponseHandler*, data : T, sendThrift : bool) : void
+ executeAndRespond_WorkFn(executor : folly_Executor*, workFn : WorkFn) : RequestHandler*
}
class http_CallbackRequestHandler {
+ http_CallbackRequestHandler(callback : function)
+ onRequest(message : HTTPMessage*) : void
+ onBody(body : IOBuf) : void
+ onEOM() : void
}
class ResponseHandler {
+ sendHeaders(...) : void
+ sendBody(...) : void
+ sendEOM() : void
}
class folly_Executor {
+ add(func : function) : void
}
TaskResource --> TaskManager : uses
TaskResource --> TaskResourceHelpers : uses
TaskResource --> http_CallbackRequestHandler : creates
TaskResourceHelpers --> http_CallbackRequestHandler : returns
http_CallbackRequestHandler --> ResponseHandler : writes responses
TaskResourceHelpers --> folly_Executor : schedules work
TaskResourceHelpers --> ResponseHandler : sendPrestoResponse
TaskManager <.. TaskResourceHelpers : workFn calls methods on
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Contributor
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
executeAndRespondhelper assumes a voidWorkFn(per comment) but doesn’t enforce it; consider constraining the template (e.g., viastatic_assert(std::is_void_v<std::invoke_result_t<WorkFn>>)or a concept) to avoid accidentally ignoring non-void return values in future uses. - In
executeAndRespond, you moveworkintofolly::viafrom a lambda capture; if this handler is ever reused or copied in unexpected ways, this double-move pattern could be fragile—consider wrapping the work in a smallstd::function<void()>orfolly::Functo make the ownership semantics clearer. - The new
sendPrestoResponsehelper duplicates thesendThriftboolean decision at each call site; you might consider an overload that takes theHTTPMessageand internally callsshouldUseThriftto further reduce boilerplate and keep the negotiation logic centralized.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `executeAndRespond` helper assumes a void `WorkFn` (per comment) but doesn’t enforce it; consider constraining the template (e.g., via `static_assert(std::is_void_v<std::invoke_result_t<WorkFn>>)` or a concept) to avoid accidentally ignoring non-void return values in future uses.
- In `executeAndRespond`, you move `work` into `folly::via` from a lambda capture; if this handler is ever reused or copied in unexpected ways, this double-move pattern could be fragile—consider wrapping the work in a small `std::function<void()>` or `folly::Func` to make the ownership semantics clearer.
- The new `sendPrestoResponse` helper duplicates the `sendThrift` boolean decision at each call site; you might consider an overload that takes the `HTTPMessage` and internally calls `shouldUseThrift` to further reduce boilerplate and keep the negotiation logic centralized.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
…late in TaskResource (prestodb#27224) Summary: TaskResource.cpp had significant code duplication across its 9 HTTP handler methods. This extracts three helpers to reduce boilerplate: 1. `executeAndRespond()` - Template that creates a CallbackRequestHandler wrapping the full folly::via -> thenValue -> thenError pipeline for simple fire-and-forget handlers. Used by abortResults, acknowledgeResults, and removeRemoteSource, reducing each from ~30 lines to ~5 lines. 2. `sendPrestoResponse<T, ThriftT>()` - Consolidates the Thrift/JSON content negotiation dispatch pattern that was copy-pasted in 4 handlers (createOrUpdateTaskImpl, deleteTask, getTaskStatus, getTaskInfo). 3. `shouldUseThrift()` - Extracts the repeated Accept header check for Thrift content type, used in those same 4 handlers. Net reduction of 60 lines (76 insertions, 136 deletions) with no behavioral changes. Differential Revision: D94577167
8959348 to
4033cef
Compare
This was referenced Mar 31, 2026
15 tasks
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
TaskResource.cpp had significant code duplication across its 9 HTTP handler
methods. This extracts three helpers to reduce boilerplate:
executeAndRespond()- Template that creates a CallbackRequestHandlerwrapping the full folly::via -> thenValue -> thenError pipeline for simple
fire-and-forget handlers. Used by abortResults, acknowledgeResults, and
removeRemoteSource, reducing each from ~30 lines to ~5 lines.
sendPrestoResponse<T, ThriftT>()- Consolidates the Thrift/JSON contentnegotiation dispatch pattern that was copy-pasted in 4 handlers
(createOrUpdateTaskImpl, deleteTask, getTaskStatus, getTaskInfo).
shouldUseThrift()- Extracts the repeated Accept header check for Thriftcontent type, used in those same 4 handlers.
Net reduction of 60 lines (76 insertions, 136 deletions) with no behavioral
changes.
Summary by Sourcery
Refactor TaskResource HTTP handlers to remove duplicated response and handler boilerplate while preserving existing behavior.
Enhancements: