Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/flat namespace #58

Merged
merged 13 commits into from
Oct 21, 2019
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

source/tutorial/overview
source/topics/overview
source/api/overview
source/api/usim
source/api/usim.py
source/glossary

Expand Down
34 changes: 0 additions & 34 deletions docs/source/api/overview.rst

This file was deleted.

10 changes: 0 additions & 10 deletions docs/source/api/usim.basics.rst

This file was deleted.

177 changes: 165 additions & 12 deletions docs/source/api/usim.rst
Original file line number Diff line number Diff line change
@@ -1,19 +1,172 @@
.. this API reference is autogenerated by apidoc
TODO: replace it with a manually curated one
μSim API Reference
==================

usim package
============
.. py:module:: usim
:synopsis: The μSim namespace

.. automodule:: usim
:members:
:undoc-members:
:show-inheritance:
The :py:mod:`usim` package provides access to the entire μSim API in one
convenient, flat namespace.
Logically, the API can be divided into different topics.
In addition, :py:mod:`usim.typing` allows for type annotations to statically
verify simulations.

Submodules
----------
.. hint::

μSim provides a :ref:`compatibility layer <simpy_compatibility>`
to the `SimPy`_ simulation framework.
The :py:mod:`usim.py` package is a drop-in replacement
for the :py:mod:`simpy` package.

Starting a Simulation
---------------------

Simulations in μSim are always defined based on a number of initial root
:term:`activities <activity>`,
which may branch out to more :term:`activities <activity>`.
A simulation is started by calling :py:func:`usim.run`, passing in its
:term:`activities <activity>` and optionally the time window to simulate.

.. autofunction:: usim.run

Simulating Time
---------------

μSim provides a number of primitives to check or wait for specific points in time
of a simulation.

:py:data:`usim.time`
Expressions define points in time or delays.
For example, ``await (time + 20)`` delays for 20 time units.

:py:data:`usim.eternity`
A point in time indefinitely far into the future.

:py:data:`usim.instant`
A point in time indistinguishable from the current moment.

In addition, recurring actions can be repeated at specific delays or intervals
in ``async for`` block.

:py:data:`usim.interval`
Repeat in fixed intervals, regardless of any time spent in a block.

:py:data:`usim.delay`
Repeat after fixed delays, in addition to any time spent in a block.

Branching and Multitasking
--------------------------

An :term:`activity` may not only ``await`` another,
it may also run one or more :term:`activities <activity>` concurrently.
This requires opening a scope in an ``async with`` context
which defines the lifetime of child activities.

:py:class:`usim.Scope`
An :term:`asynchronous context manager` which can concurrently
run :term:`activities <activity>` until it is closed.
A scope is forcefully closed if an exception occurs
in the hosting :term:`activity` or a child.

:py:func:`usim.until`
A :py:class:`~usim.Scope` that is forcefully closed
if a specific notification triggers.

Each child :term:`activity` is represented by a :py:class:`~usim.typing.Task`.
Tasks can be inspected for their current status,
and various exceptions only occur when interacting with tasks.

:py:class:`usim.TaskState`
Enum describing the possible :py:meth:`~usim.typing.Task.status`
of a :py:class:`~usim.typing.Task`.

:py:exc:`usim.TaskClosed` and :py:exc:`usim.VolatileTaskClosed`
The exception value of a :py:class:`~usim.typing.Task` that was forcefully
closed by its :py:class:`~usim.Scope`.

:py:exc:`usim.CancelTask` and :py:exc:`usim.TaskCancelled`
Exception used to :py:meth:`~usim.typing.Task.cancel`
a :py:class:`~usim.typing.Task`,
and the resulting exception value of the :py:class:`~usim.typing.Task`.

During a :py:class:`usim.Scope`,
multiple child activities may fail with an exception at the same time.
The :py:class:`usim.Scope` collects and propagates all exceptions from child activities.

:py:exc:`usim.Concurrent`
Exception that propagates all exceptions from child activities at once;
also occurs if only a single child activity fails.
Never includes an exception raised in the scope itself.

Synchronising Conditions
------------------------

μSim allows to model any boolean that may change at a later time
as a :py:class:`~usim.typing.Condition`.
These can be combined and negated to derive new :py:class:`~usim.typing.Condition`\ s.

:py:class:`usim.Flag`
A :py:class:`~usim.typing.Condition` with a fixed value which can be explicitly
:py:meth:`~usim.Flag.set` to either :py:data:`True` or :py:data:`False`.

It is common for types to return a :py:class:`~usim.typing.Condition` instead of
a plain :py:class:`bool`.

:py:class:`usim.Tracked`
A mutable value which can be explicitly :py:meth:`~usim.Tracked.set` or modified
using arithmetic operators, such as ``+``, ``-``, ``*`` or ``/``.
Comparison operators, such as ``==``, ``<=`` or ``>``, provide
a :py:class:`~usim.typing.Condition` which triggers once the value matches.

Sharing State
-------------

Concurrently running :term:`activities <activity>` frequently need to access,
modify or exchange state.
μSim provides several types to easily write :term:`activities <activity>` that
safely share state.

:py:class:`usim.Lock`
Ensure mutually exclusive access for multiple activities.

:py:class:`usim.Channel`
Broadcast messages to multiple subscribers.

:py:class:`usim.Queue`
Send and receive unique messages.

:py:exc:`usim.StreamClosed`
Exception for operations not supported by a closed
:py:class:`~usim.Channel` or :py:class:`~usim.Queue`

Modelling Resources
-------------------

Simulations commonly revolve around resources which are produced/consumed,
blocked or waited for.
μSim implements a range of generic, ready-to-use resources for various use-cases.

:py:class:`usim.Resources`
Supply of named resources which can be temporarily borrowed
or permanently produced/consumed.

:py:class:`usim.Capacities`
Fixed supply of named resources which can be temporarily borrowed.

:py:exc:`usim.ResourcesUnavailable`
Exception raised when an attempt to :py:meth:`~usim.Resources.claim`
resources fails.

Detailed Topics
---------------

.. toctree::
:maxdepth: 2

usim.basics
usim.typing
usim_timing
usim_branching
usim_synchronising
usim_sharing
usim_resources
usim.typing

.. _SimPy: https://simpy.readthedocs.io/
26 changes: 26 additions & 0 deletions docs/source/api/usim_branching.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Branching Tasks and Concurrent Exceptions
=========================================

.. autoclass:: usim.Scope
:members:

.. autofunction:: usim.until
:async-with:

.. autoclass:: usim.TaskState
:members:

.. autoexception:: usim.TaskClosed
:members:

.. autoexception:: usim.VolatileTaskClosed
:members:

.. autoexception:: usim.CancelTask
:members:

.. autoexception:: usim.TaskCancelled
:members:

.. autoexception:: usim.Concurrent
:members:
11 changes: 11 additions & 0 deletions docs/source/api/usim_resources.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Resource Modelling
==================

.. autoclass:: usim.Resources
:members:

.. autoclass:: usim.Capacities
:members:

.. autoexception:: usim.ResourcesUnavailable
:members:
14 changes: 14 additions & 0 deletions docs/source/api/usim_sharing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Sharing State
=============

.. autoclass:: usim.Lock
:members:

.. autoclass:: usim.Channel
:members:

.. autoclass:: usim.Queue
:members:

.. autoexception:: usim.StreamClosed
:members:
8 changes: 8 additions & 0 deletions docs/source/api/usim_synchronising.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Synchronisation via Conditions
==============================

.. autoclass:: usim.Flag
:members:

.. autoclass:: usim.Tracked
:members:
File renamed without changes.
2 changes: 2 additions & 0 deletions docs/source/topics/simpy.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _simpy_compatibility:

SimPy Compatibility
===================

Expand Down
13 changes: 10 additions & 3 deletions usim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@
from ._primitives.flag import Flag
from ._primitives.locks import Lock
from ._primitives.context import until, Scope, VolatileTaskClosed
from ._primitives.task import TaskCancelled, TaskState, TaskClosed
from ._primitives.task import TaskCancelled, TaskState, TaskClosed, CancelTask
from ._primitives.concurrent_exception import Concurrent
from ._basics.streams import Channel, Queue, StreamClosed
from ._basics.tracked import Tracked
from ._basics.resource import Capacities, Resources, ResourcesUnavailable


__all__ = [
'run',
'time', 'eternity', 'instant', 'interval', 'delay',
'until', 'Scope', 'TaskCancelled', 'VolatileTaskClosed', 'TaskClosed', 'TaskState',
'Flag', 'Lock',
'until', 'Scope',
'TaskCancelled', 'VolatileTaskClosed', 'TaskClosed', 'TaskState', 'CancelTask',
'Concurrent',
'Flag', 'Tracked',
'Lock',
'Channel', 'Queue', 'StreamClosed',
'Capacities', 'Resources', 'ResourcesUnavailable',
]


Expand Down
8 changes: 0 additions & 8 deletions usim/basics.py

This file was deleted.

2 changes: 1 addition & 1 deletion usim_pytest/test_types/test_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Type

from usim import Scope, time, until
from usim.basics import Resources, Capacities, ResourcesUnavailable
from usim import Resources, Capacities, ResourcesUnavailable
from usim._basics.resource import BaseResources

from ..utility import via_usim, assertion_mode
Expand Down
2 changes: 1 addition & 1 deletion usim_pytest/test_types/test_streams.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Type

from usim import time, Scope
from usim.basics import Queue, Channel, StreamClosed
from usim import Queue, Channel, StreamClosed
from usim.typing import Stream

from ..utility import via_usim, turnstamp
Expand Down
2 changes: 1 addition & 1 deletion usim_pytest/test_types/test_tracked.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pytest

from usim import Scope, time
from usim.basics import Tracked
from usim import Tracked

from ..utility import via_usim, assertion_mode

Expand Down