Skip to content

Commit

Permalink
Deprecated message trigger placeholders.
Browse files Browse the repository at this point in the history
  • Loading branch information
hjoliver committed Mar 14, 2016
1 parent 70a3fc4 commit d31f135
Show file tree
Hide file tree
Showing 16 changed files with 114 additions and 123 deletions.
23 changes: 6 additions & 17 deletions doc/cug.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3348,23 +3348,12 @@ \subsubsection{Trigger Types}
\paragraph{Message Triggers}
\label{MessageTriggers}

Message triggers allow triggering off custom messages emitted by a task as it
runs. {\em Message outputs} must be registered for the task in the suite
definition, and matching messages sent back to the suite daemon by the
task at the appropriate time. {\em Note that polling does not yet detect custom
message output completion.} Custom output messages should normally contain the
cycle point in order to
distinguish between the outputs of different instances of the same task.
The task implementation can use \lstinline=$CYLC_TASK_CYCLE_POINT= for
this, or \lstinline@cylc cycle-point --offset=P2M@ for an offset value.
The matching message string registered in the suite definition, however, does
not get interpreted by the shell, so a cycle point placeholder is used instead:
\lstinline=[]= for the current cycle point, or for an offset \lstinline=[-P2M]=.

The \lstinline=$CYLC_DIR/examples/message-triggers/= suite is a self-contained
example that illustrates message triggering. Note that the graph trigger
notation uses a label that selects the message registered under the task
\lstinline=[runtime]= section.
Tasks can also trigger off custom output messages. These must be registered in
the \lstinline=[runtime]= section of the emitting task, and reported using the
\lstinline=cylc message= command in task scripting. The graph trigger notation
refers to the item name of the registered output message.
The example suite \lstinline=$CYLC_DIR/examples/message-triggers= illustrates
message triggering.

\lstset{language=suiterc}
\lstinputlisting{../examples/message-triggers/suite.rc}
Expand Down
17 changes: 7 additions & 10 deletions doc/suiterc.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1706,26 +1706,23 @@ \subsection{[runtime]}

\paragraph[{[[[}outputs{]]]}]{[runtime] \textrightarrow [[\_\_NAME\_\_]] \textrightarrow [[[outputs]]]}

This section is for registering custom message outputs that other tasks can
trigger off instead of the standard triggers. The task implementation must send
corresponding messages using the \lstinline=cylc task message= command at the
appropriate time. See~\ref{MessageTriggers} for more information.
Register custom task outputs for use in message triggering in this section
(\ref{MessageTriggers})

\subparagraph[\_\_OUTPUT\_\_ ]{[runtime] \textrightarrow [[\_\_NAME\_\_]] \textrightarrow [[[outputs]]] \textrightarrow \_\_OUTPUT\_\_}

Replace \_\_OUTPUT\_\_ with one or more labelled output messages, and use the
labels in graph trigger notation. Messages should contain a placeholder for
the current cycle point (\lstinline=[]=) or some offset from it (e.g.\ \lstinline=[-P2M]=).
Replace \_\_OUTPUT\_\_ with one or more custom task output messages
(\ref{MessageTriggers}). The item name is used to select the custom output
message in graph trigger notation.
\begin{myitemize}
\item {\em type:} string
\item {\em default:} (none)
\item{ \em examples:}
\end{myitemize}
\begin{lstlisting}
foo = "sea state products ready for []"
bar = "nwp restart files ready for [-PT6H]"
out1 = "sea state products ready"
out2 = "NWP restart files completed"
\end{lstlisting}
See~\ref{MessageTriggers} for more information.

\paragraph[{[[[}suite state polling{]]]}]{[runtime] \textrightarrow [[\_\_NAME\_\_]] \textrightarrow [[[suite state polling]]]}

Expand Down
27 changes: 11 additions & 16 deletions examples/message-triggers/suite.rc
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,18 @@ title = "test suite for cylc-6 message triggers"
final cycle point = 20141201T00
[[dependencies]]
[[[P2M]]]
graph = """
# bar triggers off message 'x' emitted by foo:
foo:x => bar
# baz triggers off message 'y' emitted by the previous instance of foo:
foo[-P2M]:y => baz
"""
graph = """foo:out1 => bar
foo[-P2M]:out2 => baz"""
[runtime]
[[foo]]
script = """
echo HELLO
sleep 2
TARGET_POINT=$CYLC_TASK_CYCLE_POINT
cylc message "file 1 for $TARGET_POINT done"
sleep 2
TARGET_POINT=$(cylc cycle-point --offset P2M)
cylc message "file 2 for $TARGET_POINT done"
sleep 2"""
sleep 5
cylc message "file 1 done"
sleep 10
cylc message "file 2 done"
sleep 10"""
[[[outputs]]]
x = "file 1 for [] done"
y = "file 2 for [P2M] done"
out1 = "file 1 done"
out2 = "file 2 done"
[[bar, baz]]
script = sleep 10
9 changes: 0 additions & 9 deletions lib/cylc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1699,15 +1699,6 @@ def generate_taskdefs(self, line, left_nodes, right, section, seq,
# Record message outputs.
for lbl, msg in self.cfg['runtime'][name]['outputs'].items():
outp = output(msg, base_interval)
# Check for a cycle offset placeholder.
# TODO - DEPRECATE OUTPUT OFFSET PLACEHOLDERS
if not re.search(r'\[[^\]]*\]', msg):
print >> sys.stderr, (
"Message outputs require an "
"offset placeholder (e.g. '[]' or '[-P2M]'):")
print >> sys.stderr, " %s = %s" % (lbl, msg)
raise SuiteConfigError(
'ERROR: bad message output string')
if outp not in self.taskdefs[name].outputs:
self.taskdefs[name].outputs.append(outp)

Expand Down
23 changes: 2 additions & 21 deletions lib/cylc/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import re
from cycling.loader import get_interval, get_interval_cls
from trigger import BACK_COMPAT_MSG_RE, MSG_RE
from trigger import get_message_offset


class output(object):
Expand All @@ -33,27 +33,8 @@ class output(object):
"""

def __init__(self, msg, base_interval=None):
self.msg_offset = None
self.msg = msg
m = re.match(BACK_COMPAT_MSG_RE, self.msg)
if m:
# Old-style offset
prefix, signed_offset, sign, offset, suffix = m.groups()
if signed_offset is not None:
self.msg_offset = base_interval.get_inferred_child(
signed_offset)
else:
n = re.match(MSG_RE, msg)
if n:
# New-style offset
prefix, signed_offset, sign, offset, suffix = n.groups()
if offset:
self.msg_offset = get_interval(signed_offset)
else:
self.msg_offset = get_interval_cls().get_null()
else:
# Plain message, no offset.
pass
self.msg_offset = get_message_offset(msg, base_interval)

def get(self, point):
new_point = point
Expand Down
77 changes: 44 additions & 33 deletions lib/cylc/trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,51 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import re
import sys

from cylc.task_id import TaskID
from cylc.cycling.loader import (
get_interval, get_interval_cls, get_point_relative)
from cylc.task_state import TaskState, TaskStateError


BACK_COMPAT_MSG_RE = re.compile('^(.*)\[\s*T\s*(([+-])\s*(\d+))?\s*\](.*)$')
MSG_RE = re.compile('^(.*)\[\s*(([+-])?\s*(.*))?\s*\](.*)$')
warned = False


def get_message_offset(msg, base_interval=None):
"""Return back-compat message offset, or None."""

BACK_COMPAT_MSG_RE_OLD = re.compile('^(.*)\[\s*T\s*(([+-])\s*(\d+))?\s*\](.*)$')
BACK_COMPAT_MSG_RE = re.compile('^(.*)\[\s*(([+-])?\s*(.*))?\s*\](.*)$')
DEPRECATION_TEMPLATE = "WARNING: message trigger offsets are deprecated\n %s"

offset = None
global warned

# cylc-5 [T+n] message offset - DEPRECATED
m = re.match(BACK_COMPAT_MSG_RE_OLD, msg)
if m:
if not warned:
print >> sys.stderr, DEPRECATION_TEMPLATE % msg
warned = True
prefix, signed_offset, sign, offset, suffix = m.groups()
if signed_offset is not None:
offset = base_interval.get_inferred_child(
signed_offset)
else:
# cylc-6 [<interval>] message offset - DEPRECATED
n = re.match(BACK_COMPAT_MSG_RE, msg)
if n:
if not warned:
print >> sys.stderr, DEPRECATION_TEMPLATE % msg
warned = True
prefix, signed_offset, sign, offset, suffix = n.groups()
if offset:
offset = get_interval(signed_offset)
else:
offset = get_interval_cls().get_null()
# else: Plain message, no offset.
return offset


class TriggerError(Exception):
Expand All @@ -50,9 +86,9 @@ class trigger(object):
[runtime]
[[foo]]
[[[outputs]]]
x = "file X uploaded for [P1D]"
y = "file Y uploaded for []"
"""
x = "file X uploaded"
y = "file Y finished"
"""

def __init__(
self, task_name, qualifier=None, graph_offset_string=None,
Expand All @@ -78,39 +114,14 @@ def __init__(

# Message trigger?
try:
msg = outputs[qualifier]
self.message = outputs[qualifier]
except KeyError:
raise TriggerError(
"ERROR: undefined trigger qualifier: %s:%s" % (
task_name, qualifier))
else:
# Back compat for [T+n] in message string.
m = re.match(BACK_COMPAT_MSG_RE, msg)
msg_offset = None
if m:
prefix, signed_offset, sign, offset, suffix = m.groups()
if offset:
msg_offset = base_interval.get_inferred_child(
signed_offset)
else:
msg_offset = get_interval_cls().get_null()
else:
n = re.match(MSG_RE, msg)
if n:
prefix, signed_offset, sign, offset, suffix = n.groups()
if offset:
msg_offset = get_interval(signed_offset)
else:
msg_offset = get_interval_cls().get_null()
else:
raise TriggerError(
"ERROR: undefined trigger qualifier: %s:%s" % (
task_name, qualifier))
self.message = msg
self.message_offset = msg_offset

def is_standard(self):
return self.builtin is not None
self.message_offset = get_message_offset(self.message,
base_interval)

def get_prereq(self, point):
"""Return a prerequisite string."""
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title = "test suite for pre cylc-6 message triggers"
title = "test suite for deprecated cylc-5 message triggers"

[cylc]
[[reference test]]
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
title = test suite for cylc-6 message triggers
title = test suite for deprecated cylc-6 message triggers
[cylc]
UTC mode = True
[[reference test]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#-------------------------------------------------------------------------------
# Test validation fails message outputs with no cycle offset placeholder.
# Test new-style simplified message triggers (see GitHub #1761)
. $(dirname $0)/test_header
#-------------------------------------------------------------------------------
set_test_number 2
#-------------------------------------------------------------------------------
install_suite $TEST_NAME_BASE $TEST_NAME_BASE
#-------------------------------------------------------------------------------
TEST_NAME=$TEST_NAME_BASE-validate
run_fail $TEST_NAME cylc validate $SUITE_NAME
grep_ok 'ERROR: bad message output string' $TEST_NAME.stderr
run_ok $TEST_NAME cylc validate $SUITE_NAME
#-------------------------------------------------------------------------------
TEST_NAME=$TEST_NAME_BASE-run
suite_run_ok $TEST_NAME cylc run --reference-test --debug $SUITE_NAME
#-------------------------------------------------------------------------------
purge_suite $SUITE_NAME
15 changes: 15 additions & 0 deletions tests/message-triggers/03-new-style/reference.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
2016-03-15T12:15:44+13 INFO - Suite starting on niwa-34403.niwa.local:7766
2016-03-15T12:15:44+13 INFO - Run mode: live
2016-03-15T12:15:44+13 INFO - Initial point: 20140801T0000+13
2016-03-15T12:15:44+13 INFO - Final point: 20141201T0000+13
2016-03-15T12:15:44+13 INFO - Cold Start 20140801T0000+13
2016-03-15T12:15:44+13 INFO - [baz.20140801T0000+13] -triggered off []
2016-03-15T12:15:44+13 INFO - [foo.20140801T0000+13] -triggered off []
2016-03-15T12:15:46+13 INFO - [foo.20141001T0000+13] -triggered off []
2016-03-15T12:15:48+13 INFO - [bar.20140801T0000+13] -triggered off ['foo.20140801T0000+13']
2016-03-15T12:15:49+13 INFO - [foo.20141201T0000+13] -triggered off []
2016-03-15T12:15:50+13 INFO - [baz.20141001T0000+13] -triggered off ['foo.20140801T0000+13']
2016-03-15T12:15:50+13 INFO - [bar.20141001T0000+13] -triggered off ['foo.20141001T0000+13']
2016-03-15T12:15:53+13 INFO - [baz.20141201T0000+13] -triggered off ['foo.20141001T0000+13']
2016-03-15T12:15:53+13 INFO - [bar.20141201T0000+13] -triggered off ['foo.20141201T0000+13']
2016-03-15T12:15:58+13 INFO - Suite shutting down at 2016-03-15T12:15:58+13
22 changes: 22 additions & 0 deletions tests/message-triggers/03-new-style/suite.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
title = "test suite for cylc-6 message triggers"

[scheduling]
initial cycle point = 20140801T00
final cycle point = 20141201T00
[[dependencies]]
[[[P2M]]]
graph = """foo:out1 => bar
foo[-P2M]:out2 => baz"""
[runtime]
[[foo]]
script = """
sleep 2
cylc message "file 1 done"
sleep 2
cylc message "file 2 done"
sleep 2"""
[[[outputs]]]
out1 = "file 1 done"
out2 = "file 2 done"
[[bar, baz]]
script = /bin/true
12 changes: 0 additions & 12 deletions tests/message-triggers/03-placeholder/suite.rc

This file was deleted.

0 comments on commit d31f135

Please sign in to comment.