/
islandora_job.drush.inc
125 lines (116 loc) · 4.4 KB
/
islandora_job.drush.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
/**
* @file
* Drush commands for the islandora_job module.
*/
/**
* Implements hook_drush_command().
*/
function islandora_job_drush_command() {
$items = array();
$items['islandora-job-router'] = array(
'description' => t('Job routing function for Islandora that is executed by the worker processes. There is no need to ever execute this yourself.'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
);
$items['islandora-job-list-functions'] = array(
'description' => t('Lists all job functions.'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
'options' => array(
'param_format' => array(
'description' => t('Flag to format as gearman server params, prefixed by "-f". Functions are otherwise newline-separated.'),
'required' => FALSE,
),
),
);
return $items;
}
/**
* Routes a payload received from Gearman to the appropriate job function.
*
* Reads STDIN for JSON containing the function to execute, the module it comes
* from, and the arguments to supply it.
*/
function drush_islandora_job_router() {
// XXX: Due to how Drush bootstrapping works, the connection may be created
// without credentials (when your site's front page is
// 'islandora/object/some:object', for example). Resetting to ensure a new
// connection gets created should fix it.
module_load_include('inc', 'islandora_job', 'includes/db');
module_load_include('inc', 'islandora_job', 'includes/utilities');
drupal_static_reset('islandora_get_tuque_connection');
// Parse the payload into an associative array.
$raw_payload = stream_get_contents(STDIN);
$payload = json_decode($raw_payload, TRUE);
// Get the list of all available jobs.
$job_registry = module_invoke_all("islandora_job_register_jobs");
$func_name = islandora_job_get_full_func_name($payload['func']);
$args = $payload['args'];
// Dynamically execute the job function, if it's in the list.
// Echo out the results so there's a return value for foreground jobs.
if (isset($job_registry[$func_name])) {
$job = $job_registry[$func_name];
$type = $job['type'];
$module = $job['module'];
$name = isset($job['name']) ? $job['name'] : NULL;
$status_id = islandora_job_start_job_status($raw_payload);
register_shutdown_function('islandora_job_router_job_error', $status_id, $func_name, $args);
module_load_include($type, $module, $name);
try {
$return = call_user_func_array($func_name, $args);
islandora_job_remove_job_status($status_id);
echo $return;
}
catch (Exception $e) {
drush_set_error('islandora_job', dt('The callback !func_name with args !args threw an exception.', array(
'!func_name' => $func_name,
'!args' => implode(', ', $args),
)));
islandora_job_update_job_status($status_id, ISLANDORA_JOB_STATE__ERROR);
throw $e;
}
}
}
/**
* Prints a list of multisite-aware job names out to the command line.
*/
function drush_islandora_job_list_functions() {
module_load_include('inc', 'islandora_job', 'includes/utilities');
$format = drush_get_option('param_format', FALSE);
$functions = array_map('islandora_job_function_name', islandora_job_get_aliased_function_names());
$imploder = $format ? ' ' : "\n";
if ($format) {
$add_prefix = function (&$function) {
$function = "-f $function";
};
array_walk($functions, $add_prefix);
}
drush_print(implode($imploder, $functions));
}
/**
* Shutdown callback to update job status in the event of an error.
*
* @param int $status_id
* The status ID of the job to be updated.
* @param string $name
* The name of the job.
* @param array $args
* The arguments that were passed to the job.
*/
function islandora_job_router_job_error($status_id, $name, array $args) {
$error = error_get_last();
$applicable_errors = array(
E_ERROR,
E_PARSE,
E_RECOVERABLE_ERROR,
);
if ($error != NULL && in_array($error['type'], $applicable_errors)) {
drush_set_error('islandora_job', dt('The callback !func_name with args !args threw an exception: !exception in !file on line !line.', array(
'!func_name' => $name,
'!args' => implode(', ', $args),
'!exception' => isset($error['message']) ? $error['message'] : '',
'!file' => isset($error['file']) ? $error['file'] : '',
'!line' => isset($error['line']) ? $error['line'] : '',
)));
islandora_job_update_job_status($status_id, ISLANDORA_JOB_STATE__ERROR);
}
}