-
Notifications
You must be signed in to change notification settings - Fork 12
Custom RPC opts mapper #539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@@ -304,10 +304,12 @@ export class GenericHandler implements RestateHandler { | |||
attemptCompletedSignal: abortSignal, | |||
}; | |||
|
|||
const handlerComponent = handler.component(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In hindsight, this extraction is not necessary, can inline all 3 usages if preferred
Hey @mupperton, I can see how this can be useful indeed!
|
One more thought, if I'd like to use that for |
This isn't touching the serdes of the handlers, so no issues with discovery, this is about when doing an RPC call
Yeah that's fair, this could instead be done as an interceptor on
Potentially yes, although I'd imagine if you had a specific header for a specific use-case you would want to add that in-line in usages, this was meant more as a global setting, like you always use binary data in every handler, or always use your own custom JSON serde, so you don't want to overwrite the input/output serde of every RPC call/send in addition to the handler serde changes made for discovery I think possibly the interceptor style approach on genericCall/genericSend might be the way to go though instead, and hopefully a cleaner implementation - let me know if you agree |
Yes, so my use case is to send a custom tracing header between RPC call requests, so I need access to the incoming request headers, but I do this through AsyncLocalStorage (as I also need it elsewhere like in logger context, like the Discord discussion we had about traceparent) and set it at invocation start and then can access it in my equivalent custom implementation of this PR that way So I was thinking that would be another change to propose to add a invocation middleware thing to be able to wrap an invocation in AsyncLocalStorage context (as an example use-case) which then completely removes my "hacks" Maybe there is a way though to also give more "context" to the interceptor approach though, like providing the actual |
Motivation:
I want to be able to set a HTTP header on every RPC call, which I currently achieve by iterating over my handlers and wrapping them in a new function which modifies the
ctx
object to overwrite the RPC call methods and auto-inject the HTTP header into an existing ClientCallOptions object or create a new one, on each call - a bit of a hasslePossible other use cases:
I considered other approaches to this problem, such as allowing it to be set as handler metadata, which would then become a property of the HandlerWrapper class, but this didn't feel logical to belong to an individual handler, and felt more global - of course the mapper function can be coded to opt-out of default behaviour if a handler actually provides some Opts or SendOpts
Happy to hear thoughts on this, and please feel free to enhance the JSDoc on the public API if not sufficient
Happy to shorten the property names (e.g.
clientCallOptsMapper
) if too verbose, but I struggled to think of a good short name