-
Notifications
You must be signed in to change notification settings - Fork 361
Consider Alternate Handler Types #96
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
Comments
cc: @softprops, @sapessi. |
As a disclaimer, I am not very familiar with lambda itself. To provide some context re: Tower. Tower is not a framework, or even tied to a specific protocol. It aims to provide a standardized handler function. The goal is to avoid having each framework / lib provide its own handler function so that there is a common base upon which we can build things. For example, in the lambda runtime lib, you define: pub trait Handler<Event, Output, EventError> {
/// Method to execute the handler function
fn run(&mut self, event: Event, ctx: Context) -> Result<Output, EventError>;
} Tower defines the pub trait Service<Request> {
type Response;
type Error;
type Future: Future<Item = Self::Response, Error = Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error>;
fn call(&mut self, req: Request) -> Self::Future;
} A few thoughts: AsynchronousTower If you opted for an async handler (like tower Service), you would be able to avoid most of the overhead and run on a single thread with no synchronization. You would also be able to process requests concurrently. It also is farily trivial to bridge async -> sync by using a thread pool. In fact, this sounds like a great combinator for Tower to include. Light & StableThe The BackpressureThe Tower service trait comes with a mechanism by which to implement backpressure: the We experimented a lot with strategies by which to expose backpressure. I believe that the strategy we landed on works very well in many different situations. If you want to talk more about this, I would be happy to. Common interfaceLike I said, Tower is not a web framework, or even tied to a specific protocol. It is a common interface that can be implemented by any other web framework / client. By providing a common interface, adapters between components are no longer needed. If every library / framework provides its own Also, by defining a common interface, it becomes possible to build reusable middleware components. You can see the tower project provides a number of common components: https://github.com/tower-rs/tower. |
(Pulled from #94)
I wonder if we can support that through an optional extension for customers that do care about this. To that end, I've been talking to @carllerche—he might be able to comment on this more—about the usage of Tower in underlying of the Lambda runtime, and my current thinking is that we can provide several valid handler signatures as implemented by specialized tower services and a corresponding
Into<Service>
(for context, this is the foundational Service trait) that'll be executed by the the Lambda runtime itself. Given this definition, we can provide several specialized services along the lines of:Service<(http::Request<T>, Context)> -> http::Response<U>
Service<(http::Request<T>, Context)> -> Result<http::Response<U>, HandlerError>
Service<(aws_lambda_events::event::sqs::SqsEvent, Context)> -> U
Service<(aws_lambda_events::event::sqs::SqsEvent, Context)> -> Result<U, HandlerError>
Note: each service function signature would be implemented in terms of a sealed trait similar to
HttpService
.In the absence of a handler error, the
Into<Service>
implementation would place a default value forHandlerError
. Handler construction will still be available using a something similar to aServiceFn
.To address some potential concerns:
HttpService
behind a feature flag.The text was updated successfully, but these errors were encountered: