Skip to content
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

Mixing buffered and streaming responses #805

Closed
GabrielBianconi opened this issue Feb 1, 2024 · 3 comments
Closed

Mixing buffered and streaming responses #805

GabrielBianconi opened this issue Feb 1, 2024 · 3 comments

Comments

@GabrielBianconi
Copy link

I'm trying to build a Lambda with routes for both streaming (Axum SSE) and regular (buffered) handlers.

I've tried using run_with_streaming_response, which works as expected for the streaming handlers but sends an empty response for regular handlers.

With run, the regular handler works as expected but it also buffers the streaming handler before responding.

Here's a minimal example:

use axum::{
    response::{
        sse::{Event, Sse},
        IntoResponse,
    },
    routing::get,
    Router,
};
use futures::stream::{self, Stream};
use std::{convert::Infallible, time::Duration};
use tokio_stream::StreamExt as _;

async fn regular_handler() -> impl IntoResponse {
    "Buffered hello world!"
}

async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
    let stream = stream::repeat_with(|| Event::default().data("Streamed hello world!"))
        .map(Ok)
        .throttle(Duration::from_secs(1))
        .take(5);

    Sse::new(stream).keep_alive(
        axum::response::sse::KeepAlive::new()
            .interval(Duration::from_secs(1))
            .text("keep-alive-text"),
    )
}

#[tokio::main]
async fn main() -> Result<(), lambda_http::Error> {
    let app = Router::new()
        .route("/a", get(regular_handler))
        .route("/b", get(sse_handler));

    // lambda_http::run(app).await // --> /a works fine, but also buffers /b before responding

    lambda_http::run_with_streaming_response(app).await // --> /a returns an empty reply from server, /b streams as expected
}

Is there a way to set up a Lambda that accepts both types of handlers?

Thank you.

@bnusunny
Copy link
Contributor

bnusunny commented Feb 1, 2024

Lambda response streaming is decided by the invoke mode of function URLs. When you configure a function URL to response streaming, all the invokes are streamed. It is not possible to switch between buffered and streamed responses per invoke, unless you build a custom frontend to invoke the lambda function using Lambda API directly.

@GabrielBianconi
Copy link
Author

Makes sense, thank you.

Copy link

github-actions bot commented Feb 1, 2024

This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants