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

feat: Add notification pathway for aborted flows #875

Merged
merged 1 commit into from
Mar 4, 2024
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
1 change: 1 addition & 0 deletions classes/dataflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ protected static function define_properties(): array {
'timemodified' => ['type' => PARAM_INT, 'default' => 0],
'usermodified' => ['type' => PARAM_INT, 'default' => 0],
'confighash' => ['type' => PARAM_TEXT, 'default' => ''],
'notifyonabort' => ['type' => PARAM_TEXT, 'default' => '']
];
}

Expand Down
3 changes: 3 additions & 0 deletions classes/form/dataflow_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ public function definition() {
$select->setMultiple(true);
$mform->addElement('static', 'log_handlers_desc', '', get_string('log_handlers_desc', 'tool_dataflows'));

$mform->addElement('text', 'notifyonabort', get_string('notifyonabort', 'tool_dataflows'));
$mform->addElement('static', 'notifyonabort_desc', '', get_string('notifyonabort_desc', 'tool_dataflows'));

$this->add_action_buttons();
}

Expand Down
45 changes: 45 additions & 0 deletions classes/local/execution/engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ public function initialise() {
$error = error_get_last();
$this->logger->log(Logger::ERROR, 'Engine: shutdown happened abruptly', ['lasterror' => $error]);
$this->set_status(self::STATUS_ABORTED);

$notifyreason = new \Exception('Shutdown handler triggered abort. Last error: ' . $error);
$this->notify_on_abort($notifyreason);

$this->run->finalise($this->status, $this->export());
}
});
Expand Down Expand Up @@ -585,6 +589,9 @@ public function abort(?\Throwable $reason = null) {
$this->set_status(self::STATUS_ABORTED);
$this->release_lock();

// If configured to send email, attempt to notify of the abort reason.
$this->notify_on_abort($reason);

// TODO: We may want to make this the responsibility of the caller.
if (isset($reason)) {
throw $reason;
Expand Down Expand Up @@ -845,4 +852,42 @@ private function setup_logging() {

$this->logger = $log;
}

/**
* Send a notification email for abort if required.
*
* @param \Throwable $reason A throwable representing the reason for abort.
*/
public function notify_on_abort(?\Throwable $reason) {
// If configured to send email, attempt to notify of the abort reason.
$notifyemail = $this->dataflow->get('notifyonabort');
if (empty($notifyemail)) {
return;
}

$this->log('Sending abort notification email.', [], Logger::NOTICE);
$context = [
'flowname' => $this->dataflow->get('name'),
'run' => $this->run->get('id'),
'reason' => isset($reason) ? $reason->getMessage() : ''
];
$message = get_string('notifyonabort_message', 'tool_dataflows', $context);

// First try to match the email with a Moodle user.
$to = \core_user::get_user_by_email($notifyemail);

// Otherwise send it with a dummy account.
if (!$to) {
$to = \core_user::get_noreply_user();
$to->email = $notifyemail;
$to->firstname = $this->dataflow->get('name');
$to->emailstop = 0;
$to->maildisplay = true;
$to->mailformat = 1;
}
$from = \core_user::get_noreply_user();
$subject = get_string('notifyonabort_subject', 'tool_dataflows', $this->dataflow->get('name'));

email_to_user($to, $from, $subject, $message);
}
}
1 change: 1 addition & 0 deletions db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="The time this record was modified."/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Who last modified this record?"/>
<FIELD NAME="confighash" TYPE="char" LENGTH="40" NOTNULL="false" SEQUENCE="false" COMMENT="The config hash of the most recent run"/>
<FIELD NAME="notifyonabort" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="Email address to notify aborted runs to."/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
Expand Down
15 changes: 15 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,21 @@ function xmldb_tool_dataflows_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2023122201, 'tool', 'dataflows');
}

if ($oldversion < 2024030200) {

// Define field loghandlers to be added to tool_dataflows.
$table = new xmldb_table('tool_dataflows');
$field = new xmldb_field('notifyonabort', XMLDB_TYPE_CHAR, '255', null, null, null, '', 'confighash');

// Conditionally launch add field loghandlers.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Dataflows savepoint reached.
upgrade_plugin_savepoint(true, 2024030200, 'tool', 'dataflows');
}

return true;
}

Expand Down
8 changes: 8 additions & 0 deletions lang/en/tool_dataflows.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@
Example:{$a->example} Note: If you use \'[dataroot]\', make sure to quote the value or it will be interpreted as an array.';
$string['error:vars_not_object'] = 'Vars must form a YAML object (Define each var as &lt;var&gt;: &lt;value&gt;)';
$string['error:invalid_yaml'] = 'Invalid YAML (Try quoting your value(s)): {$a}';
$string['notifyonabort'] = 'Notify on abort';
$string['notifyonabort_desc'] = 'Enter an email address to be notified on for dataflow aborts.';
$string['notifyonabort_message'] = 'The dataflow {$a->flowname} was aborted on run {$a->run}.

Reason: {$a->reason}

See the run logs for further details.';
$string['notifyonabort_subject'] = 'Dataflow run aborted: {$a}';

// Dataflow import form.
$string['dataflow_file'] = 'Dataflow file';
Expand Down
4 changes: 2 additions & 2 deletions version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2023122201;
$plugin->release = 2023122201;
$plugin->version = 2024030200;
$plugin->release = 2024030200;
$plugin->requires = 2022112800; // Our lowest supported Moodle (3.3.0).
$plugin->supported = [400, 402];
// TODO $plugin->incompatible = ; // Available as of Moodle 3.9.0 or later.
Expand Down
Loading