Newsgroups: php.internals
Path: news.php.net
Xref: news.php.net php.internals:113054
Return-Path: <me@kelunik.com>
Delivered-To: mailing list internals@lists.php.net
Received: (qmail 48862 invoked from network); 2 Feb 2021 21:52:32 -0000
Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5)
  by pb1.pair.com with SMTP; 2 Feb 2021 21:52:32 -0000
Received: from php-smtp4.php.net (localhost [127.0.0.1])
	by php-smtp4.php.net (Postfix) with ESMTP id 46CC21804CF
	for <internals@lists.php.net>; Tue,  2 Feb 2021 13:35:50 -0800 (PST)
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net
X-Spam-Level: 
X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_40,DKIM_SIGNED,
	DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,
	RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE autolearn=no
	autolearn_force=no version=3.4.2
X-Spam-Virus: No
X-Envelope-From: <me@kelunik.com>
Received: from mo4-p00-ob.smtp.rzone.de (mo4-p00-ob.smtp.rzone.de [81.169.146.221])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256)
	(No client certificate requested)
	by php-smtp4.php.net (Postfix) with ESMTPS
	for <internals@lists.php.net>; Tue,  2 Feb 2021 13:35:49 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1612301747;
	s=strato-dkim-0002; d=kelunik.com;
	h=Cc:To:Subject:Message-ID:Date:From:In-Reply-To:References:Cc:Date:
	From:Subject:Sender;
	bh=zcAsfx9vCQ6McStKYHgXuK8Xt8D5cdWA/iRlLooosqc=;
	b=Pn+JhYGf4A1XSpXun6NkGd+72dKWsiWnN22aC2CDJA+2GGZkIBVnLVau0fwFgD7hD0
	BTpnvJ+AleUw6N0njPr06XTj0P2zcrLgmVp8meX0jELGTlKu/0n7rYh4rt9DEoHF2EPI
	ZhgXTzp8UBTdYhjIXtcFcfuJ2iAA+jWLpH7F/VBwFy7nBWd6OB4sLJndzUt0WPB6Lp8a
	CSfTFBMYqpojOcwk1q2SNdQ9hvv47X65NGZR+4dq5G+iZLb+LaVMf8Gy5WgJkUhs5AOJ
	6YjE8xDGEdXW9F3uuwwx/m1EoW8sLYJ0AbF+7tQzXqTpOzVF+tDNpt106qOftsKN8FO1
	OLnw==
X-RZG-AUTH: ":IWkkfkWkbvHsXQGmRYmUo9mlsGbEv0XHBzMIJSS+jKTzde5mDb8AaBYcZiAqcA=="
X-RZG-CLASS-ID: mo00
Received: from mail-pf1-f176.google.com
	by smtp.strato.de (RZmta 47.16.0 AUTH)
	with ESMTPSA id u0ab94x12LZlIq6
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
	(Client did not present a certificate)
	for <internals@lists.php.net>;
	Tue, 2 Feb 2021 22:35:47 +0100 (CET)
Received: by mail-pf1-f176.google.com with SMTP id y142so7259695pfb.3
        for <internals@lists.php.net>; Tue, 02 Feb 2021 13:35:47 -0800 (PST)
X-Gm-Message-State: AOAM532rhpZgZ5fEUfq25mW8X/qiru4uIke2xCf6/Hxu8UdZ1x1rQjli
	D4Qc94H1NtjXZb1IxWXkWtbxAJyzGikl1FiXaFo=
X-Google-Smtp-Source: ABdhPJyvHpHaSSKUuOBKQaauHx3dpPCSIUKq3ZWCfBmdNhj/Cdl7nbk8jKnLKKYEAgvlaFkAaMWPPM7M000EIIEPrhs=
X-Received: by 2002:a63:1707:: with SMTP id x7mr104294pgl.266.1612301746173;
 Tue, 02 Feb 2021 13:35:46 -0800 (PST)
MIME-Version: 1.0
References: <E4BE4688-3CD1-4CE8-A818-5A862F0293F5@trowski.com> <CAF+90c9LTxzgicz_Xv8CDzyxM=tNZ2NMXwYoK-UuTiNCE85+0Q@mail.gmail.com>
In-Reply-To: <CAF+90c9LTxzgicz_Xv8CDzyxM=tNZ2NMXwYoK-UuTiNCE85+0Q@mail.gmail.com>
Date: Tue, 2 Feb 2021 22:35:23 +0100
X-Gmail-Original-Message-ID: <CANUQDCiOe56LzG02xqT-uy8P4R80tjTpLFBOSGYJoXLpNi4r0Q@mail.gmail.com>
Message-ID: <CANUQDCiOe56LzG02xqT-uy8P4R80tjTpLFBOSGYJoXLpNi4r0Q@mail.gmail.com>
To: Nikita Popov <nikita.ppv@gmail.com>
Cc: Aaron Piotrowski <aaron@trowski.com>, php internals <internals@lists.php.net>
Content-Type: multipart/alternative; boundary="000000000000d9fbe305ba6140f4"
Subject: Re: [PHP-DEV] [RFC] Fibers
From: me@kelunik.com (Niklas Keller)

--000000000000d9fbe305ba6140f4
Content-Type: text/plain; charset="UTF-8"

Hey Nikita,

Thank you for the proposal. Ergonomics of async I/O in PHP certainly leave
> something to be desired right now, and improvements in this area are
> welcome.
>
> Despite your explanations in the RFC and this thread, I'm still having a
> hard time understanding the purpose of the FiberScheduler.
>
> My current understanding is that the FiberScheduler is a special type of
> fiber that cannot be explicitly scheduled by the user -- it is
> automatically scheduled by Fiber::suspend() and automatically un-scheduled
> by Fiber::resume() or Fiber::throw(). It's the fiber that runs between
> fibers :) Does that sound accurate?
>

Yes, that's accurate. Fibers are used for cooperative multi-tasking and
there's usually a single scheduler responsible for the scheduling. Multiple
schedulers would block each other or busy wait. So having multiple
schedulers is strongly discouraged in long running applications, however,
it might be acceptable in traditional applications, i.e. PHP-FPM. In
PHP-FPM, multiple schedulers partially blocking each other is still better
than blocking entirely for every I/O operation.


> What's not clear to me is why the scheduling fiber needs to be
> distinguished from other fibers. If we want to stick with the general
> approach, why is Fiber::suspend($scheduler) not Fiber::transferTo($fiber),
> where $fiber would be the fiber serving as scheduler (but otherwise a
> normal Fiber)? I would expect that context-switching between arbitrary
> fibers would be both most expressive, and make for the smallest interface.
>

There are a few reasons to make a difference here:

- SchedulerFibers are run to completion at script end, which isn't the case
for normal fibers.
- Terminating fibers need a fiber to return to. For schedulers it's fine if
a resumed fiber terminates, for normal fibers it should be an exception if
the scheduler fiber terminates without explicitly resuming the suspended
fiber.
- Keeping the previous fiber for each suspension point is complicated if
not impossible to get right and generally complicates the implementation
and cognitive load, see following example:

main -> A -> B -> C -> A (terminates) -> C (previous) -> B (terminates) ->
C (previous, terminates) -> main

In the example above, the previous fiber linked list from C back to main
needs to be optimized at some point, otherwise A and B need to be kept in
memory and thus leak memory until C is resumed.

I'm sure Aaron can present a few other reasons to keep the separation.


> The more limited alternative is to instead have Fiber::suspend() return to
> the parent fiber (the one that resume()d it). Here, the parent fiber
> effectively becomes the scheduler fiber. If I understand right, the reason
> why you don't want to use that approach, is that it doesn't allow you to
> call some AMP function from the {main} fiber, create the scheduler there
> and then treat {main} just like any other fiber. Is that correct?
>

Correct, this wouldn't allow top-level Fiber::suspend(). It would also make
the starting / previously resuming party responsible for resuming the fiber
instead of the fiber being able to "choose" the scheduler for a specific
suspension point. One fiber would thus be effectively limited to a single
scheduler.

Best,
Niklas

--000000000000d9fbe305ba6140f4--