You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm writing a fairly generic all-in-one Lambda function which will be handling many different types of events. For example, SQS, SNS, CloudWatch scheduled events, S3 events, SES events, and of course API Gateway requests/responses. I have an existing Rust Lambda doing this but it's incredibly old (from the crowbar days) so I'm essentially rewriting it from scratch.
I'm implementing tower::Service for my service directly and I'm trying to define its outputs so that I can return either a synchronous buffered response or a streaming response so I can have the flexibility of both. I'm aware that the only case that streaming is applicable is in API Gateway responses.
use bytes::Bytes;use lambda_runtime::streaming::Body;use lambda_runtime::{ErrorasLambdaError,StreamResponse};use lambda_runtime::{FunctionResponse,LambdaEvent};use std::pin::Pin;use std::sync::Arc;use tower::Service;#[derive(Clone)]pubstructLambdaService(Arc<LambdaServiceInner>);implLambdaService{pubfnnew(id:implInto<String>) -> Self{Self(Arc::new(LambdaServiceInner{id: id.into()}))}}structLambdaServiceInner{id:String,}/// Represents a response to the Lambda invocation, either a buffered response or a streaming /// response.// FIXME here is where the issue occurspubtypeLambdaResponse = FunctionResponse<Bytes,StreamResponse<Body>>;implService<LambdaEvent<serde_json::Value>>forLambdaService{typeResponse = LambdaResponse;typeError = LambdaError;typeFuture = Pin<Box<dynFuture<Output=Result<Self::Response,Self::Error>>>>;fnpoll_ready(&mutself,_cx:&mut std::task::Context<'_>) -> std::task::Poll<Result<(),Self::Error>>{
std::task::Poll::Ready(Ok(()))}fncall(&mutself,req:LambdaEvent<serde_json::Value>) -> Self::Future{let cloned = self.clone();Box::pin(asyncmove{
cloned.on_event(req).await})}}implLambdaService{pubasyncfnon_event(&self,event:LambdaEvent<serde_json::Value>) -> Result<LambdaResponse,LambdaError>{eprintln!("service id: {}; request_id: {}",self.0.id, event.context.request_id);let output = serde_json::json!({"context": event.context,"event": event.payload,});eprintln!("event: {}", serde_json::to_string_pretty(&output).unwrap());Ok(FunctionResponse::BufferedResponse(Vec::with_capacity(0).into()))}}
My main function simply instantiates the service and calls lambda_runtime::run with it:
use api_lambda::LambdaService;use lambda_runtime::ErrorasLambdaError;#[tokio::main]asyncfnmain() -> Result<(),LambdaError>{
lambda_runtime::run(LambdaService::new("my-id")).await}
When I try to compile this:
error[E0277]: the trait bound `Response<Body>: futures_core::stream::Stream` is not satisfied
--> crates/api-lambda/src/main.rs:6:70
|
6 | lambda_runtime::run(LambdaService::new("my-id")).await
| ^^^^^ the trait `futures_core::stream::Stream` is not implemented for `Response<Body>`
|
= help: the following other types implement trait `futures_core::stream::Stream`:
&mut S
AssertUnwindSafe<S>
Body
Box<S>
CallAll<Svc, S>
CallAllUnordered<Svc, S>
Pin<P>
async_stream::async_stream::AsyncStream<T, U>
and 111 others
note: required by a bound in `run`
--> /path/to/dir/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lambda_runtime-0.13.0/src/lib.rs:119:8
|
111 | pub async fn run<A, F, R, B, S, D, E>(handler: F) -> Result<(), Error>
| --- required by a bound in this function
...
119 | S: Stream<Item = Result<D, E>> + Unpin + Send + 'static,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `run`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `api-lambda` (bin "api-lambda") due to 2 previous errors
I think I've narrowed it down: it's lambda_runtime::streaming::Response that does not implement Stream, and this violates the type constraints.
Am I correct in this reading of it?
I'm not sure how to write a Stream implementation for StreamResponse because it contains a lambda_runtime::MetadataPrelude that might need to be written first.
I'm writing a fairly generic all-in-one Lambda function which will be handling many different types of events. For example, SQS, SNS, CloudWatch scheduled events, S3 events, SES events, and of course API Gateway requests/responses. I have an existing Rust Lambda doing this but it's incredibly old (from the
crowbar
days) so I'm essentially rewriting it from scratch.I'm implementing
tower::Service
for my service directly and I'm trying to define its outputs so that I can return either a synchronous buffered response or a streaming response so I can have the flexibility of both. I'm aware that the only case that streaming is applicable is in API Gateway responses.My main function simply instantiates the service and calls
lambda_runtime::run
with it:When I try to compile this:
Note my type alias definition for the response:
I've tried a number of different values for
StreamResponse<S>
:lambda_runtime::streaming::Body
axum::body::Body
axum::body::BodyDataStream
All of these fail indicating:
The issue is that it appears that for all of the above types,
Stream
is implemented, so I'm a bit confused as to why this is happening.I'm happy to contribute an example showing a generic return over both outcomes if I can get some help wrangling the types.
The text was updated successfully, but these errors were encountered: