forked from php/php-src
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser_cache_lookup_cache_fork_001.phpt
More file actions
117 lines (101 loc) · 2.52 KB
/
user_cache_lookup_cache_fork_001.phpt
File metadata and controls
117 lines (101 loc) · 2.52 KB
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
--TEST--
OPcache user cache request-local lookup cache sees cross-process updates on next fetch
--EXTENSIONS--
opcache
pcntl
--SKIPIF--
<?php
if (!function_exists('pcntl_fork')) {
die('skip pcntl_fork() not available');
}
?>
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.user_cache_memory_consumption=32
--FILE--
<?php
use OPcache\UserCacheException;
function fetch_or_miss(string $key): string
{
try {
$value = OPcache\cache_fetch($key);
return is_string($value) ? $value : get_debug_type($value);
} catch (UserCacheException) {
return 'MISS';
}
}
function wait_for_file(string $path): void
{
$deadline = microtime(true) + 5.0;
while (!file_exists($path)) {
if (microtime(true) >= $deadline) {
throw new RuntimeException("timed out waiting for {$path}");
}
usleep(1000);
}
}
function cleanup_files(string ...$paths): void
{
foreach ($paths as $path) {
@unlink($path);
}
}
function run_lookup_cache_scenario(string $key, ?string $initialValue, string $action, ?string $updatedValue): void
{
$prefix = sys_get_temp_dir() . '/opcache_lookup_cache_' . $key . '_' . getmypid();
$readyFile = $prefix . '.ready';
$doneFile = $prefix . '.done';
$resultFile = $prefix . '.result';
cleanup_files($readyFile, $doneFile, $resultFile);
if ($initialValue === null) {
OPcache\cache_delete($key);
} else {
OPcache\cache_store($key, $initialValue);
}
$pid = pcntl_fork();
if ($pid === -1) {
throw new RuntimeException('pcntl_fork() failed');
}
if ($pid === 0) {
$first = fetch_or_miss($key);
file_put_contents($readyFile, 'ready');
wait_for_file($doneFile);
$second = fetch_or_miss($key);
file_put_contents($resultFile, $first . "\n" . $second);
exit(0);
}
wait_for_file($readyFile);
switch ($action) {
case 'store':
OPcache\cache_store($key, $updatedValue);
break;
case 'delete':
OPcache\cache_delete($key);
break;
case 'clear':
OPcache\cache_clear();
break;
default:
throw new RuntimeException("unknown action {$action}");
}
file_put_contents($doneFile, 'done');
pcntl_waitpid($pid, $status);
echo trim((string) file_get_contents($resultFile)), "\n";
cleanup_files($readyFile, $doneFile, $resultFile);
}
OPcache\cache_clear();
run_lookup_cache_scenario('lookup_hit_store_key', 'old', 'store', 'new');
run_lookup_cache_scenario('lookup_miss_store_key', null, 'store', 'created');
run_lookup_cache_scenario('lookup_hit_delete_key', 'old', 'delete', null);
run_lookup_cache_scenario('lookup_hit_clear_key', 'old', 'clear', null);
?>
--EXPECT--
old
new
MISS
created
old
MISS
old
MISS