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

ENH: Add new conditions to condition API #57

Merged
merged 19 commits into from
Jul 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/code/conds/api/scheduler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rocketry import Rocketry
from rocketry.conds import scheduler_running

app = Rocketry(config={
"shut_cond": scheduler_running(more_than="5 minutes")
})
13 changes: 13 additions & 0 deletions docs/code/conds/api/task_running.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from rocketry.conds import running

@app.task(end_cond=running(more_than="2 minutes"))
def do_things():
... # Terminates if runs over 2 minutes

@app.task(start_cond=running(do_things))
def do_if_runs():
... # Starts if do_things is running

@app.task(start_cond=running(do_things, less_than="2 minutes"))
def do_if_runs_less_than():
... # Starts if do_things is running less than 2 mins
17 changes: 17 additions & 0 deletions docs/code/conds/api/task_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from rocketry.conds import running, finished, succeeded, failed

@app.task()
def do_things():
... # Dummy task for demonstration

@app.task(finished(task=do_things).this_hour)
def do_if_finish():
...

@app.task(succeeded(task=do_things).today.between("10:00", "12:00"))
def do_if_fail_between():
...

@app.task(failed.this_week.on("Monday"))
def do_if_itself_fails():
...
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,15 @@ return instances of conditions.
Here are some examples:

.. literalinclude:: /code/conds/api/simple.py
:language: py
:language: py


.. toctree::
:maxdepth: 3
:caption: Contents:

logical
periodical
pipeline
task_status
scheduler
14 changes: 14 additions & 0 deletions docs/handbooks/conditions/api/logical.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

Logical Operators
=================

There are three logical operators for conditions:

- ``&``: **AND** operator
- ``|``: **OR** operator
- ``~``: **NOT** operator

Examples:

.. literalinclude:: /code/conds/api/logic.py
:language: py
90 changes: 90 additions & 0 deletions docs/handbooks/conditions/api/periodical.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Periodical Execution
====================

Time based scheduling is the base for most schedulers.
Often it is interpret that a task is set to run when
a given time is reached and the task has not yet run
at that time, or given time has passed from the previous
run. Time based scheduling can be divided into two categories:

- Floating periods: Run when given time has passed from previous run
- Fixed period: Run at given time of day, week etc.

Floating Periods
----------------

Perhaps the simplest scheduling is to run a task
when a given amount of time has passed. This
can be done by:

.. literalinclude:: /code/conds/api/every.py
:language: py

.. note::

The condition ``every`` is linked running the task


Fixed Periods
-------------

It is also common to have a task to run once in some
agreed fixed time span. Such time spans are:

- hour: starts at 0 minute and ends at 60 minute
- day: starts at 00:00 and ends at 24:00
- week: starts on Monday at 00:00 and ends on Sunday at 24:00
- month: starts at 1st at 00:00 and ends 28rd-31st at 24:00

Running a task every hour is different than running a task
hourly in Rocketry. The difference is that the former runs
every time after 60 minutes has passed but the latter every
full hour. If time is now 07:15, the former will run at
08:15 but the latter will run at 08:00.

.. literalinclude:: /code/conds/api/periodical.py
:language: py


Constrained
^^^^^^^^^^^

The fixed periods can also be constrained using ``before``,
``after`` and ``between``:

- ``before``: From the beginning of the fixed period till the given time
- ``after``: From the given time to the end of the fixed period
- ``between``: From given start time to the given end time

So what this means in practice? Here is an illustration for a day/daily:

- *before 14:00*: From 00:00 (0 am) to 14:00 (2 pm)
- *after 14:00*: From 14:00 (2 pm) to 24:00 (12 pm)
- *between 08:00 and 16:00*: From 08:00 (8 am) to 16:00 (4 pm)

and some illustations what this means for a week/weekly:

- *before Friday*: From Monday 00:00 (0 am) to Friday 24:00 (12 pm)
- *after Friday*: From Friday 00:00 (0 am) to Sunday 24:00 (12 pm)
- *between Tuesday and Friday*: From Tuesday 00:00 (0 am) to Friday 24:00 (12 pm)

There are also *on* and *starting* arguments:

- ``on``: On given time component
- ``starting``: The fixed period starts on given time

For example, *on Friday* means Friday 00:00 (0 am) to Friday 24:00 (12 pm)
and *starting Friday* means the week is set to start on Friday.

.. literalinclude:: /code/conds/api/periodical_restricted.py
:language: py

.. note::

The logic follows natural language. Statement
``between Monday and Friday`` means Monday at 00:00
(0 am) to Friday 24:00 (12 pm).

There are also **time of ...** conditions check if the current time
is within the given period.

17 changes: 17 additions & 0 deletions docs/handbooks/conditions/api/pipeline.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

Pipelining
==========

There are also conditions related to if another task has
runned/succeeded/failed before the task we are setting the
starting condition. These are useful for creating task
depenencies or task pipelines.

.. literalinclude:: /code/conds/api/pipe_single.py
:language: py

You can also pipe multiple at the same time to avoid long
logical statements:

.. literalinclude:: /code/conds/api/pipe_multiple.py
:language: py
16 changes: 16 additions & 0 deletions docs/handbooks/conditions/api/scheduler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Scheduler
=========

Scheduler related conditions are often
useful for testing purposes to prevent
the scheduler running without exit.

Perhaps the most useful of such conditions is
``scheduler_running``. This condition is true
if the scheduler has been running more than
given in ``more_than`` argument. There is also
an argument ``less_than`` to specify the maximum.

.. literalinclude:: /code/conds/api/scheduler.py
:language: py
53 changes: 53 additions & 0 deletions docs/handbooks/conditions/api/task_status.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

Task Status
===========

Task status conditions are often useful for the end condition
to prevent running a task when an important task is running
or for more advanced scheduling control.

Here is a list of task status conditions:

- ``rocketry.conds.started``: Task has started
- ``rocketry.conds.failed``: Task has failed
- ``rocketry.conds.succeeded``: Task has succeeded
- ``rocketry.conds.finished``: Task has finished

All of them support periods:

- ``this_minute``: Status happened in the current minute (fixed)
- ``this_hour``: Status happened in the current hour (fixed)
- ``this_day``: Status happened in the current day (fixed)
- ``today``: Alias for ``this_day``
- ``this_week``: Status happened in the current week (fixed)
- ``this_month``: Status happened in the current month (fixed)

All of the constrains supports additional constrains:

- ``before``: Status happened before given time
- ``after``: Status happened after given time
- ``between``: Status happened between given times
- ``on``: Status happened at given time


Here are examples:

.. literalinclude:: /code/conds/api/task_status.py
:language: py

.. note::

If the ``task`` is not given, the task is interpret to be
the task the condition is set to.

Task Running
------------

There is also the condition ``rocketry.conds.running``. This
condition is true if the given task (or the task itself if not
given) is running. There are also options ``more_than`` and
``less_than`` to specify timespan how long the task should be
running for the condition to be true:

.. literalinclude:: /code/conds/api/task_running.py
:language: py
Loading