~qaul/community

8

[Katharina Fey] Re: Question regarding collector

Details
Message ID
<871rqjj30t.fsf@kookie.space>
DKIM signature
missing
Download raw message
From: Katharina Fey <kookie@spacekookie.de>
To: Leonora Tindall <nora@nora.codes>
Subject: Re: Question regarding collector
In-Reply-To: <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes> <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes> <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space> <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes> <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space> <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
Date: Fri, 21 Feb 2020 13:28:13 +0000
Message-ID: <875zg0jcia.fsf@kookie.space>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
	micalg=pgp-sha256; protocol="application/pgp-signature"

--=-=-=
Content-Type: text/plain

Hey Nora,

> I'll throw my energies in that direction, and we can table this for
> later. As you say, this kind of optimization is important but not as
> important as having working software in the first place.

I wrote a small reproduction of the problem that fits into a single code
file: https://pastebin.com/0FigytMF, you'll neet async-std with the
unstable feature enabled (because the pin API isn't stable there yet I
think).  Anyway, it looks like it just never polls that "outbox" future
more than once, which is a problem because we have this pattern _all_
over the codebase :(

Gonna try to ask Stjepan for some help about this, if we're doing
something wrong, or if this is an async-std bug.  This would be kinda
bad for all sorts of reasons :/

> Personally, I really appreciate you doing the work necessary to guide
> the work as you're the only person who has both a good technical
> knowledge and a view of the whole system and it's goals.

Thanks!  I appreciate hearing this.  It's definitely not easy and I've
been thinking about how to best deal with there being too much
information in my head.  Maybe the weekly calls would be a good way to
start, where I talk less about what I've been doing and rather about
what needs doing.


~k

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEU1yozzD8YhxLtnIc+XKu6iiH1UcFAl5P2wIACgkQ+XKu6iiH
1UdYWg/+ObaMtjrefm5eH8daigLpbwoCNMhZyM9ZBkAx3wEoeDvwJRDIaTu7DaJk
L2AOrtDxckRS6DF4UtEnFVWH/PWlphSgMognObStKxNbaJLbhbFiqcGUtDDb/91r
fj7FvEphQ3IKhPsSzxePFIFCV8bF/aiGKGUIu6jZmRQ9n6ljtnV7jaRdxDZm435+
Dm87Z3eYNXGPY3zr0WjzR+kOCeUQ4PgVPPb2oGSIsVJpdAq1P502PA28fEhjcptI
VQS7TUExoy5PTTHBZCxgGINNYP9gF7U6DUJKRdzg2ySzTR6I1PyElm2U8EokI8Do
8CFJyH8ByK4OYqUJY3aDB8EzMJeFyCk98cOgitcoORtO850AGcQvaV6OiNrq3wh1
VWkAvrNqxKEydku/saL2K4S3G+M9RyEBLL9o2vuebpCQt61BflaqyZgR2OiJgwdP
fgBDrMOhi3D6ZzTcxlbsRWFKAyhCMdnkxRDVSsYDoTq0nvTS8ema9r5SwoW+NXJK
HngPWld019hKOL7qGkipGaFfDxLXEKkkRnA/fQXCpRXGSpvB519jQwQ2AmBpK6cC
RniGNetuFKVgTfjqdhmX+lQmULsU9Nbjq9gqXRfITVD+zTNO6gndazyKLnGjxPq1
wMo1RQQWIZrJLLnE3U5iD4v9Gqf00/5f8YTDqrQukcS/FaPlUe0=
=2Unh
-----END PGP SIGNATURE-----
--=-=-=--
Details
Message ID
<87wo8bhoe1.fsf@kookie.space>
In-Reply-To
<871rqjj30t.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
From: Katharina Fey <kookie@spacekookie.de>
To: Leonora Tindall <nora@nora.codes>
Subject: Re: Question regarding collector
In-Reply-To: <875zg0jcia.fsf@kookie.space>
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes> <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes> <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space> <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes> <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space> <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com> <875zg0jcia.fsf@kookie.space>
Date: Fri, 21 Feb 2020 14:09:47 +0000
Message-ID: <8736b4jal0.fsf@kookie.space>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
	micalg=pgp-sha256; protocol="application/pgp-signature"

--=-=-=
Content-Type: text/plain

Hey!

> Gonna try to ask Stjepan for some help about this, if we're doing
> something wrong, or if this is an async-std bug.  This would be kinda
> bad for all sorts of reasons :/

So I re-read a conversation I had with Stjepan a few weeks ago, and I
read the async-std docs again and it kinda sounds like poll_fn doesn't
actually work the way we're using it at the moment.  The ctx that's
passed in, that's used for the poll() function on the pinned future,
gives access to a waker, which can be called to wake() a task.

This would imply that we need to have some mechanism to determine when a
task should be woken up.

+ When writing a netmod: the task should be woken up when $something in
  the driver registers that there's new data to fetch

+ When writing ratman internals: the workers get woken when there's new
  work, stuff like collector::completed() needs to be re-polled when a
  worker hands in work

Actually that last case applies to most internals, including libqaul.
But this will be a lot of work, because we need to figure out what the
call relations between our modules are, and also how to interact with
wakers, store them, etc.

So here's a suggestion for all the ratman and libqaul internals: we
replace all the poll_fn blocks with a simple sleeping loop:


        let outbox = Arc::clone(&self.outbox);

        loop {
            let mut vec = outbox.lock().await;
            match vec.pop_front() {
                Some(f) => return f,
                None => {}
            }

            drop(vec);
            task::sleep(std::time::Duration::from_millis(10)).await;
        }


This will just retry every 10ms, which is slow enough to not pin the
thread permanently, but fast enough that it should be neglegable.
Everything should have buffers that are lange enough to keep up with
whatever we're gonna be doing in the prototype phase.

I'm a bit worried about using this for the netmod, because networking
code has much higher throughput, so maybe the wifi-direct netmod should
be the first one to actually use the poll-api correctly (we should have
a way to get a "hey there's new data" from the android api).

I guess this is a pretty bad hack but maybe it's fine for the first
draft, then we figure out how to use the wakers api.  -- having looked
at it a bit, I'm a bit confused how we would poll a future, by passing
in a Context, and then also still have the context to wake the task
later - not to mention, what if the lock fails, which currently just
returns a Poll::Pending, does that mean that the future would never try
to get the lock again?  It's really weird and I'm not sure I fully
understand it :/


~k

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEU1yozzD8YhxLtnIc+XKu6iiH1UcFAl5P5LAACgkQ+XKu6iiH
1UdluQ/+Md3CC/WzIiuzO3RBNsK9c456FjkDuBPYlgJ/mZgO3kLUhZrRO5Aw2Dm/
GBvKSRz+ZMqnZa9MhX3a/0fcbo7GkyEMy7zcRixCzNxmGOJIJ80lro1rLNcyAx2D
PJ+WYCS/9u1e4ffaO7vPhBeV0ADBIBWS1Ei0rtCcYrXm0wr2yJUAErGzkPhs9js5
jGmx4NPDRb45U2AZCUKR7InfXbT9r9TxqOes8cZXdVGyAgnBbyPE/kCHeVaixXGo
xvWWwNqiSDgfmQu955uk+CHjSap0OyPUkCscLT3/qgzH9FSmYs1zGOHQun/ijDn7
g8TeGRoOz3ZFBhzNG5DlS5EWdIdNWtoICSh+W9aSqAKZpCFpay2A7F/tHCqRt8MW
s/MLj4OFjxhBYP9BVD/Ti8rEACs/371KNh1HU8u40cJYXBrwnc+Bs883hCujB9vp
01txn3eeM6iIz7UMjQnLvbKMiIvoDwxgofnVZz9Rmjy+RBWxsJzPmCJBDZRFAtNA
e06XRmtWjUF0uRLRACeipIT0k3W32iMJiB0W5jhHEGkW371UCvHiUr8uxr8HQcJA
DTC5+zvzWSk1v2URVU95Ksjjy9laTTEEygfPWRGvV6natGIbPy0OMenmZCHwuQtc
3S2D1u9CYRNQ02sfN8UIibFvjMbK6WiFSX2Idw+2+rYNMntAs3k=
=6tTy
-----END PGP SIGNATURE-----
--=-=-=--

[Leonora Tindall] Re: Question regarding collector

Details
Message ID
<87pne3hob1.fsf@kookie.space>
In-Reply-To
<87wo8bhoe1.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
From: Leonora Tindall <nora@nora.codes>
To: Katharina Fey <kookie@spacekookie.de>
Subject: Re: Question regarding collector
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes>
 <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes>
 <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space>
 <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes>
 <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space>
 <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
 <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space>
Message-ID: <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
Date: Fri, 21 Feb 2020 11:05:30 -0600


Hi Katharina,

I'm pretty sure this 10ms waitloop is essentially what the async_std 
executor is already doing. It keeps a queue of all runnable tasks (every 
poll_fn() task is runnable unless sleeping or .await'ing something else) 
globally, and local executor pool threads steal them. Once stolen they 
remain in the local thread's task queue unless stolen by another thread. 
They are executed until the queue is exhausted at which point the thread 
sleeps for 10ms.

https://github.com/async-rs/async-std/blob/8ea920c9f05f00fd8cc17c7e70ed5676e9a969ad/src/task/executor/pool.rs#L123

So, unless the poll_fn futures are not runnable for some reason, they're 
already getting run every 10ms at worst.

Regarding the netmods, I think implementing our own futures would be the 
way to go were we lacking async_std. However, this isn't a problem for 
netmod-mem, because its runnable state depends only on the state of its 
channels, which are handled by async_std's channels, nor for netmod-udp, 
whose runnable state depends only on async_std locks and network 
interfaces, which are already Waker-aware. I'm not sure about netmod-ws; 
it's possible that we'll need custom Waker-aware futures there.

Best,
Nora

On 2/21/20 8:09 AM, Katharina Fey wrote:
> Hey!
> 
>> Gonna try to ask Stjepan for some help about this, if we're doing
>> something wrong, or if this is an async-std bug.  This would be kinda
>> bad for all sorts of reasons :/
> 
> So I re-read a conversation I had with Stjepan a few weeks ago, and I
> read the async-std docs again and it kinda sounds like poll_fn doesn't
> actually work the way we're using it at the moment.  The ctx that's
> passed in, that's used for the poll() function on the pinned future,
> gives access to a waker, which can be called to wake() a task.
> 
> This would imply that we need to have some mechanism to determine when a
> task should be woken up.
> 
> + When writing a netmod: the task should be woken up when $something in
>    the driver registers that there's new data to fetch
> 
> + When writing ratman internals: the workers get woken when there's new
>    work, stuff like collector::completed() needs to be re-polled when a
>    worker hands in work
> 
> Actually that last case applies to most internals, including libqaul.
> But this will be a lot of work, because we need to figure out what the
> call relations between our modules are, and also how to interact with
> wakers, store them, etc.
> 
> So here's a suggestion for all the ratman and libqaul internals: we
> replace all the poll_fn blocks with a simple sleeping loop:
> 
> 
>          let outbox = Arc::clone(&self.outbox);
> 
>          loop {
>              let mut vec = outbox.lock().await;
>              match vec.pop_front() {
>                  Some(f) => return f,
>                  None => {}
>              }
> 
>              drop(vec);
>              task::sleep(std::time::Duration::from_millis(10)).await;
>          }
> 
> 
> This will just retry every 10ms, which is slow enough to not pin the
> thread permanently, but fast enough that it should be neglegable.
> Everything should have buffers that are lange enough to keep up with
> whatever we're gonna be doing in the prototype phase.
> 
> I'm a bit worried about using this for the netmod, because networking
> code has much higher throughput, so maybe the wifi-direct netmod should
> be the first one to actually use the poll-api correctly (we should have
> a way to get a "hey there's new data" from the android api).
> 
> I guess this is a pretty bad hack but maybe it's fine for the first
> draft, then we figure out how to use the wakers api.  -- having looked
> at it a bit, I'm a bit confused how we would poll a future, by passing
> in a Context, and then also still have the context to wake the task
> later - not to mention, what if the lock fails, which currently just
> returns a Poll::Pending, does that mean that the future would never try
> to get the lock again?  It's really weird and I'm not sure I fully
> understand it :/
> 
> 
> ~k
> 
Details
Message ID
<87lforho8s.fsf@kookie.space>
In-Reply-To
<87pne3hob1.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
Date: Fri, 21 Feb 2020 17:58:59 +0000
From: Katharina Fey <kookie@spacekookie.de>
To: Leonora Tindall <nora@nora.codes>
Subject: Re: Question regarding collector
In-Reply-To: <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes> <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes> <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space> <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes> <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space> <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com> <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space> <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
Message-ID: <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de>
X-TUID: b+NvDjjrt87q

Hey Nora,

> https://github.com/async-rs/async-std/blob/8ea920c9f05f00fd8cc17c7e70ed5676e9a969ad/src/task/executor/pool.rs#L123
>
> So, unless the poll_fn futures are not runnable for some reason,
> they're already getting run every 10ms at worst.

See, that's what I was already thinking but in the example I sent you
the function _isn't_ being polled repeatedly, and I'm not really sure
why, and how to make it be. I had a look at the waker api, which seems
straight forward, but then actually using it isn't.

I'm wondering if you have ideas for that given the small example I sent
you in on pastebin.

As for the collector I changed the poll behaviour, which now means it
works. I also added some tests that insert and process 1000, 10000,
100000 and 1000000 messages, all being rather small and we want to have
a way to more easily generate whole frame sequences.

~k

[Leonora Tindall] Re: Question regarding collector

Details
Message ID
<87d0a3hnra.fsf@kookie.space>
In-Reply-To
<87lforho8s.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
From: Leonora Tindall <nora@nora.codes>
To: Katharina Fey <kookie@spacekookie.de>
Subject: Re: Question regarding collector
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes>
 <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes>
 <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space>
 <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes>
 <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space>
 <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
 <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space>
 <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
 <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de>
Message-ID: <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes>
Date: Sat, 22 Feb 2020 19:57:46 -0600


Hi Katharina,

After some playing around, I realized that there's potentially a more 
elegant way to do this (re: your example, that is.)

So, fundamentally, the issue is that there's no communication to the 
executor about _what_ the polling function in done() is polling, right? 
We can add that channel of communication by adding a Waker, stored in 
the Manager struct. When the Manager is polled, the poll function 
populates the field with its Waker (if not already populated), and when 
the worker adds finished work to the outbox, it wake()s the Manager's 
Waker. This could be enforced with a different API design. Patch and 
patched main.rs attached.

Regarding other tasks, I went ahead and did a rebase for the async 
branch; it's async-rebased. It was pretty simple to reconcile. If you 
like it, we can make the MR be based on that, and merge it. I've also 
been playing around with a "qauld" implementation - a UNIX daemon that 
will use the IPC interface. Obviously neither the router nor the IPC 
interface are ready for use yet, but it's been informative as to how the 
APIs work. I'm going to refactor and push that on its own branch.

I hope you're having a wonderful weekend!
Nora

On 2/21/20 11:58 AM, Katharina Fey wrote:
> Hey Nora,
> 
>> https://github.com/async-rs/async-std/blob/8ea920c9f05f00fd8cc17c7e70ed5676e9a969ad/src/task/executor/pool.rs#L123
>>
>> So, unless the poll_fn futures are not runnable for some reason,
>> they're already getting run every 10ms at worst.
> 
> See, that's what I was already thinking but in the example I sent you
> the function _isn't_ being polled repeatedly, and I'm not really sure
> why, and how to make it be. I had a look at the waker api, which seems
> straight forward, but then actually using it isn't.
> 
> I'm wondering if you have ideas for that given the small example I
> sent you in on pastebin.
> 
> As for the collector I changed the poll behaviour, which now means it
> works. I also added some tests that insert and process 1000, 10000,
> 100000 and 1000000 messages, all being rather small and we want to
> have a way to more easily generate whole frame sequences.
> 
> ~k
> 

From 735aef7c3dc10202809e16082b181016c417b868 Mon Sep 17 00:00:00 2001
From: Leonora Tindall <nora@nora.codes>
Date: Sat, 22 Feb 2020 19:53:23 -0600
Subject: [PATCH] waker configuration

---
 src/main.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 203d8d8..77e8e52 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
 use async_std::{
     sync::{Arc, Mutex},
-    task::{self, Poll},
+    task::{self, Poll, Waker},
     future::{self, Future},
     pin::Pin
 };
@@ -27,6 +27,7 @@ impl Worker {
         if *b > 10 {
             println!("Done with work");
             parent.outbox.lock().await.push_back(*b);
+            parent.waker.lock().await.as_ref().map(|w| w.wake_by_ref());
             None
         } else {
             Some(())
@@ -44,6 +45,7 @@ struct Manager {
     workers: Arc<Mutex<BTreeMap<usize, Arc<Worker>>>>,
     inbox: Mutex<BTreeMap<usize, VecDeque<usize>>>,
     outbox: Arc<Mutex<VecDeque<usize>>>,
+    waker: Arc<Mutex<Option<Waker>>>,
 }
 
 impl Manager {
@@ -61,6 +63,10 @@ impl Manager {
     pub async fn done(&self) -> usize {
         let outbox = Arc::clone(&self.outbox);
         future::poll_fn(|ctx| {
+            let mut waker = task::block_on(async { self.waker.lock().await  });
+            if waker.is_none() {
+                *waker = Some(ctx.waker().clone());
+            }
             let lock = &mut outbox.lock();
             match unsafe { Pin::new_unchecked(lock).poll(ctx) } {
                 Poll::Ready(ref mut vec) if vec.len() > 0 => match vec.pop_front() {
@@ -106,4 +112,4 @@ async fn main() {
 
     let data = man.done().await;
     dbg!(data);
-}
\ No newline at end of file
+}
-- 
2.20.1


use async_std::{
    sync::{Arc, Mutex},
    task::{self, Poll, Waker},
    future::{self, Future},
    pin::Pin
};
use std::collections::{BTreeMap, VecDeque};

/// Workers do work
struct Worker {
    buf: Mutex<usize>,
}

impl Worker {
    fn new() -> Arc<Self> {
        Arc::new(Self {
            buf: Default::default(),
        })
    }

    /// Return None if work is done
    async fn poll(&self, parent: Arc<Manager>) -> Option<()> {
        println!("Polling worker");
        let mut b = self.buf.lock().await;
        *b += 1;

        if *b > 10 {
            println!("Done with work");
            parent.outbox.lock().await.push_back(*b);
            parent.waker.lock().await.as_ref().map(|w| w.wake_by_ref());
            None
        } else {
            Some(())
        }
    }
}

/// Managers take credit
///
/// The "work" here is just incrementing usize, but the actual work is
/// more complicated. Also, the ID is usually a byte array, but here
/// we just use usize too because why not.
#[derive(Default)]
struct Manager {
    workers: Arc<Mutex<BTreeMap<usize, Arc<Worker>>>>,
    inbox: Mutex<BTreeMap<usize, VecDeque<usize>>>,
    outbox: Arc<Mutex<VecDeque<usize>>>,
    waker: Arc<Mutex<Option<Waker>>>,
}

impl Manager {
    pub fn new() -> Arc<Self> {
        Default::default()
    }

    /// Queue some work for the workers to do, and the manager to get credit for
    pub async fn queue(&self, id: usize) {
        self.inbox.lock().await.entry(id).or_default().push_back(1);
    }


    /// Poll for completed messages from teh outside world
    pub async fn done(&self) -> usize {
        let outbox = Arc::clone(&self.outbox);
        future::poll_fn(|ctx| {
            let mut waker = task::block_on(async { self.waker.lock().await  });
            if waker.is_none() {
                *waker = Some(ctx.waker().clone());
            }
            let lock = &mut outbox.lock();
            match unsafe { Pin::new_unchecked(lock).poll(ctx) } {
                Poll::Ready(ref mut vec) if vec.len() > 0 => match vec.pop_front() {
                    Some(f) => Poll::Ready(f),
                    None => unreachable!(),
                },
                Poll::Ready(ref vec) => {
                    println!("Pending vecdeque empty");
                    Poll::Pending
                }
                Pending => {
                    println!("Pending lock");
                    Poll::Pending
                },
            }
        })
        .await
    }

    pub async fn spawn(self: Arc<Self>, id: usize) {
        let w = Worker::new();
        let this = Arc::clone(&self);
        this.workers.lock().await.insert(id, Arc::clone(&w));

        task::spawn(async move {
            while let Some(()) = w.poll(Arc::clone(&this)).await {}
            this.workers.lock().await.remove(&id);
        });
    }
}

#[async_std::main]
async fn main() {
    let man = Manager::new();

    for _ in 0..10 {
        man.queue(0).await;
    }

    dbg!(man.inbox.lock().await.iter().fold(0, |acc, (_, i)| acc + i.len()));

    Arc::clone(&man).spawn(0).await;

    let data = man.done().await;
    dbg!(data);
}
Details
Message ID
<878skrhnq9.fsf@kookie.space>
In-Reply-To
<87d0a3hnra.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message

From: Katharina Fey <kookie@spacekookie.de>
To: Leonora Tindall <nora@nora.codes>
Subject: Re: Question regarding collector
In-Reply-To: <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes>
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes> <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes> <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space> <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes> <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space> <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com> <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space> <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes> <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de> <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes>
Date: Mon, 24 Feb 2020 16:36:47 +0000
Message-ID: <87ftf0hrhc.fsf@kookie.space>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
	micalg=pgp-sha256; protocol="application/pgp-signature"

--=-=-=
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

Hey Nora,

I had a chat with Stjepan the other day and he said that the 10ms
re-poll is an optimisation that we shouldn't rely on (evidently).

> So, fundamentally, the issue is that there's no communication to the=20
> executor about _what_ the polling function in done() is polling,
> right? [...]

I've been thinking about this too and I kinda like this design, even
more so than just to replace the Tree<Id, VecDeque> with channels,
because the vecdeque can accommidate 1000 frames being dumped into the
queue at the same time, without having to schedule the worker to work
down the load first.

I'm wondering if we want to write a smol abstraction for this, because I
feel like: poll this "closure, and give me easy access to a waker" is
somethingi we might wanna do in a few places.  "async-utils" or
something.

Are you gonna be able to attend the call in a bit?  If so, see you there
and let's talk this and the rebase (which I'm fine just pushing to the
async branch and maybe merging soon) then!


~k

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEU1yozzD8YhxLtnIc+XKu6iiH1UcFAl5T+6QACgkQ+XKu6iiH
1Uetqg/+IjZM2jJmaBss5Xq1JoX/O6jbbtgcKG4m/IDnGXyecOfHjaZ08VkTCfDe
ym6V50FjfA7IRJgP4PvBE8FzTtlf8WEvchBazFRaj8kG63aQ6K3JjNtkqITfaNGp
r/BZKLd9G+BYBsLezWgasi7aKhixtgX8agnb+Ilo2jQdSpDd0Ts1ojGxN5IQl6Eh
0oH/8Agz7PdD3asF6VLQfttWUx1gSf83isRDGSGuibU2Ep6/N8cswIBDBt9y5ZBW
agIg8E6n0LgJ7PAZb1hAAm2O7bFN991YFHX03RPYgxL3eAyDV4xHtcrr3rtrU0hr
fROlEjqAx1Es44b4Wm8XDZbClc4OvIWDGbyavLZztuWuCjVPEuW8h+6ePfWz4R8D
SCVnZbO4OxKgAS+rDvO+BEBkG6+NnpL+pcOiZlOZ8aUUHNCBJG51VLL9k5aqnrmw
3OekFKjzIkD7or+3HGB67DZSNr2Mz5MRaejEPg2DK0AMpvv8Q3NsE1W0SU9Z9TeE
USC6+nihHBUHqft9f55JfP0bZHXCBqPnxPQwXrAp3NddeG20Jd6VQYfLzn2vMdUi
tP/JOpkN9RzH9BJoundLifVN9rlE7vaUBie2VM0KBJOxcBHI/Fp/j1dZandm0Th1
qwvXk7YsT3nphUZxqVtsKLEfG/uGYh3OptZLjn5iLbvd8uMY79I=
=hP+X
-----END PGP SIGNATURE-----
--=-=-=--

[Leonora Tindall] Re: Question regarding collector

Details
Message ID
<874kvfhnmm.fsf@kookie.space>
In-Reply-To
<878skrhnq9.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
Patch: +32 -10
From: Leonora Tindall <nora@nora.codes>
To: Katharina Fey <kookie@spacekookie.de>
Subject: Re: Question regarding collector
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes>
 <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes>
 <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space>
 <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes>
 <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space>
 <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
 <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space>
 <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
 <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de>
 <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes>
 <87ftf0hrhc.fsf@kookie.space>
Message-ID: <909869b5-dbcd-f97b-1613-d95eda53a85d@nora.codes>


Hey Katharina,

This is an extremely cursed method of doing this, which does seem to 
actually work. I don't _think_ it's a violation of the DerefMut 
contract, technically? But it feels kind of gross.

On the other hand, it's transparent to existing code...

Best,
Nora

On 2/24/20 10:36 AM, Katharina Fey wrote:
> Hey Nora,
> 
> I had a chat with Stjepan the other day and he said that the 10ms
> re-poll is an optimisation that we shouldn't rely on (evidently).
> 
>> So, fundamentally, the issue is that there's no communication to the
>> executor about _what_ the polling function in done() is polling,
>> right? [...]
> 
> I've been thinking about this too and I kinda like this design, even
> more so than just to replace the Tree<Id, VecDeque> with channels,
> because the vecdeque can accommidate 1000 frames being dumped into the
> queue at the same time, without having to schedule the worker to work
> down the load first.
> 
> I'm wondering if we want to write a smol abstraction for this, because I
> feel like: poll this "closure, and give me easy access to a waker" is
> somethingi we might wanna do in a few places.  "async-utils" or
> something.
> 
> Are you gonna be able to attend the call in a bit?  If so, see you there
> and let's talk this and the rebase (which I'm fine just pushing to the
> async branch and maybe merging soon) then!
> 
> 
> ~k
> 

From 9c3b3f066781263d9aa115a353c5d77c7f6e4adf Mon Sep 17 00:00:00 2001
From: Leonora Tindall <nora@nora.codes>
Date: Mon, 24 Feb 2020 11:14:48 -0600
Subject: [PATCH] derefmut waker

---
 src/main.rs | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 77e8e52..5267668 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,33 @@ use async_std::{
    pin::Pin
};
use std::collections::{BTreeMap, VecDeque};
use std::ops::{Deref, DerefMut};

#[derive(Default)]
struct Notifier<T> {
    inner: T,
    waker: Option<Waker>,
}

impl<T> Deref for Notifier<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl<T> DerefMut for Notifier<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.waker.as_ref().map(|w| w.wake_by_ref());
        &mut self.inner
    }
}

impl<T> Notifier<T> {
    fn register_waker(notifier: &mut Self, waker: Waker) {
        notifier.waker = Some(waker);
    }
}

/// Workers do work
struct Worker {
@@ -27,7 +54,6 @@ impl Worker {
        if *b > 10 {
            println!("Done with work");
            parent.outbox.lock().await.push_back(*b);
            parent.waker.lock().await.as_ref().map(|w| w.wake_by_ref());
            None
        } else {
            Some(())
@@ -44,8 +70,7 @@ impl Worker {
struct Manager {
    workers: Arc<Mutex<BTreeMap<usize, Arc<Worker>>>>,
    inbox: Mutex<BTreeMap<usize, VecDeque<usize>>>,
    outbox: Arc<Mutex<VecDeque<usize>>>,
    waker: Arc<Mutex<Option<Waker>>>,
    outbox: Arc<Mutex<Notifier<VecDeque<usize>>>>,
}

impl Manager {
@@ -63,21 +88,18 @@ impl Manager {
    pub async fn done(&self) -> usize {
        let outbox = Arc::clone(&self.outbox);
        future::poll_fn(|ctx| {
            let mut waker = task::block_on(async { self.waker.lock().await  });
            if waker.is_none() {
                *waker = Some(ctx.waker().clone());
            }
            let lock = &mut outbox.lock();
            match unsafe { Pin::new_unchecked(lock).poll(ctx) } {
                Poll::Ready(ref mut vec) if vec.len() > 0 => match vec.pop_front() {
                    Some(f) => Poll::Ready(f),
                    None => unreachable!(),
                },
                Poll::Ready(ref vec) => {
                Poll::Ready(ref mut vec) => {
                    Notifier::register_waker(vec, ctx.waker().clone());
                    println!("Pending vecdeque empty");
                    Poll::Pending
                }
                Pending => {
                },
                Poll::Pending => {
                    println!("Pending lock");
                    Poll::Pending
                },
-- 
2.20.1
Details
Message ID
<87zhd7g915.fsf@kookie.space>
In-Reply-To
<874kvfhnmm.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message
From: Katharina Fey <kookie@spacekookie.de>
To: Leonora Tindall <nora@nora.codes>
Subject: Re: Question regarding collector
In-Reply-To: <909869b5-dbcd-f97b-1613-d95eda53a85d@nora.codes>
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes> <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes> <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space> <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes> <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space> <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com> <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space> <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes> <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de> <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes> <87ftf0hrhc.fsf@kookie.space> <909869b5-dbcd-f97b-1613-d95eda53a85d@nora.codes>
Date: Mon, 24 Feb 2020 17:36:23 +0000
Message-ID: <877e0bj3ag.fsf@kookie.space>
MIME-Version: 1.0
Content-Type: multipart/signed; boundary="=-=-=";
	micalg=pgp-sha256; protocol="application/pgp-signature"

--=-=-=
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

Hey Nora,

> This is an extremely cursed method of doing this, which does seem to=20
> actually work. I don't _think_ it's a violation of the DerefMut=20
> contract, technically? But it feels kind of gross.

I have to admit, I kinda like that!  Do you want to pull it out into an
async-utils crate in the qaul.net repo root, so we can reuse this?
Because I honestly feel like this would be extremely useful for libqaul
internals as well!

> +impl<T> Notifier<T> {
> +    fn register_waker(notifier: &mut Self, waker: Waker) {
> +        notifier.waker =3D Some(waker);
> +    }
> +}

How come you impl this for a type method that takes Self, instead of
just implementing it for instances?  I feel the semanticts are basically
the same, but might be nicer to use.

Also, maybe we just grab a &Waker, and clone internally.  That way it's
implicit, but again nicer to the user (is there like IntoOwned<Waker> or
something that can take an ownership, or reference, as long as the type
is clone?)


~k

--=-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEU1yozzD8YhxLtnIc+XKu6iiH1UcFAl5UCZsACgkQ+XKu6iiH
1UdqHRAAmgwq2ViRdxFPU5brEX53jqyLHmEPu5PkSPlg/s76pVUKGfgS7tgHlMMe
XXor95Xo/TtUp7fgQgUEJ5TbGdRGxldTUFyY8Px8YOfMRNYuj2MHrePSBQcWBnVM
I6IAbGfZNXihky4ieUox5Or8dBz8lYjD8bTUha+JsRslp2H/AGVjUX4ssQMNiDEZ
Ok09AHEYzwI6146UBhh+iTFXI5ly+x9KcQM3y6k5Vw1l4SPQvTV/hDhi4cJ+YmbG
sBv0abg7z+yMKwXH3mwhHcvdnn1J4vmqU4l52YfibJRTUIc+yI1l64ygF4VH9fSM
aM82SS+JohK5rhgdB+7uD63d+8Yev5ZvC0vJ90+uSFCKC2DSSYteJHZuM/9dTuh+
8dtSoIyhBX7X5Od0i/WRS4JAqWnt9nCIdhJroHCjc4zbAQy05UhreQ7bfVZaQv7m
zrpIYL6LOD1aFkV+A8YdEqCJzgOaSfSP04LQCL0D8WH4Wb6H4B9CGLd7WsMa/VtN
dw/QiMGmd7OtGzDVZ0XX+jceUjcMkGxd4H8vt90oxwCej3t+D+yXNpug7gIEdX7+
Ojuuray0d2Pz8i4P366kdb8Fr5NCYDx8kyRYq3Enen769owym4+GzPxYxo6i9P0N
20YrUb3cd4zt+F04Qa5o6TrJixAIkvn+rEKcQn0y/joqCmS4BNE=
=Z2qV
-----END PGP SIGNATURE-----
--=-=-=--

[Leonora Tindall] Re: Question regarding collector

Details
Message ID
<87v9nvg8zr.fsf@kookie.space>
In-Reply-To
<87zhd7g915.fsf@kookie.space> (view parent)
DKIM signature
missing
Download raw message

From: Leonora Tindall <nora@nora.codes>
To: Katharina Fey <kookie@spacekookie.de>
Subject: Re: Question regarding collector
References: <bd289b45-06dc-e5d1-76ce-5536e9cf6238@nora.codes>
 <8a4c5753-5545-4afe-b349-e9701dbb6be6@nora.codes>
 <87pne9e07c.fsf@kookie.space> <87mu9dduin.fsf@kookie.space>
 <edff7876-ef26-60a9-6ae6-e2dc241c0d78@nora.codes>
 <87imk0euir.fsf@kookie.space> <87ftf4eqpb.fsf@kookie.space>
 <3f8947ec-c387-470d-b1cc-5960c291e3e0@www.fastmail.com>
 <875zg0jcia.fsf@kookie.space> <8736b4jal0.fsf@kookie.space>
 <6ba36606-fc45-8a05-83f0-d2a33f05c984@nora.codes>
 <74152198-2E66-44C1-A705-F07FF837C5C8@spacekookie.de>
 <9c05b753-3006-e75d-ac0a-0f2f4d603d2e@nora.codes>
 <87ftf0hrhc.fsf@kookie.space>
 <909869b5-dbcd-f97b-1613-d95eda53a85d@nora.codes>
 <877e0bj3ag.fsf@kookie.space>
Message-ID: <6fcfe85d-2b48-60ab-a4a3-63c8acd9f7d3@nora.codes>
Date: Mon, 24 Feb 2020 11:40:44 -0600


> How come you impl this for a type method that takes Self, instead of
> just implementing it for instances?  I feel the semanticts are basically
> the same, but might be nicer to use.

This is similar to how a lot of methods are implemented on Box, so as 
not to conflict with methods on the inner type.

I'll go ahead and shove it into a crate!

Best,
Nora