Adding `unsafe impl Send for durian_capnp::provider::Client {}` is going to
cause undefined behavior, because `Client` objects make use of
`Rc<RefCell<T>>` behind the scenes. So I'm not surprised that you see
panics when you do that.

Did you try using `tokio::task::spawn_local()` instead of
`tokio::task::spawn()`? Your previous usage of
`futures::executor::LocalPool` stalled the tokio event loop, but
`tokio::task::spawn_local()` should be fine.

On Tue, May 19, 2020 at 9:42 AM Mostafa Sedaghat joo <
mostafa.sedag...@gmail.com> wrote:

> Hi David
>
> Hope you are well and in good health.
>
> Finally I could find a solution for my problem. I would like to share it
> with you. I should not use `spawn_local` because it blocks main event loop.
> [image: durian_flows.jpg]
> The execution needs to get some information from the client and therefore
> it blocked the current event loop.
> I solved it by using `spawn` and running the execution inside another
> thread (OS thread).
>
> Here is the solution I could find:
> let (tx, mut rx) = oneshot::channel(); tokio::task::spawn(async move {
> // execution happens here...
> tx.send("hooray, it executed ").unwrap();
> }); // promise backs to main loop
> Promise::from_future(async move {
> loop {
> rx.try_recv();
> //tokio::task::yield_now().await;
> tokio::time::delay_for(std::time::Duration::from_millis(10 as u64)).await;
> }
> Ok(())
> })
>
> There are two things I would like to share with you:
> 1- To use `spawn` method, it is needed to enable `Send` marker for client:
> unsafe impl Send for durian_capnp::provider::Client {}
> 2- If I use `tokio::yield_now` sometimes there is a panic at
> "capnp-rpc::rpc":
> https://github.com/capnproto/capnproto-rust/blob/b89c092090fc915c410ab27c239ef10f3ea4f1ea/capnp-rpc/src/rpc.rs#L1985
>
> Do you think these are related? Do you think this way of using Capnp is
> feasible?
>
> You can check the pcap file here:
> https://github.com/b00f/durian/blob/capnp/durian-server/durian.capnp
> Server implementation:
> https://github.com/b00f/durian/tree/capnp/durian-server
> Client implementation:
> https://github.com/b00f/durian/tree/capnp/run/durian-client
>
> I know you might be very busy but I really appreciate your response.
>
> Kind regards
> Mostafa
>
> On Sat, May 16, 2020 at 12:56 PM Mostafa Sedaghat joo <
> mostafa.sedag...@gmail.com> wrote:
>
>> Hi David,
>>
>> Your solution is based on returning a promise.
>> But I need to wait on current task (execute_tx) to get the response from
>> the client (get_storage) the continue the task (execute_tx) .
>> Running a task inside another task which is not a good idea. right?
>> I would like to know if I want to change the design, what is your
>> suggestion?
>>
>> You can find the code here:
>>
>> https://github.com/b00f/durian/blob/c75116deed7a7b46c644111c5d391eee650a62de/durian-server/src/provider_adaptor.rs#L43
>>
>> Many thanks
>>
>>
>> On Sunday, May 10, 2020 at 1:28:52 AM UTC+8, David Renshaw wrote:
>>>
>>> Hi Mostafa,
>>>
>>> The problem is that you're creating an independent
>>> futures::executor::LocalPool inside the method and then blocking on it.
>>> That never yields control back to the main event loop.
>>>
>>> It should work if you set things up like this:
>>>
>>> impl executor::Server for ExecutorImpl {
>>>     fn execute(
>>>         &mut self,
>>>         params: executor::ExecuteParams,
>>>         mut results: executor::ExecuteResults,
>>>     ) -> Promise<(), Error> {
>>>         let provider = pry!(pry!(params.get()).get_provider());
>>>         Promise::from_future(async move {
>>>             let storage_req = provider.get_storage_request();
>>>             let storage_result = storage_req.send().promise.await?;
>>>             let storage = storage_result.get()?.get_storage()?;
>>>
>>>             // use storage here ...
>>>             println!("storage = {}", storage);
>>>             Ok(())
>>>         })
>>>     }
>>> }
>>>
>>>
>>>
>>>
>>> On Sat, May 9, 2020 at 10:44 AM Mostafa Sedaghat joo <
>>> mostafa...@gmail.com> wrote:
>>>
>>>> Hello guys,
>>>>
>>>>
>>>> I hope you all are doing well
>>>>
>>>>
>>>> I am struggling with an issue for more than a week, I decided to ask
>>>> you if you can help me. Currently I am working on a project for executing
>>>> smart contracts based on Web-Assembly for Blockchains. The project is named
>>>> Durian and you can check it here: https://github.com/b00f/durian
>>>>
>>>> Durian simply provides an interface for blockchains to execute smart
>>>> contracts. A client can ask the Durian: "Hey please execute this smart
>>>> contract for me", and then Durian tries to execute it. During the
>>>> execution, Durian might ask the client to provide some information:
>>>> "Blockchain please give me some information like storage, account, etc."
>>>> Finally the execution will return with the final result.
>>>>
>>>> Locally everything works fine. I wanted to make it as a web service. So
>>>> I have two choices:
>>>>
>>>> Pull model: Client asks blockchain to execute the smart contract and
>>>> in a loop he asks Durian: Hey Durian do you need anything that I can
>>>> provide for you”, Durian might say:” Yes please, Give me this storage” and
>>>> so on. In this case I can use gRPC or CapnProto, Both works fine.
>>>>
>>>> Push model: Client asks Durian to execute a smart contract, during the
>>>> execution, Durian calls client several times to get some information. Like
>>>> storage as an example. The point is that calling the client happens inside
>>>> the execution call.
>>>> [image: durian_flows.png]
>>>>
>>>> I decided to implement the second model using CapnP Proto.  I tried and
>>>> tried and again tried but unfortunately I failed. The difference between
>>>> this model and PubSub is in the PubSub model, the publisher and the
>>>> subscriber are running independently.
>>>>
>>>> First of all I want to know do you think the Push model is something
>>>> feasible and practical?
>>>>
>>>> If yes, Why can't I call the client from the server?
>>>> [image: durian_diagram.png]
>>>>
>>>> I have attached my work. I made it as simple as I could. I removed the
>>>> Durian from it and just added only one method for getting storage. I want
>>>> to get storage value from the client during the execution.
>>>>
>>>> I really appreciate it if you can take a look at it and let me know
>>>> which part I was doing wrong?
>>>>
>>>> In advance I would like to thank you.
>>>>
>>>>
>>>> Regards,
>>>>
>>>> Mostafa
>>>>
>>>> --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Cap'n Proto" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to capn...@googlegroups.com.
>>>> To view this discussion on the web visit
>>>> https://groups.google.com/d/msgid/capnproto/CAJr8eKtwcLa3f7tGiPvM39bQ8S7gqFptDZ1Zw47yRJHzqNr5DQ%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/capnproto/CAJr8eKtwcLa3f7tGiPvM39bQ8S7gqFptDZ1Zw47yRJHzqNr5DQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> --
>> You received this message because you are subscribed to the Google Groups
>> "Cap'n Proto" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to capnproto+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/capnproto/cf911c07-005a-4373-b400-5a1955a49643%40googlegroups.com
>> <https://groups.google.com/d/msgid/capnproto/cf911c07-005a-4373-b400-5a1955a49643%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Cap'n Proto" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to capnproto+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/capnproto/CAJr8eKsyNM8ADE2zSkx99H4ggcEZuV%2BtPax2UDtxYnPbCg0hig%40mail.gmail.com
> <https://groups.google.com/d/msgid/capnproto/CAJr8eKsyNM8ADE2zSkx99H4ggcEZuV%2BtPax2UDtxYnPbCg0hig%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to capnproto+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/capnproto/CABR6rW-gS%3DLvdK70O1piLC3p11MzCVt3zj5%3DBcqPfuBkpQMYoQ%40mail.gmail.com.

Reply via email to