mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-20 11:26:13 +00:00
MVC: add locking in JsonKeyValueStoreField type.
Although in theory the current stat() should at least make sure the same thread wouldn't execute the same action twice, it seems in reality actions are being executed for every record in a set. Calling stat() after write+flush seems to return the previous status in stead of the one just written to disk (ufs issue on fbsd?). To prevent this from happening, use fstat() and lock the target file while processing. Found this with the firewall api plugin enabled and a set of rules in it, which seemed to trigger "list gateways" for every record.
This commit is contained in:
parent
cc67f7625e
commit
8b7d1a5b1b
@ -124,23 +124,30 @@ class JsonKeyValueStoreField extends BaseListField
|
||||
$sourcefile = $this->internalSourceFile;
|
||||
}
|
||||
if (!empty($this->internalConfigdPopulateAct)) {
|
||||
// execute configd action when provided
|
||||
if (!is_file($sourcefile)) {
|
||||
$muttime = 0;
|
||||
if (is_file($sourcefile)) {
|
||||
$sourcehandle = fopen($sourcefile, "r+");
|
||||
} else {
|
||||
$stat = stat($sourcefile);
|
||||
// ignore empty files
|
||||
$muttime = $stat['size'] == 0 ? 0 : $stat['mtime'];
|
||||
$sourcehandle = fopen($sourcefile, "w");
|
||||
}
|
||||
if (time() - $muttime > $this->internalConfigdPopulateTTL) {
|
||||
$act = $this->internalConfigdPopulateAct;
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdRun($act, false, 20);
|
||||
if (!empty($response) && json_decode($response) !== null) {
|
||||
// only store parsable results
|
||||
file_put_contents($sourcefile, $response);
|
||||
if (flock($sourcehandle, LOCK_EX)) {
|
||||
// execute configd action when provided
|
||||
$stat = fstat($sourcehandle);
|
||||
$muttime = $stat['size'] == 0 ? 0 : $stat['mtime'];
|
||||
if (time() - $muttime > $this->internalConfigdPopulateTTL) {
|
||||
$act = $this->internalConfigdPopulateAct;
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdRun($act, false, 20);
|
||||
if (!empty($response) && json_decode($response) !== null) {
|
||||
// only store parsable results
|
||||
fseek($sourcehandle, 0);
|
||||
ftruncate($sourcehandle, 0);
|
||||
fwrite($sourcehandle, $response);
|
||||
fflush($sourcehandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
flock($sourcehandle, LOCK_UN);
|
||||
fclose($sourcehandle);
|
||||
}
|
||||
if (is_file($sourcefile)) {
|
||||
$data = json_decode(file_get_contents($sourcefile), true);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user