-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
|
||
type StorageValue = Vec<u8>; | ||
|
||
impl Externalities for AsyncExternalities { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part could be much simpler if we refactored storage access and stuff that is now in extensions into capability-based externalities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First brief review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started looking a bit in this PR, super nice stuff 👍
But I did not really follow how native is using AsyncExternalities
(see comments).
I also start to wonder, since we are sharing a SpawnedNamed
for is handling the different calls: should we try to implement some sync at the end of RuntimeInstanceSpawn
lifetime (eg to kill sibling threads on panic from the with_externalities_safe
).
Similarily should we wait for all threads before completion (if a thread panic but there is no join to wait for it we possibly could have failure or success depending on the scheduling)?
1cbf57e
to
19ead82
Compare
cf40171
to
669465a
Compare
c2cbcf2
to
f7a02fc
Compare
2a682e8
to
34ec74d
Compare
Co-authored-by: Bastian Köcher <[email protected]>
Co-authored-by: Bastian Köcher <[email protected]>
… into nv-parallel-runtime
b9b9772
to
87430f8
Compare
87430f8
to
0583236
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides moving the stuff that was added to sp-io to a new crate
|
||
impl EntryPoint { | ||
/// Call this entry point. | ||
pub fn call(&self, data_ptr: Pointer<u8>, data_len: WordSize) -> anyhow::Result<u64> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are converting it to a String
on the calling side anyway. Instead of pulling in another dependency you could do the same here as well.
bot merge |
Trying merge. |
Good to see this is merged. Looking forward to use this feature in our runtime! Some questions: |
I am eager to try it out in the NPOS stuff. Hard use cases are concurrent phragmen and concurrent feasibility check. But an easier use case is this: I have a PR ready for a new test called PJR check. Each solution should ideally be checked to be These are just of the top of my head, I haven't looked into them in detail yet though. |
At the moment, should be quite big but with #7354 should be much as any additional runtime call.
Trait constant can change during runtime upgrade, they are not really constants.
We need to explore deterministic story of message passing. But it is definitely on the list.
You can safely drop handles without joining threads. Thanks for great questions, I'll add examples/tests so that answers are persisted. |
First of all, I would say that the API is experimental and I don't think there are any guarantees about it.
Yeah, you got it right. The storage is not readable nor writable. Lifting this limitation would involve massive design work, as far as I understand. The workers share the same binary though, so they do have access to any code and data that reside within the binary. Source level stuff like Trait constants also should be accessible.
It might be useful for concurrent and/or batch signature verification. Stateless contracts might also work (that is not even on the horizon though).
I think it would have been cool if storage could be accessed, preferably mutable. That can be achieved near-term if a worker could only operate on isolated child-trie. Message passing: I feel it would be hard to use efficiently (I think the goal for the most efficient use is to make the workers as independent as possible while having the widest forks possible), but at the same time I feel there is potential to explore there.
That's a good question. I think I'd prefer trapping in this case, since the workers are pure functions right now - not joining to one is basically a no-op. If we ever get to making them some effects we could lift this easily and allow other behavior.
Well, yes and no, but mostly no. And this is a very good point. During the block import it's possible. As long as you can carry the handles between on_initialize and on_finalize. But that won't work due to the fact that block building spawns a separate runtime instance for each call. |
Thanks for the answers. They are really helpful. Just one more comment, this will make weights & benchmarking very interesting... |
As long as you don't have unbound parallelism and reference machine used for benchmarking has number of cores specified, benchmarks should be valid. |
It can be fixed in principle (by keeping tasks alive during block production) But anyway, the problem with persisting handles will not probably be solved until we ditch native runtime |
About it, I was thinking that forcing join would be good (but it requires to manage a pool of thread for the runtime call). The case I don't like much is a panicking worker that is not joined, then its extrinsic evaluation can non deterministically panic or not. One can even include by mistake a panicking extrinsic in a block. |
How could it be non-deterministic? When runtime finishes its execution there are two outcomes: in one the runtime joined the worker and the other where the runtime didn't. Which outcome takes place depends solely on the actions of the runtime which is assumed to be deterministic. Sure, strictness is not necessary, but there are 0 reasons when you want to do that and then if that happens then it is certainly a programming error, which should be reported ASAP IMO. Then, this would rule out the users from relying on the behavior of automatic joining leaving us a possibility to endow our own semantics to this event. |
I was wrongly thinking about the panicking behavior, but it all run behind a panic handler so that is fine. Still think we should either join or early terminate worker :) |
Closes #1459