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 <
[email protected]> 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 <
>> [email protected]> 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 [email protected].
>>> 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 [email protected].
> 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/capnproto/CAJr8eKsyNM8ADE2zSkx99H4ggcEZuV%2BtPax2UDtxYnPbCg0hig%40mail.gmail.com.