forked from vfremaux/moodle-local_vmoodle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvcron.php
157 lines (140 loc) · 5.64 KB
/
vcron.php
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file is a cron microclock script.
* It will be used as replacement of setting individual
* cron lines for all virtual instances.
*
* Setup this vcron to run at the smallest period possible, as
* it will schedule all availables vmoodle to be run as required.
* Note that one activaton of this cron may not always run real crons
* or may be run more than one cron.
*
* If used on a big system with clustering, ensure hostnames are adressed
* at the load balancer entry and not on physical hosts
*
* @package local_vmoodle
* @category local
* @author Valery fremaux ([email protected])
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
*/
require('../../config.php');
define('ROUND_ROBIN', 0);
define('LOWEST_POSSIBLE_GAP', 1);
global $VCRON;
$VCRON = new StdClass;
$VCRON->ACTIVATION = 'cli'; // Choose how individual cron are launched (cli or curl)
$VCRON->STRATEGY = ROUND_ROBIN ; // Choose vcron rotation mode
$VCRON->PERIOD = 15 * MINSECS ; // Used if LOWEST_POSSIBLE_GAP to setup the max gap
$VCRON->TIMEOUT = 300; // Time out for CURL call to effective cron
$VCRON->TRACE = $CFG->dataroot.'/vcrontrace.log'; // Trace file where to collect cron outputs
$VCRON->TRACE_ENABLE = false; // Enables tracing
/**
* fire a cron URL using CURL.
*
*
*/
function fire_vhost_cron($vhost) {
global $VCRON, $DB;
if ($VCRON->TRACE_ENABLE) {
$CRONTRACE = fopen($VCRON->TRACE, 'a');
}
$ch = curl_init($vhost->vhostname.'/admin/cron.php');
curl_setopt($ch, CURLOPT_TIMEOUT, $VCRON->TIMEOUT);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Moodle');
curl_setopt($ch, CURLOPT_POSTFIELDS, '');
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8"));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$timestamp_send = time();
$rawresponse = curl_exec($ch);
$timestamp_receive = time();
if ($rawresponse === false) {
$error = curl_errno($ch) .':'. curl_error($ch);
if ($VCRON->TRACE_ENABLE) {
if ($CRONTRACE) {
fputs($CRONTRACE, "VCron start on $vhost->vhostname : $timestamp_send\n" );
fputs($CRONTRACE, "VCron Error : $error \n");
fputs($CRONTRACE, "VCron stop on $vhost->vhostname : $timestamp_receive\n#################\n\n" );
fclose($CRONTRACE);
}
}
mtrace("VCron started on $vhost->vhostname : $timestamp_send\n" );
mtrace("VCron Error : $error \n");
mtrace("VCron stop on $vhost->vhostname : $timestamp_receive\n#################\n\n" );
return false;
}
if ($VCRON->TRACE_ENABLE) {
if ($CRONTRACE) {
fputs($CRONTRACE, "VCron start on $vhost->vhostname : $timestamp_send\n" );
fputs($CRONTRACE, $rawresponse."\n");
fputs($CRONTRACE, "VCron stop on $vhost->vhostname : $timestamp_receive\n#################\n\n" );
fclose($CRONTRACE);
}
}
mtrace("VCron start on $vhost->vhostname : $timestamp_send\n" );
mtrace($rawresponse."\n");
mtrace("VCron stop on $vhost->vhostname : $timestamp_receive\n#################\n\n" );
$vhost->lastcrongap = time() - $vhost->lastcron;
$vhost->lastcron = $timestamp_send;
$vhost->croncount++;
$DB->update_record('local_vmoodle', $vhost);
}
if (!$vmoodles = $DB->get_records('local_vmoodle', array('enabled' => 1))) {
die("Nothing to do. No Vhosts");
}
$allvhosts = array_values($vmoodles);
mtrace("<pre>");
mtrace("Moodle VCron... start");
mtrace("Last croned : ".@$CFG->vmoodle_cron_lasthost);
if ($VCRON->STRATEGY == ROUND_ROBIN){
$rr = 0;
foreach ($allvhosts as $vhost) {
if ($rr == 1) {
set_config('vmoodle_cron_lasthost', $vhost->id);
mtrace("Round Robin : ".$vhost->vhostname);
fire_vhost_cron($vhost);
die('Done.');
}
if ($vhost->id == @$CFG->vmoodle_cron_lasthost) {
$rr = 1; // take next one
}
}
// we were at last. Loop back and take first
set_config('vmoodle_cron_lasthost', $allvhosts[0]->id);
mtrace("Round Robin : ".$vhost->vhostname);
fire_vhost_cron($allvhosts[0]);
} elseif ($VCRON->STRATEGY == LOWEST_POSSIBLE_GAP) {
// first make measurement of cron period
if (empty($CFG->vcrontickperiod)) {
set_config('vcrontime', time());
return;
}
set_config('vcrontickperiod', time() - $CFG->vcrontime);
$hostsperturn = max(1, $VCRON->PERIOD / $CFG->vcrontickperiod * count($allvhosts));
$i = 0;
foreach ($allvhosts as $vhost) {
if ((time() - $vhost->lastcron) > $VCRON->PERIOD) {
fire_vhost_cron($vhost);
$i++;
if ($i >= $hostsperturn) {
return;
}
}
}
}