Jump to page: 1 2
Thread overview
Async-await on stable Rust!
Nov 08, 2019
Heromyth
Nov 08, 2019
rikki cattermole
Nov 08, 2019
Sebastiaan Koppe
Nov 08, 2019
rikki cattermole
Nov 08, 2019
Sebastiaan Koppe
Nov 08, 2019
rikki cattermole
Nov 08, 2019
Sebastiaan Koppe
Nov 08, 2019
rikki cattermole
Nov 08, 2019
jmh530
Nov 08, 2019
Russel Winder
Nov 10, 2019
Russel Winder
Nov 10, 2019
Russel Winder
Nov 10, 2019
Russel Winder
Nov 10, 2019
rikki cattermole
Nov 10, 2019
Paolo Invernizzi
Nov 10, 2019
Russel Winder
Nov 09, 2019
Heromyth
November 08, 2019
See https://blog.rust-lang.org/2019/11/07/Async-await-stable.html.
November 08, 2019
On 08/11/2019 3:04 PM, Heromyth wrote:
> See https://blog.rust-lang.org/2019/11/07/Async-await-stable.html.

https://rust-lang.github.io/async-book/02_execution/04_executor.html
https://rust-lang.github.io/async-book/03_async_await/01_chapter.html

So from what I can tell, there are two aspects to this.

1. Future's which have custom executors which you must explicitly call.
2. async/await which ties into the borrow checker and requires await to be called so pretty much stack only.

From previous discussion this isn't what we want in D.
The previous designs discussed is an event loop poll based and heap allocate the closure.

It does mean that we need an event loop in druntime, but since I am expecting to write up an event loop soon for the graphics workgroup I'll add that to part of its requirements (with -betterC compatible).
November 08, 2019
On Friday, 8 November 2019 at 02:13:28 UTC, rikki cattermole wrote:
> So from what I can tell, there are two aspects to this.
>
> 1. Future's which have custom executors which you must explicitly call.
> 2. async/await which ties into the borrow checker and requires await to be called so pretty much stack only.
>
> From previous discussion this isn't what we want in D.
> The previous designs discussed is an event loop poll based and heap allocate the closure.
>
> It does mean that we need an event loop in druntime, but since I am expecting to write up an event loop soon for the graphics workgroup I'll add that to part of its requirements (with -betterC compatible).

Please have a look at the approach taken by structured concurrency. Recently mentioned on this forum by John Belmonte: https://forum.dlang.org/post/rnqbswwwhdwkvvqvodlb@forum.dlang.org

Kotlin has taken that route as well and I have found working with it's concurrency very pleasant.

The central idea of structured concurrency (a term taken from structured programming) is to provide 'blocks' or nurseries where tasks (threads/fiber/coroutines) run concurrent, and only exit those blocks when all it's concurrent tasks are finished.

It is a simple restriction, but solves a lot of problems. You can follow the links provided in John Belmonte's posts for some more explanation.
November 08, 2019
On 08/11/2019 10:57 PM, Sebastiaan Koppe wrote:
> On Friday, 8 November 2019 at 02:13:28 UTC, rikki cattermole wrote:
>> So from what I can tell, there are two aspects to this.
>>
>> 1. Future's which have custom executors which you must explicitly call.
>> 2. async/await which ties into the borrow checker and requires await to be called so pretty much stack only.
>>
>> From previous discussion this isn't what we want in D.
>> The previous designs discussed is an event loop poll based and heap allocate the closure.
>>
>> It does mean that we need an event loop in druntime, but since I am expecting to write up an event loop soon for the graphics workgroup I'll add that to part of its requirements (with -betterC compatible).
> 
> Please have a look at the approach taken by structured concurrency. Recently mentioned on this forum by John Belmonte: https://forum.dlang.org/post/rnqbswwwhdwkvvqvodlb@forum.dlang.org
> 
> Kotlin has taken that route as well and I have found working with it's concurrency very pleasant.
> 
> The central idea of structured concurrency (a term taken from structured programming) is to provide 'blocks' or nurseries where tasks (threads/fiber/coroutines) run concurrent, and only exit those blocks when all it's concurrent tasks are finished.
> 
> It is a simple restriction, but solves a lot of problems. You can follow the links provided in John Belmonte's posts for some more explanation.

This is a better article from one of the sites you linked: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

After reading this, I can confidently say that this is not the problem I am trying to solve.

To me async/await is synchronously executed when a closure is ready to execute. However, that doesn't mean it can't work with my existing idea ;)



Nursery nursery;

nursery.async {
	....
};


nursery.async {
	....
};

return; // nursery.__dtor == run
November 08, 2019
On Friday, 8 November 2019 at 10:36:05 UTC, rikki cattermole wrote:
> This is a better article from one of the sites you linked: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/

Yes, that is a good one.

> After reading this, I can confidently say that this is not the problem I am trying to solve.

I understand. I just wanted you to be aware of it.

> To me async/await is synchronously executed when a closure is ready to execute.

What does 'ready to execute' mean? And why synchronously? isn't the idea of async to run concurrently?

> However, that doesn't mean it can't work with my existing idea ;)
>
> Nursery nursery;
>
> nursery.async {
> 	....
> };
>
> nursery.async {
> 	....
> };
>
> return; // nursery.__dtor == run

Except that you would want to run immediately, and then joinAll on the __dtor. For it is perfectly possible to have a long living nursery; the one at the root of the program for instance.

E.g

---
with (Nursery()) {
  async {
}
November 09, 2019
On 09/11/2019 2:24 AM, Sebastiaan Koppe wrote:
> On Friday, 8 November 2019 at 10:36:05 UTC, rikki cattermole wrote:
>> This is a better article from one of the sites you linked: https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/ 
>>
> 
> Yes, that is a good one.
> 
>> After reading this, I can confidently say that this is not the problem I am trying to solve.
> 
> I understand. I just wanted you to be aware of it.

I am, but thanks for the reminder.

>> To me async/await is synchronously executed when a closure is ready to execute.
> 
> What does 'ready to execute' mean? And why synchronously? isn't the idea of async to run concurrently?

So ready to execute could mean that a socket has data in the buffer ready to be read.

So I'm treating async as if it its synchronous from a language design point of view, but if you want it to be asynchronous it can be. It should depend upon the library implementation its calling into.

In other words, I don't want this behavior baked into the language. That seems like a good way to have regrets that we can't fix easily.

>> However, that doesn't mean it can't work with my existing idea ;)
>>
>> Nursery nursery;
>>
>> nursery.async {
>>     ....
>> };
>>
>> nursery.async {
>>     ....
>> };
>>
>> return; // nursery.__dtor == run
> 
> Except that you would want to run immediately, and then joinAll on the __dtor. For it is perfectly possible to have a long living nursery; the one at the root of the program for instance.
> 
> E.g
> 
> ---
> with (Nursery()) {
>    async {
> }

Indeed that was a very simple example. But throw in a copy constructor + destructor pair, you should be able to build up a nice little tree on the Nursery implementation instance. Which from what I read could be quite useful with executing the closures.
November 08, 2019
On Friday, 8 November 2019 at 14:28:36 UTC, rikki cattermole wrote:
> On 09/11/2019 2:24 AM, Sebastiaan Koppe wrote:
>> What does 'ready to execute' mean? And why synchronously? isn't the idea of async to run concurrently?
>
> So ready to execute could mean that a socket has data in the buffer ready to be read.

Ah, you mean after it first yielded.

> In other words, I don't want this behavior baked into the language. That seems like a good way to have regrets that we can't fix easily.

I am not so sure, good concurrency seems to require a little help from the compiler.

> Indeed that was a very simple example. But throw in a copy constructor + destructor pair, you should be able to build up a nice little tree on the Nursery implementation instance. Which from what I read could be quite useful with executing the closures.

Perfect.

November 08, 2019
On Friday, 8 November 2019 at 09:57:59 UTC, Sebastiaan Koppe wrote:
> [snip]
>
> Please have a look at the approach taken by structured concurrency. Recently mentioned on this forum by John Belmonte: https://forum.dlang.org/post/rnqbswwwhdwkvvqvodlb@forum.dlang.org
>
> Kotlin has taken that route as well and I have found working with it's concurrency very pleasant.
> [snip]

The nurseries idea looks the same as Chapel's cobegin blocks
https://chapel-lang.org/docs/primers/taskParallel.html


November 09, 2019
On 09/11/2019 4:11 AM, Sebastiaan Koppe wrote:
> On Friday, 8 November 2019 at 14:28:36 UTC, rikki cattermole wrote:
>> On 09/11/2019 2:24 AM, Sebastiaan Koppe wrote:
>>> What does 'ready to execute' mean? And why synchronously? isn't the idea of async to run concurrently?
>>
>> So ready to execute could mean that a socket has data in the buffer ready to be read.
> 
> Ah, you mean after it first yielded.

That's one way to do it, yes.
You may not want to wrap it in a fiber though.
That can be a bit costly if you don't need it.

But that is a decision that the language does not need to make luckily.
It can be made by the compiler hook implementation and what library its hooking the closure creation into.

>> In other words, I don't want this behavior baked into the language. That seems like a good way to have regrets that we can't fix easily.
> 
> I am not so sure, good concurrency seems to require a little help from the compiler.

From what I've read over the years, nobody seems to have any compelling solution to concurrency. Its a hard problem to solve, at least in the general case.
That is why I don't like the idea of baking one model into the language. It probably won't work for a lot of people, assuming it works as advertised.
November 08, 2019
On Fri, 2019-11-08 at 15:24 +0000, jmh530 via Digitalmars-d wrote:
> […]
> 
> The nurseries idea looks the same as Chapel's cobegin blocks https://chapel-lang.org/docs/primers/taskParallel.html

Chapel has many things to teach most other programming languages about parallelism, especially on a truly multi-processor computer. Not least of which is partitioned global address space (PGAS).

-- 
Russel.
===========================================
Dr Russel Winder      t: +44 20 7585 2200
41 Buckmaster Road    m: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



« First   ‹ Prev
1 2