File inc/cache.inc.php changed (mode: 100644) (index 3ecaf17..24c9dbf) |
5 |
5 |
require_once(__DIR__ . '/util.inc.php'); |
require_once(__DIR__ . '/util.inc.php'); |
6 |
6 |
require_once(__DIR__ . '/prof.inc.php'); |
require_once(__DIR__ . '/prof.inc.php'); |
7 |
7 |
|
|
|
8 |
|
define('RG_CACHE_LOCK_NO_WAIT', 0x02); // 'L' |
|
9 |
|
define('RG_CACHE_UNLOCK', 0x04); // 'U' |
|
10 |
|
define('RG_CACHE_DISABLE_TIMEOUT', 0x08); // 'T' |
|
11 |
|
|
8 |
12 |
// Client side can disable the cache for various reasons (unit testing etc.) |
// Client side can disable the cache for various reasons (unit testing etc.) |
9 |
13 |
if (!isset($rg_cache_enable)) |
if (!isset($rg_cache_enable)) |
10 |
14 |
$rg_cache_enable = TRUE; |
$rg_cache_enable = TRUE; |
|
... |
... |
function rg_cache_send($cmd, $para, $flags) |
381 |
385 |
|
|
382 |
386 |
$rg_cache_count++; |
$rg_cache_count++; |
383 |
387 |
|
|
|
388 |
|
$timeout = $rg_cache_timeout; |
|
389 |
|
|
384 |
390 |
$f = ''; |
$f = ''; |
385 |
391 |
if ($flags & RG_SOCKET_NO_WAIT) |
if ($flags & RG_SOCKET_NO_WAIT) |
386 |
392 |
$f .= 'W'; |
$f .= 'W'; |
|
393 |
|
if ($flags & RG_CACHE_LOCK_NO_WAIT) |
|
394 |
|
$f .= 'L'; |
|
395 |
|
if ($flags & RG_CACHE_UNLOCK) |
|
396 |
|
$f .= 'U'; |
|
397 |
|
if ($flags & RG_CACHE_DISABLE_TIMEOUT) |
|
398 |
|
$timeout = null; |
387 |
399 |
|
|
388 |
400 |
$xcmd = $cmd . ' F=' . $f . ' I=' . $rg_cache_count . ' ' . $para; |
$xcmd = $cmd . ' F=' . $f . ' I=' . $rg_cache_count . ' ' . $para; |
389 |
401 |
if ($rg_cache_debug) |
if ($rg_cache_debug) |
390 |
402 |
rg_log('Sending [' . $xcmd . ']...'); |
rg_log('Sending [' . $xcmd . ']...'); |
391 |
403 |
$ret = rg_socket($rg_cache_socket, $xcmd . "\n", |
$ret = rg_socket($rg_cache_socket, $xcmd . "\n", |
392 |
|
$rg_cache_timeout, $rg_cache_tries, $flags); |
|
|
404 |
|
$timeout, $rg_cache_tries, $flags); |
393 |
405 |
if ($ret === FALSE) { |
if ($ret === FALSE) { |
394 |
406 |
if ($rg_cache_debug) |
if ($rg_cache_debug) |
395 |
407 |
rg_log('Disabling cache check for 5s'); |
rg_log('Disabling cache check for 5s'); |
|
... |
... |
function rg_cache_set($ns_var, $value, $flags) |
483 |
495 |
|
|
484 |
496 |
rg_prof_start('cache_set'); |
rg_prof_start('cache_set'); |
485 |
497 |
|
|
486 |
|
while (1) { |
|
|
498 |
|
do { |
487 |
499 |
$k = rg_cache_prepare_key($ns_var); |
$k = rg_cache_prepare_key($ns_var); |
488 |
500 |
rg_cache_core_set($k, $value); |
rg_cache_core_set($k, $value); |
489 |
501 |
|
|
|
... |
... |
function rg_cache_set($ns_var, $value, $flags) |
496 |
508 |
rg_log('cache_set[' . $ns_var . '] = ' . rg_array2string($value)); |
rg_log('cache_set[' . $ns_var . '] = ' . rg_array2string($value)); |
497 |
509 |
|
|
498 |
510 |
$ret = TRUE; |
$ret = TRUE; |
499 |
|
break; |
|
500 |
|
} |
|
|
511 |
|
} while (0); |
501 |
512 |
|
|
502 |
513 |
rg_prof_end('cache_set'); |
rg_prof_end('cache_set'); |
503 |
514 |
return $ret; |
return $ret; |
|
... |
... |
function rg_cache_sleep() |
616 |
627 |
return TRUE; |
return TRUE; |
617 |
628 |
} |
} |
618 |
629 |
|
|
|
630 |
|
/* |
|
631 |
|
* Locks an node and if ok; returns the var if lock is not locked |
|
632 |
|
*/ |
|
633 |
|
function rg_cache_lock($ns_var, $flags) |
|
634 |
|
{ |
|
635 |
|
global $rg_cache_debug; |
|
636 |
|
|
|
637 |
|
rg_prof_start('cache_lock'); |
|
638 |
|
|
|
639 |
|
do { |
|
640 |
|
$k = rg_cache_prepare_key($ns_var); |
|
641 |
|
$ret = rg_cache_send('LOCK', $k, $flags | RG_CACHE_DISABLE_TIMEOUT); |
|
642 |
|
if ($ret === FALSE) |
|
643 |
|
break; |
|
644 |
|
|
|
645 |
|
$ret = rg_unserialize($ret); |
|
646 |
|
if ($ret === FALSE) { |
|
647 |
|
rg_cache_set_error('cannot unserialize answer: ' |
|
648 |
|
. rg_util_error()); |
|
649 |
|
break; |
|
650 |
|
} |
|
651 |
|
|
|
652 |
|
if ($rg_cache_debug) |
|
653 |
|
rg_log('cache_lock[' . $ns_var . '] returns: ' |
|
654 |
|
. ($ret === FALSE ? 'FALSE' : rg_array2string($ret))); |
|
655 |
|
|
|
656 |
|
rg_cache_core_set($ns_var, $ret); |
|
657 |
|
} while (0); |
|
658 |
|
|
|
659 |
|
rg_prof_end('cache_lock'); |
|
660 |
|
return $ret; |
|
661 |
|
} |
File scripts/cache.php changed (mode: 100644) (index e510a5f..8e76339) |
... |
... |
require_once("/etc/rocketgit/config.php"); |
16 |
16 |
$INC = dirname(__FILE__) . "/../inc"; |
$INC = dirname(__FILE__) . "/../inc"; |
17 |
17 |
require_once($INC . "/init.inc.php"); |
require_once($INC . "/init.inc.php"); |
18 |
18 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
19 |
|
require_once($INC . "/sql.inc.php"); |
|
20 |
|
require_once($INC . "/struct.inc.php"); |
|
21 |
19 |
require_once($INC . "/cache.inc.php"); |
require_once($INC . "/cache.inc.php"); |
22 |
|
require_once($INC . "/repo.inc.php"); |
|
23 |
20 |
require_once($INC . "/prof.inc.php"); |
require_once($INC . "/prof.inc.php"); |
24 |
|
require_once($INC . "/mr.inc.php"); |
|
25 |
|
require_once($INC . "/keys.inc.php"); |
|
26 |
|
require_once($INC . "/user.inc.php"); |
|
27 |
|
require_once($INC . "/bug.inc.php"); |
|
28 |
|
require_once($INC . "/fixes.inc.php"); |
|
29 |
21 |
require_once($INC . "/ver.php"); |
require_once($INC . "/ver.php"); |
30 |
22 |
|
|
31 |
|
function rg_destroy($k, &$conn_table) |
|
|
23 |
|
$rg_cache_locks = array(); |
|
24 |
|
|
|
25 |
|
function rg_wake_from_lock($k, $para1) |
32 |
26 |
{ |
{ |
33 |
|
rg_log_debug($k . ': Destroying'); |
|
34 |
|
if (isset($conn_table['r'][$k])) |
|
35 |
|
unset($conn_table['r'][$k]); |
|
36 |
|
if (isset($conn_table['w'][$k])) |
|
37 |
|
unset($conn_table['w'][$k]); |
|
|
27 |
|
global $rg_cache_conn_table; |
|
28 |
|
global $rg_cache_locks; |
|
29 |
|
|
|
30 |
|
rg_log_debug('wake_from_lock: k=' . $k . ' para1=' . $para1); |
|
31 |
|
|
|
32 |
|
while (1) { |
|
33 |
|
if (empty($rg_cache_locks[$para1]['wait'])) { |
|
34 |
|
//rg_log_debug($k . ': nobody to wake!'); |
|
35 |
|
unset($rg_cache_locks[$para1]); |
|
36 |
|
break; |
|
37 |
|
} |
|
38 |
|
|
|
39 |
|
rg_log_ml($k . ': before array_shift: ' . print_r($rg_cache_locks, TRUE)); |
|
40 |
|
$a = array_shift($rg_cache_locks[$para1]['wait']); |
|
41 |
|
$conn_id = $a['conn_id']; $cmd_id = $a['cmd_id']; |
|
42 |
|
if (!array_key_exists($conn_id, $rg_cache_conn_table['conns'])) { |
|
43 |
|
rg_log_debug($k . ': waiting client is gone: ' . $conn_id); |
|
44 |
|
continue; |
|
45 |
|
} |
|
46 |
|
|
|
47 |
|
rg_log_debug($k . ': waking ' . $conn_id); |
|
48 |
|
$rg_cache_locks[$para1]['who'] = $conn_id; |
|
49 |
|
$s2 = &$rg_cache_conn_table['conns'][$conn_id]; |
|
50 |
|
$ret = rg_cache_core_get("normal::" . $para1); |
|
51 |
|
if ($ret === FALSE) |
|
52 |
|
$buf2 = 'ER ' . $cmd_id . ' NOT_FOUND' . "\n"; |
|
53 |
|
else |
|
54 |
|
$buf2 = 'OK ' . $cmd_id . ' ' . rg_cache_prepare($ret) . "\n"; |
|
55 |
|
$s2['send'] .= $buf2; |
|
56 |
|
$rg_cache_conn_table['w'][$conn_id] = $s2['socket']; |
|
57 |
|
break; |
|
58 |
|
} |
|
59 |
|
} |
|
60 |
|
|
|
61 |
|
function rg_destroy($k) |
|
62 |
|
{ |
|
63 |
|
global $rg_cache_conn_table; |
|
64 |
|
global $rg_cache_locks; |
|
65 |
|
|
|
66 |
|
rg_log_debug($k . ': Destroying...'); |
|
67 |
|
if (isset($rg_cache_conn_table['r'][$k])) |
|
68 |
|
unset($rg_cache_conn_table['r'][$k]); |
|
69 |
|
if (isset($rg_cache_conn_table['w'][$k])) |
|
70 |
|
unset($rg_cache_conn_table['w'][$k]); |
38 |
71 |
// TODO: seems socket is already closed |
// TODO: seems socket is already closed |
39 |
|
if (isset($conn_table['conns'][$k]['socket'])) |
|
40 |
|
if (is_resource($conn_table['conns'][$k]['socket']) |
|
41 |
|
|| is_object($conn_table['conns'][$k]['socket'])) |
|
42 |
|
socket_close($conn_table['conns'][$k]['socket']); |
|
43 |
|
unset($conn_table['conns'][$k]); |
|
|
72 |
|
if (isset($rg_cache_conn_table['conns'][$k]['socket'])) |
|
73 |
|
if (is_resource($rg_cache_conn_table['conns'][$k]['socket']) |
|
74 |
|
|| is_object($rg_cache_conn_table['conns'][$k]['socket'])) |
|
75 |
|
socket_close($rg_cache_conn_table['conns'][$k]['socket']); |
|
76 |
|
unset($rg_cache_conn_table['conns'][$k]); |
|
77 |
|
|
|
78 |
|
foreach ($rg_cache_locks as $para1 => $i) { |
|
79 |
|
if ($i['who'] != $k) |
|
80 |
|
continue; |
|
81 |
|
|
|
82 |
|
rg_wake_from_lock($k, $para1); |
|
83 |
|
} |
44 |
84 |
} |
} |
45 |
85 |
|
|
46 |
|
function rg_handle_command($k, &$conn_table, $cmd) |
|
|
86 |
|
function rg_handle_command($k, $cmd) |
47 |
87 |
{ |
{ |
48 |
|
//rg_log_debug($k . ': handle_command: cmd=' . $cmd); |
|
|
88 |
|
global $rg_cache_conn_table; |
|
89 |
|
global $rg_cache_locks; |
49 |
90 |
|
|
50 |
|
$s = &$conn_table['conns'][$k]; |
|
|
91 |
|
rg_log_debug($k . ': handle_command: cmd=' . $cmd); |
|
92 |
|
|
|
93 |
|
$s = &$rg_cache_conn_table['conns'][$k]; |
51 |
94 |
|
|
52 |
95 |
$a = explode(' ', $cmd, 4); |
$a = explode(' ', $cmd, 4); |
53 |
96 |
$buf = "ER Invalid command\n"; |
$buf = "ER Invalid command\n"; |
54 |
97 |
$no_wait = FALSE; |
$no_wait = FALSE; |
|
98 |
|
$flags = ''; |
55 |
99 |
while (1) { |
while (1) { |
56 |
|
// We must have at least 2 parameters: cmd and flags and I |
|
|
100 |
|
// We must have at least 3 parameters: cmd and flags and 'I' |
57 |
101 |
if (!isset($a[2])) |
if (!isset($a[2])) |
58 |
102 |
break; |
break; |
59 |
103 |
|
|
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
70 |
114 |
|
|
71 |
115 |
$id = trim($a[2]); |
$id = trim($a[2]); |
72 |
116 |
if (strncmp($id, 'I=', 2) != 0) { |
if (strncmp($id, 'I=', 2) != 0) { |
73 |
|
rg_log($k . ': Invalid command (no id): $cmd'); |
|
|
117 |
|
rg_log($k . ': Invalid command (no id): ' . $cmd); |
74 |
118 |
break; |
break; |
75 |
119 |
} |
} |
76 |
120 |
$id = substr($id, 2); |
$id = substr($id, 2); |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
83 |
127 |
break; |
break; |
84 |
128 |
$para1 = trim($a[3]); |
$para1 = trim($a[3]); |
85 |
129 |
|
|
|
130 |
|
$ns_var = FALSE; |
|
131 |
|
|
86 |
132 |
if (strcmp($cmd, "SET") == 0) { |
if (strcmp($cmd, "SET") == 0) { |
87 |
133 |
$ns_var_value = explode("=", $para1, 2); |
$ns_var_value = explode("=", $para1, 2); |
88 |
134 |
if (!isset($ns_var_value[1])) |
if (!isset($ns_var_value[1])) |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
120 |
166 |
} |
} |
121 |
167 |
|
|
122 |
168 |
if (strcmp($cmd, "INC") == 0) { |
if (strcmp($cmd, "INC") == 0) { |
123 |
|
$v = rg_cache_core_inc("normal::" . $para1); |
|
|
169 |
|
$ns_var = $para1; |
|
170 |
|
$v = rg_cache_core_inc("normal::" . $ns_var); |
124 |
171 |
$buf = 'OK ' . $id . ' v=' . $v . "\n"; |
$buf = 'OK ' . $id . ' v=' . $v . "\n"; |
125 |
172 |
break; |
break; |
126 |
173 |
} |
} |
127 |
174 |
|
|
|
175 |
|
if (strcmp($cmd, 'LOCK') == 0) { |
|
176 |
|
// Check if an lock is already held |
|
177 |
|
if (!array_key_exists($para1, $rg_cache_locks)) |
|
178 |
|
$rg_cache_locks[$para1] = array('who' => $k, 'wait' => array()); |
|
179 |
|
|
|
180 |
|
if ($rg_cache_locks[$para1]['who'] != $k) { // lock is NOT held by "me" |
|
181 |
|
if (strstr($flags, 'L')) { // L = do not wait if lock is held |
|
182 |
|
$buf = 'ER ' . $id . ' LOCK_HELD' . "\n"; |
|
183 |
|
} else { |
|
184 |
|
rg_log_debug($k . ': added myself to wait queue'); |
|
185 |
|
$rg_cache_locks[$para1]['wait'][] = array('conn_id' => $k, 'cmd_id' => $id); |
|
186 |
|
$buf = ''; |
|
187 |
|
} |
|
188 |
|
} else { |
|
189 |
|
$ret = rg_cache_core_get("normal::" . $para1); |
|
190 |
|
if ($ret === FALSE) |
|
191 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
|
192 |
|
else |
|
193 |
|
$buf = 'OK ' . $id . ' ' . rg_cache_prepare($ret) . "\n"; |
|
194 |
|
} |
|
195 |
|
break; |
|
196 |
|
} |
|
197 |
|
|
128 |
198 |
if (strcmp($cmd, "GET") == 0) { |
if (strcmp($cmd, "GET") == 0) { |
129 |
|
$ret = rg_cache_core_get("normal::" . $para1); |
|
|
199 |
|
$ns_var = $para1; |
|
200 |
|
$ret = rg_cache_core_get("normal::" . $ns_var); |
130 |
201 |
if ($ret === FALSE) |
if ($ret === FALSE) |
131 |
202 |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
132 |
203 |
else |
else |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
135 |
206 |
} |
} |
136 |
207 |
|
|
137 |
208 |
if (strcmp($cmd, "UNSET") == 0) { |
if (strcmp($cmd, "UNSET") == 0) { |
138 |
|
$ret = rg_cache_core_unset("normal::" . $para1); |
|
|
209 |
|
$ns_var = $para1; |
|
210 |
|
$ret = rg_cache_core_unset("normal::" . $ns_var); |
139 |
211 |
if ($ret === FALSE) |
if ($ret === FALSE) |
140 |
212 |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
141 |
213 |
else |
else |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
144 |
216 |
} |
} |
145 |
217 |
|
|
146 |
218 |
if (strcmp($cmd, "ADUMP") == 0) { |
if (strcmp($cmd, "ADUMP") == 0) { |
147 |
|
$ret = rg_cache_core_adump("normal::" . $para1); |
|
|
219 |
|
$ns_var = $para1; |
|
220 |
|
$ret = rg_cache_core_adump("normal::" . $ns_var); |
148 |
221 |
if ($ret === FALSE) |
if ($ret === FALSE) |
149 |
222 |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
150 |
223 |
else |
else |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
169 |
242 |
} |
} |
170 |
243 |
|
|
171 |
244 |
if (strcmp($cmd, "APOP") == 0) { |
if (strcmp($cmd, "APOP") == 0) { |
172 |
|
$ret = rg_cache_core_apop("normal::" . $para1); |
|
|
245 |
|
$ns_var = $para1; |
|
246 |
|
$ret = rg_cache_core_apop("normal::" . $ns_var); |
173 |
247 |
if ($ret === FALSE) |
if ($ret === FALSE) |
174 |
248 |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
175 |
249 |
else |
else |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
178 |
252 |
} |
} |
179 |
253 |
|
|
180 |
254 |
if (strcmp($cmd, "ASHIFT") == 0) { |
if (strcmp($cmd, "ASHIFT") == 0) { |
181 |
|
$ret = rg_cache_core_ashift("normal::" . $para1); |
|
|
255 |
|
$ns_var = $para1; |
|
256 |
|
$ret = rg_cache_core_ashift("normal::" . $ns_var); |
182 |
257 |
if ($ret === FALSE) |
if ($ret === FALSE) |
183 |
258 |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
184 |
259 |
else |
else |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
200 |
275 |
break; |
break; |
201 |
276 |
} |
} |
202 |
277 |
|
|
203 |
|
if ($no_wait === FALSE) { |
|
|
278 |
|
do { |
|
279 |
|
if (!strstr($flags, 'U')) // U = unlock |
|
280 |
|
break; |
|
281 |
|
|
|
282 |
|
if ($ns_var === FALSE) { |
|
283 |
|
rg_log_debug($k . ': tried to unlock using a wrong command'); |
|
284 |
|
break; |
|
285 |
|
} |
|
286 |
|
|
|
287 |
|
// TODO: can happen? |
|
288 |
|
if (!array_key_exists($ns_var, $rg_cache_locks)) { |
|
289 |
|
rg_log($k . ': tried to unlock an unlocked resource [' . $ns_var . ']!'); |
|
290 |
|
break; |
|
291 |
|
} |
|
292 |
|
|
|
293 |
|
if ($rg_cache_locks[$ns_var]['who'] != $k) { |
|
294 |
|
rg_log($k . ': try to unlock an unlocked a not held lock!'); |
|
295 |
|
break; |
|
296 |
|
} |
|
297 |
|
|
|
298 |
|
rg_wake_from_lock($k, $ns_var); |
|
299 |
|
} while (0); |
|
300 |
|
|
|
301 |
|
if (($no_wait === FALSE) && !empty($buf)) { |
204 |
302 |
rg_log_debug($k . ': enqueue: ' . rtrim($buf)); |
rg_log_debug($k . ': enqueue: ' . rtrim($buf)); |
205 |
303 |
$s['send'] .= $buf; |
$s['send'] .= $buf; |
206 |
|
$conn_table['w'][$k] = $s['socket']; |
|
|
304 |
|
$rg_cache_conn_table['w'][$k] = $s['socket']; |
207 |
305 |
} |
} |
208 |
306 |
} |
} |
209 |
307 |
|
|
210 |
|
function rg_handle_recv($k, &$conn_table) |
|
|
308 |
|
function rg_handle_recv($k) |
211 |
309 |
{ |
{ |
|
310 |
|
global $rg_cache_conn_table; |
|
311 |
|
|
212 |
312 |
//rg_log_debug($k . ': handle_recv'); |
//rg_log_debug($k . ': handle_recv'); |
213 |
|
$s = &$conn_table['conns'][$k]; |
|
|
313 |
|
$s = &$rg_cache_conn_table['conns'][$k]; |
214 |
314 |
|
|
215 |
315 |
$ret = @socket_recv($s['socket'], $buf, 32 * 4096, 0); |
$ret = @socket_recv($s['socket'], $buf, 32 * 4096, 0); |
216 |
316 |
if ($ret === FALSE) { |
if ($ret === FALSE) { |
217 |
317 |
rg_log($k . ": Error in recv (" . socket_strerror(socket_last_error()) . ")"); |
rg_log($k . ": Error in recv (" . socket_strerror(socket_last_error()) . ")"); |
218 |
|
rg_destroy($k, $conn_table); |
|
|
318 |
|
rg_destroy($k); |
219 |
319 |
return; |
return; |
220 |
320 |
} |
} |
221 |
321 |
if ($ret === 0) { |
if ($ret === 0) { |
222 |
322 |
rg_log($k . ": Remote closed the connection (received 0)."); |
rg_log($k . ": Remote closed the connection (received 0)."); |
223 |
|
rg_destroy($k, $conn_table); |
|
|
323 |
|
rg_destroy($k); |
224 |
324 |
return; |
return; |
225 |
325 |
} |
} |
226 |
326 |
|
|
|
... |
... |
function rg_handle_recv($k, &$conn_table) |
235 |
335 |
return; |
return; |
236 |
336 |
|
|
237 |
337 |
$cmd = substr($s['recv'], 0, $pos); |
$cmd = substr($s['recv'], 0, $pos); |
238 |
|
rg_handle_command($k, $conn_table, $cmd); |
|
|
338 |
|
rg_handle_command($k, $cmd); |
239 |
339 |
|
|
240 |
340 |
$s['recv'] = substr($s['recv'], $pos + 1); |
$s['recv'] = substr($s['recv'], $pos + 1); |
241 |
341 |
} |
} |
242 |
342 |
} |
} |
243 |
343 |
|
|
244 |
|
function rg_handle_send($k, &$conn_table) |
|
|
344 |
|
function rg_handle_send($k) |
245 |
345 |
{ |
{ |
|
346 |
|
global $rg_cache_conn_table; |
|
347 |
|
|
246 |
348 |
//rg_log_debug($k . ': Sending...'); |
//rg_log_debug($k . ': Sending...'); |
247 |
|
$s = &$conn_table['conns'][$k]; |
|
|
349 |
|
$s = &$rg_cache_conn_table['conns'][$k]; |
248 |
350 |
|
|
249 |
351 |
$ret = @socket_send($s['socket'], $s['send'], strlen($s['send']), 0); |
$ret = @socket_send($s['socket'], $s['send'], strlen($s['send']), 0); |
250 |
352 |
if ($ret === FALSE) { |
if ($ret === FALSE) { |
251 |
353 |
rg_log($k . ": Cannot send (" . socket_strerror(socket_last_error()) . ")"); |
rg_log($k . ": Cannot send (" . socket_strerror(socket_last_error()) . ")"); |
252 |
|
rg_destroy($k, $conn_table); |
|
|
354 |
|
rg_destroy($k); |
253 |
355 |
return; |
return; |
254 |
356 |
} |
} |
255 |
357 |
|
|
256 |
358 |
$s['send'] = substr($s['send'], $ret); |
$s['send'] = substr($s['send'], $ret); |
257 |
359 |
if (empty($s['send'])) |
if (empty($s['send'])) |
258 |
|
unset($conn_table['w'][$k]); |
|
|
360 |
|
unset($rg_cache_conn_table['w'][$k]); |
259 |
361 |
} |
} |
260 |
362 |
|
|
261 |
|
function rg_handle_new($client, &$conn_table) |
|
|
363 |
|
function rg_handle_new($client) |
262 |
364 |
{ |
{ |
|
365 |
|
global $rg_cache_conn_table; |
|
366 |
|
|
263 |
367 |
socket_set_nonblock($client); |
socket_set_nonblock($client); |
264 |
368 |
|
|
265 |
369 |
$i = socket_export_stream($client); |
$i = socket_export_stream($client); |
266 |
370 |
$key = intval($i); |
$key = intval($i); |
267 |
|
$conn_table['conns'][$key] = array( |
|
|
371 |
|
$rg_cache_conn_table['conns'][$key] = array( |
268 |
372 |
"socket" => $client, |
"socket" => $client, |
269 |
373 |
"recv" => "", |
"recv" => "", |
270 |
374 |
"send" => "", |
"send" => "", |
271 |
375 |
"close_at" => time() + 30 |
"close_at" => time() + 30 |
272 |
376 |
); |
); |
273 |
|
$conn_table['r'][$key] = $client; |
|
|
377 |
|
$rg_cache_conn_table['r'][$key] = $client; |
274 |
378 |
//rg_log($key . ": Added client"); |
//rg_log($key . ": Added client"); |
275 |
379 |
|
|
276 |
380 |
/* This way I can enforce the connecting user to be apache/rocketgit |
/* This way I can enforce the connecting user to be apache/rocketgit |
|
... |
... |
function rg_handle_new($client, &$conn_table) |
280 |
384 |
*/ |
*/ |
281 |
385 |
} |
} |
282 |
386 |
|
|
283 |
|
function rg_handle_idle(&$conn_table) |
|
|
387 |
|
function rg_handle_idle() |
284 |
388 |
{ |
{ |
|
389 |
|
global $rg_cache_conn_table; |
|
390 |
|
|
285 |
391 |
$now = time(); |
$now = time(); |
286 |
392 |
|
|
287 |
|
foreach ($conn_table['conns'] as $key => $info) { |
|
|
393 |
|
foreach ($rg_cache_conn_table['conns'] as $key => $info) { |
288 |
394 |
if (!isset($info['close_at'])) { |
if (!isset($info['close_at'])) { |
289 |
395 |
rg_internal_error('close_at is not set!'); |
rg_internal_error('close_at is not set!'); |
290 |
396 |
continue; |
continue; |
291 |
397 |
} |
} |
292 |
398 |
if ($info['close_at'] < $now) { |
if ($info['close_at'] < $now) { |
293 |
399 |
rg_log_debug($key . ': Destroy key because has been too much time idle.'); |
rg_log_debug($key . ': Destroy key because has been too much time idle.'); |
294 |
|
rg_destroy($key, $conn_table); |
|
|
400 |
|
rg_destroy($key); |
295 |
401 |
} |
} |
296 |
402 |
} |
} |
297 |
403 |
} |
} |
|
... |
... |
if ($r === FALSE) { |
334 |
440 |
exit(1); |
exit(1); |
335 |
441 |
} |
} |
336 |
442 |
|
|
337 |
|
$conn_table = array("r" => array(), "w" => array(), "conns" => array()); |
|
338 |
|
$conn_table['r']['master'] = $master; |
|
|
443 |
|
$rg_cache_conn_table = array("r" => array(), "w" => array(), "conns" => array()); |
|
444 |
|
$rg_cache_conn_table['r']['master'] = $master; |
339 |
445 |
do { |
do { |
340 |
|
//rg_log_ml("conn_table: " . print_r($conn_table, TRUE)); |
|
|
446 |
|
//rg_log_ml("rg_cache_conn_table: " . print_r($rg_cache_conn_table, TRUE)); |
341 |
447 |
|
|
342 |
|
$r2 = $conn_table['r']; $w2 = $conn_table['w']; $ex = array(); |
|
|
448 |
|
$r2 = $rg_cache_conn_table['r']; $w2 = $rg_cache_conn_table['w']; $ex = array(); |
343 |
449 |
$r = @socket_select($r2, $w2, $ex, 5); |
$r = @socket_select($r2, $w2, $ex, 5); |
344 |
450 |
if ($r === FALSE) |
if ($r === FALSE) |
345 |
451 |
rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); |
rg_fatal("Cannot select (" . socket_strerror(socket_last_error()) . ")!"); |
|
... |
... |
do { |
359 |
465 |
continue; |
continue; |
360 |
466 |
} |
} |
361 |
467 |
|
|
362 |
|
rg_handle_new($client, $conn_table); |
|
|
468 |
|
rg_handle_new($client); |
363 |
469 |
continue; |
continue; |
364 |
470 |
} |
} |
365 |
471 |
|
|
366 |
|
rg_handle_recv($key, $conn_table); |
|
|
472 |
|
rg_handle_recv($key); |
367 |
473 |
} |
} |
368 |
474 |
|
|
369 |
475 |
foreach ($w2 as $key => $sock) { |
foreach ($w2 as $key => $sock) { |
370 |
|
if (isset($conn_table['conns'][$key])) |
|
371 |
|
rg_handle_send($key, $conn_table); |
|
|
476 |
|
if (isset($rg_cache_conn_table['conns'][$key])) |
|
477 |
|
rg_handle_send($key); |
372 |
478 |
} |
} |
373 |
479 |
|
|
374 |
480 |
foreach ($ex as $key => $sock) |
foreach ($ex as $key => $sock) |
375 |
|
rg_destroy($key, $conn_table); |
|
|
481 |
|
rg_destroy($key); |
376 |
482 |
} |
} |
377 |
483 |
|
|
378 |
484 |
// TODO: if we activate this, we broke the connection with events.php |
// TODO: if we activate this, we broke the connection with events.php |
379 |
|
//rg_handle_idle($conn_table); |
|
|
485 |
|
//rg_handle_idle(); |
380 |
486 |
} while (1); |
} while (1); |
381 |
487 |
|
|
382 |
488 |
socket_close($master); |
socket_close($master); |
File tests/git-commit-sign.php added (mode: 100644) (index 0000000..dbaeb4d) |
|
1 |
|
<?php |
|
2 |
|
// It also tests 'push-option' |
|
3 |
|
error_reporting(E_ALL | E_STRICT); |
|
4 |
|
ini_set("track_errors", "On"); |
|
5 |
|
|
|
6 |
|
$test_normal = TRUE; |
|
7 |
|
|
|
8 |
|
$INC = dirname(__FILE__) . "/../inc"; |
|
9 |
|
require_once(dirname(__FILE__) . "/config.php"); |
|
10 |
|
require_once($INC . "/init.inc.php"); |
|
11 |
|
require_once($INC . "/git.inc.php"); |
|
12 |
|
require_once("helpers.inc.php"); |
|
13 |
|
require_once("http.inc.php"); |
|
14 |
|
|
|
15 |
|
rg_log_set_file("git-commit-sign.log"); |
|
16 |
|
|
|
17 |
|
require_once("common.php"); |
|
18 |
|
|
|
19 |
|
$_testns = 'git-commit-sign'; |
|
20 |
|
|
|
21 |
|
|
|
22 |
|
rg_log(''); |
|
23 |
|
rg_log_enter('Preparing gpg...'); |
|
24 |
|
$l = __DIR__ . '/temp_repos/git-commit-sign-gpg'; |
|
25 |
|
rg_log('dir=' . $l); |
|
26 |
|
putenv('GNUPGHOME=' . $l); |
|
27 |
|
$r = rg_exec('rm -rf temp_repos/git-commit-sign-gpg' |
|
28 |
|
. ' && mkdir --mode=0700 -p temp_repos/git-commit-sign-gpg' |
|
29 |
|
. ' && cd temp_repos/git-commit-sign-gpg' |
|
30 |
|
. ' && gpg --no-options --lock-never --no-default-keyring' |
|
31 |
|
. ' --passphrase \'\' --batch --quick-generate-key' |
|
32 |
|
. ' \'bla <author1@embedromix.ro>\' rsa4096 default never', |
|
33 |
|
'', FALSE, FALSE, FALSE); |
|
34 |
|
if ($r['ok'] != 1) { |
|
35 |
|
rg_log_ml('out: ' . print_r($r, TRUE)); |
|
36 |
|
rg_log('Error creating gpg keyring!'); |
|
37 |
|
exit(1); |
|
38 |
|
} |
|
39 |
|
rg_log_exit(); |
|
40 |
|
|
|
41 |
|
|
|
42 |
|
rg_log(''); |
|
43 |
|
rg_log_enter('Preparing repo...'); |
|
44 |
|
$r = rg_exec('rm -rf temp_repos/git-commit-sign' |
|
45 |
|
. ' && mkdir --mode=0700 -p temp_repos/git-commit-sign' |
|
46 |
|
. ' && cd temp_repos/git-commit-sign' |
|
47 |
|
. ' && git init --initial-branch=main' |
|
48 |
|
. ' && echo "a text" > bla.txt' |
|
49 |
|
. ' && git add bla.txt' |
|
50 |
|
. ' && git -c gpg.program=../../git-commit-sign-gpg.sh' |
|
51 |
|
. ' commit --author=\'bla <author1@embedromix.ro>\'' |
|
52 |
|
. ' -a -m "bla" --gpg-sign=author1@embedromix.ro', |
|
53 |
|
'', FALSE, FALSE, FALSE); |
|
54 |
|
if ($r['ok'] != 1) { |
|
55 |
|
rg_log_ml('out: ' . print_r($r, TRUE)); |
|
56 |
|
rg_log('Cannot init repo!'); |
|
57 |
|
exit(1); |
|
58 |
|
} |
|
59 |
|
rg_log_exit(); |
|
60 |
|
|
|
61 |
|
|
|
62 |
|
|
|
63 |
|
rg_test_create_user($db, $rg_ui); |
|
64 |
|
$info = array('id' => $rg_ui['username']); |
|
65 |
|
prepare_http($info); |
|
66 |
|
|
|
67 |
|
rg_test_create_repo($db, $rg_ui, $repo); |
|
68 |
|
$r = test_login($test_url, $rg_ui); |
|
69 |
|
if ($r === FALSE) { |
|
70 |
|
rg_log("Cannot login!"); |
|
71 |
|
exit(1); |
|
72 |
|
} |
|
73 |
|
|
|
74 |
|
|
|
75 |
|
rg_test_upload_ssh_key($db, $rg_ui, 'git-commit-sign', $kn); |
|
76 |
|
|
|
77 |
|
|
|
78 |
|
rg_log(''); |
|
79 |
|
rg_log_enter('Trying to push main...'); |
|
80 |
|
$remote = 'ssh://rocketgit@' . $rg_ssh_host . ':' .$rg_ssh_port |
|
81 |
|
. '/user/' . escapeshellarg($rg_ui['username']) |
|
82 |
|
. '/' . escapeshellarg($repo['name']); |
|
83 |
|
$r = rg_exec('cd temp_repos/git-commit-sign && git remote add origin ' . $remote |
|
84 |
|
. ' && git' |
|
85 |
|
. ' -c gpg.program=../../git-commit-sign-gpg.sh' |
|
86 |
|
. ' -c user.signingKey=author1@embedromix.ro' |
|
87 |
|
. ' push' |
|
88 |
|
. ' --push-option=option1 --push-option=option2' |
|
89 |
|
. ' --signed=if-asked origin main', |
|
90 |
|
'', FALSE, FALSE, FALSE); |
|
91 |
|
if ($r['ok'] != 1) { |
|
92 |
|
rg_log_ml('out: ' . print_r($r, TRUE)); |
|
93 |
|
rg_log('Seems I cannot push main!'); |
|
94 |
|
exit(1); |
|
95 |
|
} |
|
96 |
|
rg_log_exit(); |
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
|
100 |
|
rg_log(''); |
|
101 |
|
rg_log_enter('Checking on web that everything is OK...'); |
|
102 |
|
$commit = trim(file_get_contents('temp_repos/git-commit-sign/.git/refs/heads/main')); |
|
103 |
|
rg_log('Loaded main from .git: ' . $commit); |
|
104 |
|
$data = array(); |
|
105 |
|
$headers = array(); |
|
106 |
|
$r = do_req($info, $test_url . '/user/' . rawurlencode($rg_ui['username']) |
|
107 |
|
. '/' . rawurlencode($repo['name']) . '/source/log/commit/' |
|
108 |
|
. $commit, $data, $headers); |
|
109 |
|
file_put_contents('git-commit-sign.out', $r['body']); |
|
110 |
|
if ($r === FALSE) { |
|
111 |
|
rg_log("Cannot load main commit!"); |
|
112 |
|
exit(1); |
|
113 |
|
} |
|
114 |
|
rg_log_exit(); |
|
115 |
|
|
|
116 |
|
|
|
117 |
|
|
|
118 |
|
rg_log('OK!'); |