Add built-in support and API for exit codes in WorkChains#1640
Conversation
|
@muhrin and @greschd : let's discuss here about the API and the implementation details. I started implementing this in |
Codecov Report
@@ Coverage Diff @@
## develop #1640 +/- ##
===========================================
+ Coverage 57.1% 57.13% +0.03%
===========================================
Files 274 275 +1
Lines 33874 33911 +37
===========================================
+ Hits 19343 19376 +33
- Misses 14531 14535 +4
Continue to review full report at Codecov.
|
|
I am starting to rethink the nomenclature of not just My thinking is to use the more standard and general name "exit code", as used a lot in Linux. An exit code comes with an integer exit status and an optional exit message. I feel that using this nomenclature makes the interface more consistent. It would look something like this: # Named tuple to return from Processes, e.g. from WorkChain
ExitCode = collections.namedtuple('ExitCode', 'status message')
# Exception to exit from FunctionProcesses
class Exit(Exception):
def __init__(self, status, message):
self._status = status
self._message = message
# Attributes of the Calculation node
def exit_status(self):
def exit_message(self):
# Definition of exit code on ProcessSpec
ProcessSpec.exit_code(418, 'ERROR_I_AM_A_TEAPOT', 'the process found itself in an identity crisis') |
6eeb442 to
f3fa7cc
Compare
|
@sphuber Why is there a code, a string name for the exit status and the message. Do we really need the |
|
Concerning the integer exit code: What's the convention by which they are assigned? Is it the same as for Unix exit codes, or some other convention? I think it might make sense to encode this convention for example in an from enum import IntEnum
class ProcessExitCode(IntEnum):
SUCCESS = 0
ERROR_GENERIC = 1
ERROR_I_AM_A_TEAPOT = 418 |
|
To clarify: In general I like the use of a descriptive name instead of just an integer code because it is less cryptic when the error is created. However, this doesn't give you any benefit unless the descriptive name is in some way coupled to the integer code. |
|
@muhrin I added the label because I still want to be able to refer to the error code in the In the last line, where I am returning the exit code, I do not want to have to refer to it by the integer exit status. Imagine you have a more complex workchain with many exit codes, it is more difficult to understand what is going on if you see |
|
@greschd concerning the integer exit status convention, we use exactly that of Unix, i.e. 0 means success any non-zero positive integer means failure. Now for the Since we did not remove the |
f3fa7cc to
bc0daf8
Compare
|
After discussion with @muhrin the exit code collection is made callable to be able to retrieve a particular exit code from the I also updated the documentation to explain the exit code definition on the |
b3e8cbd to
5a18f02
Compare
Currently it is possible to return non-zero integers from a WorkChain outline step to abort its execution and assign the exit status to the node, however, there is no official API yet to make this easier. Here we define the concept of an ExitCode, a named tuple that takes an integer exit status and a descriptive message. Through the ProcessSpec, a WorkChain developer can add exit codes that correspond to errors that may crop up during the execution of the workchain. For example the following spec definition: @classmethod def define(cls, spec): super(CifCleanWorkChain, cls).define(spec) spec.exit_code(418, 'ERROR_I_AM_A_TEAPOT', message='workchain found itself in an identity crisis') In one of the outline steps, the exit code can be used by retrieving it through either the integer exit status or the string label: return self.exit_code('I_AM_A_TEAPOT') or return self.exit_code(418) and return it. Returning an instance of ExitCode will trigger the exact same mechanism as returning an integer from an outline step. The engine will detect the ExitCode and return its exit status as the result, triggering the abort and the exit status to be set on the Node. Note that this addition required name changes in parts of the existing API. For example the Calculation attribute `finish_status` was renamed to `exit_status`. This is because it can now be accompanied by an string `exit_message`. The `exit_status` and `exit_message` together form the `ExitCode`.
This allows one to both access any particular exit code from the
collection through attribute dereferencing:
self.exit_codes.ERROR_I_AM_A_TEAPOT
as well as through calling it with the string label or integer
status, given that the ExitCodeNamespace implements the call method
self.exit_codes(418)
self.exit_codes('ERROR_I_AM_A_TEAPOT')
5a18f02 to
13810f9
Compare
|
Alright @muhrin @greschd , she is all ready to go. Note that after a final discussion we replaced the method of raising the |
Fixes #1639
Add built-in support and API for exit codes in WorkChains
Currently it is possible to return non-zero integers from a WorkChain
outline step to abort its execution and assign the exit status to the
node, however, there is no official API yet to make this easier.
Here we define the concept of an ExitCode, a named tuple that takes
an integer exit status and a descriptive message. Through the
ProcessSpec, a WorkChain developer can add exit codes that correspond
to errors that may crop up during the execution of the workchain. For
example the following spec definition:
In one of the outline steps, the exit code can be used by retrieving
it through either the integer exit status or the string label:
or
and return it. Returning an instance of ExitCode will trigger the exact
same mechanism as returning an integer from an outline step. The engine
will detect the ExitCode and return its exit status as the result,
triggering the abort and the exit status to be set on the Node.
Note that this addition required name changes in parts of the existing
API. For example the Calculation attribute
finish_statuswas renamedto
exit_status. This is because it can now be accompanied by an stringexit_message. Theexit_statusandexit_messagetogether form theExitCode.