Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Horizontal Navigation Bar


Button Group

Button Hyperlink
titlePrevious
typestandard
urlhttps://confluence.ecmwf.int/display/ECFLOW/Time+Dependencies
Button Hyperlink
titleUp
typestandard
urlhttps://softwareconfluence.ecmwf.int/wiki/display/ECFLOW/Going+Further
Button Hyperlink
titleNext
typestandard
urlhttps://confluence.ecmwf.int/display/ECFLOW/Add+a+Cron

Sometimes you want a task to run at a given time, or to run every three hours,
or to run only on the first of the month, or on Mondays,...
For that ecFlow supports date and time dependencies.

time

time dependencies can be absolute, i.e. they will run at the exact time.
They can also be relative; in this case we provide the time from the moment the suite is begun.
Time dependencies can be repeated at regular intervals.  The nodes stays complete once all time instances have run.

Code Block
time 23:00                  # at next 23:00
time 10:00 20:00 01:00      # every hour from 10am to 8pm
time +00:01                 # one minute after the suite has begun, or 1 minute after re-queue in a presence of a repeat
time +00:10 01:00 00:05     # 10 to 60 minutes after begin every 5 minutes

In the last example we have task that runs every five minutes, however what happens if the task takes longer ? 

When this happens, the time slot, is missed.

cron

Cron dependencies can be specified using the cron keyword.  Cron differs from time as when the node is complete it queues again immediately.  Cron also only works with a real time clock (not a hybrid clock).

Code Block
cron 23:00                 # every day at 23:00
cron 08:00 12:00 01:00     # every hour between 8 and 12
cron -w 0,2    11:00       # every sunday and tuesday at 11 am
cron -d 1,15   02:00       # every 1st and 15th of each month at 2 am
cron -m 1 -d 1 14:00       # every first of January at 2 pm
cron -w 5L 23:00           # run on *last* Friday(5L) of each month at 23pm
cron -d 1,L  23:00         # Run on the first and last of the month at 23pm
Info
titleTime,Today,Cron

When a time has expired, the associated node is free to run. The time will stay expired, until the node is re-queued.

date or day

...


In this section we show an alternative to time-based attributes, using time triggers.

The following suite based generated variables are available for time-based triggers.

(In ecflow_ui, select a suite, then look at the variables tab)

  • DD              day of the month
  • DOW           day of the week, 0-6, where 0 is Sunday
  • DOY            day of the year
  • ECF_DATE  YYYYMMDD   year, month, day format. This has the same format as repeat date. 
  • MM             month 01-12
  • TIME           HHMM
  • YYYY          year

These time-based variables on the suite, use the suites calendar. The suites calendar can be configured with the clock attribute.

Here are examples of time attributes and the corresponding trigger examples

Code Block
time 23:00    
Code Block
date 31.12.2012             # the 31st of December 2012
date 01.*.*                 # every first of the month
date *.10.*                 # every day in October
date 1.*.2008               # every first of the month, but only in 2008
day monday                  # every monday

Mixing time dependencies on the same node

A task can have several time and date dependencies.   For example:

Code Block
task tt
   day monday   # Here Day/date acts like a guard over the time. i.e. time is not considered until Monday
   time 10:00   # run on Monday at 10 am
Code Block
task tt
   day sunday                  # Ontrigger the:TIME same node, Day/date act like a guard over the time attributes.
   day wednesday
   date 01== 2300
date 1.*.*                  # Thetrigger first:DD of every month and year
   date 10.*.* == 1
day monday                   # The tenth of every month and year
   time 01:00                  # The time is only set free *if* we are on one of the day/dates
   time 16:00

The task will run on Sunday’s and Wednesday’s at 1am and 4pm, but only if the day is the 1st or the 10th of the month.

Info

With multiple time dependencies on the same node, the dependencies of the same type are or'ed together, then and'ed with the different types.

Mixing time dependencies on different nodes

When time dependencies are placed on different nodes in the hierarchy, the results may seem surprising. Notice the difference between ecflow 4 and ecflow 5

Code Block
titleecflow 4
family fam
   day monday    # The day attribute no longer guards the time attribute.
   task tt
      time 10:00 # runs on Monday morning at 00:00 ?, and Monday at 10 am 
Code Block
titleecflow 5
family fam
   day monday    # The day STILL guards the time attribute.
   task tt
      time 10:00 # Will run on Monday at 10 am 
trigger :DOW == 1

The ':' means a search for the variable up the node tree.

Triggers can also use AND/OR logic and the full range of operators <,>,<=,>=


Code Block
languagebash
titleTime attributes
task t1
    day monday
    time 13:00



Code Block
languagebash
titletime based trigger
 task t1
    trigger :DOW == 1 and :TIME >= 1300



Code Block
languagebash
titlecombination
task t1
  day monday
  trigger :TIME >= 1300



Warning

It should be noted that relative time( time +00:01) are not possible with time-based triggers, and time series are more problematic.


Text


Let us modify the previous definition file for family f2.
For brevity,

Code Block
family fam2
   time 10:00
   task tt
       day monday # This will run on Monday morning at 00:00 and Monday at 10 am

The example above assumes we have suite, with an infinite repeat loop. So why does the task run on Monday morning at  00:00 ?

This is because time dependencies on different nodes act independently of each other.  In this case time attribute was set free on Sunday at 10 am ( and once free it stays free until it is re-queued).  Hence task tt is free to run on Monday  morning. After task has run and re-queued. It will then run on Monday at 10 am.

...

Note

All time related dependencies(like cron, time, today, date and day) are relative to the clock of the suite.

For more information, see Dates and Clocks

Text

Let us modify the definition file to add a family f2.
For brevity we have omitted the previous family f1


Code Block
# Definition of the suite test
suite test
 edit ECF_INCLUDE "$HOME/course"  # replace '$HOME' with the path to your home directory
 edit ECF_HOME    "$HOME/course"

 family f2
     edit SLEEP 20
     task t1
        trigger time 00:30 23:30 00:30  # start(hh:mm) end(hh:mm) increment(hh:mm):ECF_DATE ==20200720 and :TIME >= 1000
     task t2
         daytrigger thursday
:DOW == 4 and :TIME >=   1300 time 13:00
     task t3
         date 1.*.*              # Date(day,month,year) - * means every day,month,year
         time 12:00              # Time is not considered until date is freetrigger :DD == 1 and :TIME >= 1200
     task t4
         timetrigger +00(:02.DOW == 1 and :TIME >= 1300) or (:DOW == 5 and #:TIME + means realative to suite begin/requeue time>= 1000) 
     task t5
         timetrigger 00:02:TIME == 0002              # 2 minutes past midnight
 endfamily
endsuite


Python

For brevity, we have left out family f1. In python this would be:

Code Block
languagepy
title$HOME/course/test.py
import os
from ecflow import Defs,Suite,Family,Task,Edit,Trigger,Complete,Event,Meter,Time,Day,Date,Edit

def create_family_f2():
    return Family("f2",
            Edit(SLEEP=20),
            Task("t1", TimeTrigger("00:30 23:30 00:30:ECF_DATE ==20200720 and :TIME >= 1000")),     # start(hh:mm) end(hh:mm) increment(hh:mm)
            Task("t2", Day("thursday"),Time("13:00Trigger(":DOW == 4 and :TIME >= 1300")),
            Task("t3", DateTrigger("1.*.*"), Time("12:00:DD == 1 and :TIME >= 1200")),  # Date(day,month,year) - * means every day,month,year
            Task("t4", TimeTrigger("+00:02")),        (:DOW == 1 and :TIME >= 1300) or (:DOW == 5 and :TIME >= 1000)")),          # + means realative to suite begin/requeue time
            Task("t5", TimeTrigger("00:02:TIME == 0002")))                 # 2 minutes past midnight
 
print("Creating suite definition")  
home = os.path.join(os.getenv("HOME"), "course")
defs = Defs( 
        Suite("test",
            Edit(ECF_INCLUDE=home,ECF_HOME=home),
            create_family_f2()
            ))
print(defs) 

print("Checking job creation: .ecf -> .job0")  
print(defs.check_job_creation())

print("Checking trigger expressions")
errors = defs.check()
assert len(errors) == 0,errors

print("Saving definition to file 'test.def'")
defs.save_as_defs("test.def")

What to do

  1. Make the changes to the suite definition fileCreate all the necessary ecf script‘s by copying the one from /test/f1/t7
  2. Replace the suite
    python:  python3 test.py; python3 client.py
    text:       ecflow_client --suspend=/test  ;  ecflow_client --replace=/test  test.def
  3. ecflow_ui  has a special window to explain why a task is queued. Select a queued task and click on the 'Why tab'
  4. Vary the time attributes triggers so that all task runs


Horizontal Navigation Bar


Button Group

Button Hyperlink
titlePrevious
typestandard
urlhttps://confluence.ecmwf.int/display/ECFLOW/Time+Dependencies
Button Hyperlink
titleUp
typestandard
urlhttps://softwareconfluence.ecmwf.int/wiki/display/ECFLOW/Going+Further
Button Hyperlink
titleNext
typestandard
urlhttps://confluence.ecmwf.int/display/ECFLOW/Add+a+Cron



Code Block