RFC: Handler trait #644
Replies: 7 comments 15 replies
-
You can use any struct that implements the Tower's Service trait. This trait is fairly well known because it's used by frameworks in the ecosystem like Axum. Do we need our own trait? I think this capability is not documented at all, but maybe it'd be enough to have more documentation about it. I've only been able to find an example of this in the repo, so maybe we should have more information about it: I do want to acknoledge that Tower's Service trait is not the easiest to implement, but there are many examples online. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
One downside of Tower's |
Beta Was this translation helpful? Give feedback.
-
Why is it not good enough to use a closure for passing dependencies as it is right now? |
Beta Was this translation helpful? Give feedback.
-
@greenwoodcm Are you trying to add a way to define non-async way to using runtime? Currently we can't use async functions in traits on stable channel AFAIK, so in your example we are throwing out the async functionality. Or did you want to start tokio inside |
Beta Was this translation helpful? Give feedback.
-
To add my 2 cents to this discussion as someone very new to Rust, coming from the .NET world. I like the proposed implementation, as it feels much more familiar with the way functions are defined in other compiled languages. It wasn't a heavy lift to rethink how I build Lambdas from .NET to Rust, as you have to do similar things when building native binaries with .NET. But @greenwoodcm proposed programming model would definitely have eased my adoption. |
Beta Was this translation helpful? Give feedback.
-
I think we need to go back to the problem that we're trying to solve here. I think this is a good gist for it:
That's a valid concern. I've answered that question a few times, and we have evidence in this repo that it's not intuitive for people: What's interesting for me about those discussions is that as soon as you explain it, people don't seem to have any problem understanding how to do it and following the pattern. To me, this tells me that the current semantics are not complicated per-se, they are hard to find. If you look at the readme, there is no information about it at all. The new AWS docs mention this, but they were just published a few days ago. Before jumping into a new mechanism to initialize functions, we should improve how people discover those kinds of features. Adding more docs, or addressing these kinds of questions in the existent ones right away, requires very low effort, and it can yield in a high reward for our users. The same applies to the Tower integration. The two examples of Axum integrations are very interesting, but nobody knows that you can use anything that implements Service as a Lambda function, because it's documented nowhere. Making more visible that you can use the full possibilities that Tower offers, can offer interesting possibilities for our users. Writing those docs requires very low effort. Going back to @beard-programmer's question. Are the current mechanisms not good enough? Before adding a new one, maybe we should look at whether the way people learn about the current features is good enough first. |
Beta Was this translation helpful? Give feedback.
-
Background
The Java runtime allows the developer to provide the handler method as either a static method on a class (loosely akin to a Rust module
fn
) or as a member function on a class (loosely akin to a Rust structfn handler(&mut self)
). In the latter case, the Java runtime will execute the class no-arg constructor to get an instance of the object during the initialization phase, and then use that object through the lifetime of the execution environment. This makes it fairly ergonomic to implement state sharing across invocations - one declares fields on the object and then populates those objects in the constructor.The Rust runtime only allows the former, providing the handler as a static (non-struct)
fn
. State sharing is then implemented either as global static state or by using amove
to build a closure to do it (example).Proposal
Support a struct-style programming model. This would be supported in addition to the existing
fn
model. This would allow for more ergonomic sharing of state like SDK clients or open file descriptors across invocations. A sketch programming model is provided below to illustrate the high-level proposal, though I think a full implementation of this would probably be more complicated because it would need to expose error types and deal with async stuff.Prototype
Playground link
Beta Was this translation helpful? Give feedback.
All reactions