镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Add support for optional channels in Select #12

Closed as not planned
Closed as not planned

Description

What's needed?

There might be cases when one wants to do a Select loop with some channels that are optional and if they are not present the handling of those channels will just not be used. Right now there is no trivial way to do this.

Proposed solution

Create a Select.with_optional() method like (maybe incomplete and untested):

   def with_optional(self, **optional_receivers: Optional[AsyncIterator[Any]]) -> Select:
       # TODO: check name clashing with self._receivers
       for name, recv in optional_receivers.items():
           self._result[name] = None
           if recv is None:
               continue
           self._receivers[name] = recv
           # can replace __anext__() to anext() (Only Python 3.10>=)
           msg = recv.__anext__()  # pylint: disable=unnecessary-dunder-call
           self._pending.add(asyncio.create_task(msg, name=name))  # type: ignore

       return self

With the intended use:

# chan1 can't be None, chan_none can
select = Select(chan1=chan1).with_optional(chan_none=None)
while await select.ready():
    if select.chan1:
        pass
    elif select.chan_none:  # will always be None if chan_none is None
        pass

Use cases

Yet to be seen

Alternatives and workarounds

  1. Handle the optional channel explicitly:
chan_none = None
optional_channels = {}
if chan_none is not None:
    optional_channels["chan_none"] = chan_none
select = Select(chan1=chan1, **optional_channels)
while await select.ready():
    if select.chan1:  # OK
        pass
    elif chan_none and select.chan_none:  # OK too
        pass
  1. Create a dummy channel, use the receiver in the Select and never call send to the sender of the channel.
chan_none = Broadcast[int]("chan_none").get_receiver()
select = Select(chan1=chan1, chan_none=chan_none)
while await select.ready():
    if select.chan1:  # OK
        pass
    elif select.chan_none:  # OK too, will never be True
        pass

Additional context

No response

Activity

  1. added
    part:synchronizationAffects the synchronization of multiple sources (`select`, `merge`)
    and removed
    part:channelsAffects channels implementation
    on Nov 3, 2022
  2. leandro-lucarella-frequenz commented on Nov 3, 2022

    @leandro-lucarella-frequenz
    ContributorAuthor

    This will probably be closed in favor of #29, as we don't want to add new ways to misuse Select, but I will leave it open until the docs are ready just in case.

  3. added this to the v1.1.0 milestone on Aug 7, 2023
  4. llucax commented on Nov 9, 2023

    @llucax
    Contributor

    Superseded by #116.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    part:synchronizationAffects the synchronization of multiple sources (`select`, `merge`)type:enhancementNew feature or enhancement visitble to users

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions