async-graphql / examples

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Actix + Subscriptions

sabahtalateh opened this issue · comments

commented

Can you please provide an example of how to use Subscriptions with Actix Actors

commented

No matter what framework you use, the easiest way is to create a futures::mpsc::channel.

commented

@sunli829 i tried but it not works

// Channel type
type Chan = (
    futures::channel::mpsc::Sender<i32>,
    futures::channel::mpsc::Receiver<i32>,
);

#[actix_rt::main]
async fn main() -> Result<(), io::Error> {
    // Create channel
    let c: Chan = futures::channel::mpsc::channel(10);

    // Pass within context
    let schema = Schema::build(QueryRoot, EmptyMutation, SubscriptionRoot)
        .data(c)
        .finish();
    Ok(())
}

#[Subscription]
impl SubscriptionRoot {
    async fn stream(&self, ctx: &Context<'_>) -> impl Stream<Item = i32> {
        // trying to return receiver
        let chan: &Chan = ctx.data_unchecked::<Chan>();
        &chan.1
    }
}

i got an error

error[E0277]: the trait bound `&futures::channel::mpsc::Receiver<i32>: futures::Stream` is not satisfied
  --> source/src/main.rs:51:48
   |
51 |     async fn stream(&self, ctx: &Context<'_>) -> impl Stream<Item = i32> {
   |                                                ^^^^^^^^^^^^^^^^^^^^^^^ the trait `futures::Stream` is not implemented for `&futures::channel::mpsc::Receiver<i32>`
   |
   = help: the following implementations were found:
             <futures::channel::mpsc::Receiver<T> as futures::Stream>
   = note: `futures::Stream` is implemented for `&mut futures::channel::mpsc::Receiver<i32>`, but not for `&futures::channel::mpsc::Receiver<i32>`
   = note: the return type of a function must have a statically known size

so Stream implemented for &mut Receiver and Receiver but not &Receiver. Do i need to pass channel in some other way or get it from context in some other way or something else?

commented

You should return Receiver instead of &Receiver.

Here is an example.

https://github.com/async-graphql/examples/blob/master/models/books/src/simple_broker.rs

commented

Thanks. As i understand from the example there is no way to get Receiver from ctx: &async_graphql::context::Context as all methods of Context returns references.. And the only way to return impl Stream from async fn stream(&self, ctx: &Context<'_>) -> impl Stream<Item = i32> { is to call static Broker::subscribe().

Is it all true and my idea to somehow put receiver in context and then access it within the SubscriptionRoot was misconception?

commented

Yes, Context::data get immutable borrowing, but poll a stream needs mutable borrowing.