2022-05-16 14:21:18 +03:00
|
|
|
<?php
|
|
|
|
namespace taskman;
|
2022-05-20 13:48:34 +03:00
|
|
|
use Exception;
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
require_once(__DIR__ . '/task.inc.php');
|
|
|
|
require_once(__DIR__ . '/scan.inc.php');
|
|
|
|
require_once(__DIR__ . '/cache.inc.php');
|
|
|
|
require_once(__DIR__ . '/pack.inc.php');
|
|
|
|
require_once(__DIR__ . '/util.inc.php');
|
|
|
|
require_once(__DIR__ . '/msgpack.inc.php');
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
class ConfigGlobals
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
public array $base_dirs = array();
|
|
|
|
public ?string $worker_init_fn = null;
|
|
|
|
public string $base_class = '\ConfBase';
|
|
|
|
public string $build_dir;
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function __construct(array $base_dirs, string $build_dir, ?string $worker_init_fn = null)
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
$this->base_dirs = array_map(fn($path) => normalize_path($path), $base_dirs);
|
|
|
|
$this->build_dir = $build_dir;
|
|
|
|
$this->worker_init_fn = $worker_init_fn;
|
2023-03-21 17:33:55 +03:00
|
|
|
}
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-27 01:35:16 +03:00
|
|
|
function initWorker(bool $is_master_proc)
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-25 14:07:10 +03:00
|
|
|
$GLOBALS['CONFIG_GLOBALS'] = $this;
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
if($this->worker_init_fn !== null)
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
$fn = $this->worker_init_fn;
|
2025-02-27 01:35:16 +03:00
|
|
|
$fn($is_master_proc);
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-25 15:48:28 +03:00
|
|
|
function config_log($msg)
|
|
|
|
{
|
|
|
|
echo "[CFG] $msg\n";
|
|
|
|
}
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function config_get_cache_path(ConfigGlobals $globals, string $file) : string
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
return config_get_tmp_build_path($globals, $file . '.cacheb');
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function config_get_cache_payload_path(ConfigGlobals $globals, string $file) : string
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
return config_get_tmp_build_path($globals, $file . '.pdata');
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function config_load(ConfigGlobals $globals, string $conf_path, ?string $conf_dir = null) : object
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
$conf_dir ??= config_map_base_dir($globals->base_dirs, $conf_path);
|
2023-03-21 17:33:55 +03:00
|
|
|
|
2024-03-06 16:21:38 +03:00
|
|
|
list($conf_id, $_) = config_ensure_header($conf_dir, $conf_path);
|
|
|
|
if(!$conf_id)
|
|
|
|
throw new Exception("Bad conf id: {$conf_id}");
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2024-03-06 16:21:38 +03:00
|
|
|
$pres = config_parse(array($conf_dir), $conf_path);
|
2022-05-16 14:21:18 +03:00
|
|
|
if($pres->error !== 0)
|
|
|
|
throw new Exception("Error({$pres->error}) while loading JSON from {$conf_path}:\n" . $pres->error_descr);
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
return config_load_from_kv_array($globals, $conf_dir, $conf_path, $pres->parsed_arr, $conf_id);
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function config_load_from_kv_array(
|
|
|
|
ConfigGlobals $globals, string $conf_dir, string $file,
|
|
|
|
array $arr, ?int $id = null) : object
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
|
|
|
if(!isset($arr['class']) || !isset($arr['class'][0]))
|
2022-10-10 09:47:48 +03:00
|
|
|
throw new Exception("Class is not set in file '$file'.");
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
$id ??= config_file2id($conf_dir, $file);
|
2022-05-16 14:21:18 +03:00
|
|
|
|
|
|
|
$cnf = null;
|
|
|
|
try
|
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
list($klass, $class_id, $norm_arr) = config_apply_class_normalization($arr);
|
|
|
|
|
2022-10-10 09:47:48 +03:00
|
|
|
if(!class_exists($klass))
|
|
|
|
throw new Exception("No such class '$klass'");
|
2022-05-16 14:21:18 +03:00
|
|
|
$cnf = new $klass;
|
2025-02-24 19:22:01 +03:00
|
|
|
if(!is_a($cnf, $globals->base_class))
|
|
|
|
throw new Exception("'$klass' is not subclass of '".ltrim($globals->base_class, '\\')."'");
|
2023-12-01 15:07:10 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
$cnf->import($norm_arr);
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
catch(Exception $e)
|
|
|
|
{
|
2022-10-10 09:47:48 +03:00
|
|
|
throw new Exception($e->getMessage() . " in file '{$file}'"/* . $e->getTraceAsString()*/);
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$cnf->id = $id;
|
|
|
|
$cnf->strid = config_file2strid($conf_dir, $file);
|
|
|
|
|
|
|
|
return $cnf;
|
|
|
|
}
|
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
function config_bench_load(ConfigGlobals $globals, string $file)
|
2022-05-16 14:21:18 +03:00
|
|
|
{
|
2025-02-24 19:22:01 +03:00
|
|
|
$base_dir = config_map_base_dir($globals->base_dirs, $file);
|
2022-05-16 14:21:18 +03:00
|
|
|
|
2025-02-24 19:22:01 +03:00
|
|
|
list($conf_id, $_) = config_ensure_header($base_dir, $file);
|
|
|
|
if(!$conf_id)
|
|
|
|
throw new Exception("Bad conf id: {$conf_id}");
|
|
|
|
$t = microtime(true);
|
|
|
|
$parse_res = config_parse($globals->base_dirs, $file);
|
|
|
|
if($parse_res->error !== 0)
|
|
|
|
throw new Exception("Error({$parse_res->error}) while loading JSON from {$file}:\n" . $parse_res->error_descr);
|
2025-02-25 15:48:28 +03:00
|
|
|
config_log("Parse: " . (microtime(true) - $t));
|
2025-02-24 19:22:01 +03:00
|
|
|
$t = microtime(true);
|
|
|
|
$config = config_load_from_kv_array($globals, $base_dir, $file, $parse_res->parsed_arr, $conf_id);
|
2025-02-25 15:48:28 +03:00
|
|
|
config_log("Load: " . (microtime(true) - $t));
|
2022-05-16 14:21:18 +03:00
|
|
|
}
|
|
|
|
|