Update car monitor asset reload and telemetry
This commit is contained in:
1 parent
6f965f8f3e
commit
5d75ad81bd
6 files changed
+126
-158
No files matched your search
+2
-3
@@ -59,12 +59,11 @@ $assets = [];
|
||||
foreach (collect_asset_files($root, $scanRoots) as $fullPath) {
|
||||
$relativePath = ltrim(str_replace($rootPath ?: $root, '', $fullPath), DIRECTORY_SEPARATOR);
|
||||
$fileHash = is_readable($fullPath) ? (hash_file('sha256', $fullPath) ?: 'hash-failed') : 'unreadable';
|
||||
$fileVersion = (string)filemtime($fullPath) . '-' . substr($fileHash, 0, 10);
|
||||
$publicPath = '/car/' . str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
|
||||
$fileVersion = substr($fileHash, 0, 16);
|
||||
$publicPath = '/custom/car/' . str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
|
||||
$fingerprints[] = implode('|', [
|
||||
ltrim($publicPath, '/'),
|
||||
(string)filesize($fullPath),
|
||||
(string)filemtime($fullPath),
|
||||
$fileHash,
|
||||
]);
|
||||
$assets[$publicPath] = $fileVersion;
|
||||
|
||||
@@ -214,20 +214,23 @@
|
||||
}).then(function (data) {
|
||||
if (!data || data.result !== 'ok' || !data.version) return;
|
||||
|
||||
var token = data.version.slice(0, 12);
|
||||
var previous = storeGet(storageKey);
|
||||
var mismatch = loadedAssetMismatch(data.assets);
|
||||
var forceReload = bfcacheReturn;
|
||||
var versionChanged = previous && previous !== data.version;
|
||||
var latestToken = String(data.version).slice(0, 12);
|
||||
var hasLatestToken = assetTokenFromLocation() === latestToken;
|
||||
var mismatch = !hasLatestToken && loadedAssetMismatch(data.assets);
|
||||
var wasBfcacheReturn = bfcacheReturn;
|
||||
bfcacheReturn = false;
|
||||
storeSet(storageKey, data.version);
|
||||
|
||||
if (assetTokenFromLocation() !== token || mismatch || forceReload) {
|
||||
reloadWith(data.version, mismatch || forceReload);
|
||||
if ((mismatch || wasBfcacheReturn) && !hasLatestToken) {
|
||||
reloadWith(data.version, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (previous && previous !== data.version) {
|
||||
if (versionChanged) {
|
||||
reloadWith(data.version, false);
|
||||
return;
|
||||
}
|
||||
}).then(function () {
|
||||
running = false;
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
"name": "Car Monitor",
|
||||
"short_name": "Car Monitor",
|
||||
"description": "Vehicle status monitor",
|
||||
"start_url": "/car/monitor.php?pwa=1",
|
||||
"scope": "/car/",
|
||||
"start_url": "/custom/car/monitor.php?pwa=1",
|
||||
"scope": "/custom/car/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"background_color": "#0f172a",
|
||||
"theme_color": "#0f172a",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/car/assets/icon-192.png",
|
||||
"src": "/custom/car/assets/icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
},
|
||||
{
|
||||
"src": "/car/assets/icon-512.png",
|
||||
"src": "/custom/car/assets/icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "any maskable"
|
||||
|
||||
+73
-3
@@ -3,7 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
date_default_timezone_set('Asia/Seoul');
|
||||
|
||||
$carSecretFile = '/home/seo/secret/car.php';
|
||||
$carSecretFile = __DIR__ . '/../../config/car.php';
|
||||
if (!is_file($carSecretFile)) {
|
||||
throw new RuntimeException('Missing car secret config: ' . $carSecretFile);
|
||||
}
|
||||
@@ -40,6 +40,7 @@ define('ALLOWED_IPS', array_values(array_filter(
|
||||
const ALLOWED_CMD = ['se', 'ef', 'en', 'hn', 'hf', 'dl', 'du', 'tu'];
|
||||
const CONTROL_CMD = ['ef', 'en', 'hn', 'hf', 'dl', 'du', 'tu'];
|
||||
const CARRIER_BILLING_UNIT_BYTES = 512;
|
||||
const TCP_STALE_QUEUE_BATCH_LIMIT = 200;
|
||||
|
||||
const RAW_FULL_REGEX = '/(?<modem>\d{11})\/R:(?<r>[a-z])\/E:(?<E0>[io]{5}\d{3}[io])\/D:(?<D0>[oi]{7})\/L:(?<L0>o{5})\/F:(?<F0>[ots][oi]\d{4}[oi]{4})\/S:(?<S0>[^\/]+)/';
|
||||
|
||||
@@ -271,7 +272,7 @@ function tcp_queue_update(PDO $pdo, string $requestId, array $values): void
|
||||
|
||||
function tcp_queue_insert(string $cmd, string $usageSource, string $requestId): array
|
||||
{
|
||||
$pdo = db();
|
||||
$pdo = db(true);
|
||||
db_ensure_tcp_queue_schema($pdo);
|
||||
|
||||
$now = microtime(true);
|
||||
@@ -305,6 +306,25 @@ function tcp_queue_insert(string $cmd, string $usageSource, string $requestId):
|
||||
];
|
||||
}
|
||||
|
||||
function tcp_queue_has_pending_collector_se(PDO $pdo): bool
|
||||
{
|
||||
db_ensure_tcp_queue_schema($pdo);
|
||||
tcp_queue_expire_queued_before_send($pdo);
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT 1
|
||||
FROM car_tcp_request_queue
|
||||
WHERE source = 'collector_se'
|
||||
AND cmd = 'se'
|
||||
AND status IN ('queued', 'processing', 'ui_timeout_pending')
|
||||
AND usage_deadline_ts > :now
|
||||
LIMIT 1
|
||||
");
|
||||
$stmt->execute([':now' => microtime(true)]);
|
||||
|
||||
return (bool)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
function tcp_queue_get(string $requestId): ?array
|
||||
{
|
||||
$pdo = db();
|
||||
@@ -323,7 +343,16 @@ function tcp_queue_claim_next(PDO $pdo): ?array
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$stmt = $pdo->query("SELECT * FROM car_tcp_request_queue WHERE status = 'queued' ORDER BY id ASC LIMIT 1 FOR UPDATE");
|
||||
$stmt = $pdo->query("
|
||||
SELECT *
|
||||
FROM car_tcp_request_queue
|
||||
WHERE status = 'queued'
|
||||
ORDER BY
|
||||
CASE WHEN cmd IN ('ef', 'en', 'hn', 'hf', 'dl', 'du', 'tu') THEN 0 ELSE 1 END,
|
||||
id ASC
|
||||
LIMIT 1
|
||||
FOR UPDATE
|
||||
");
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) {
|
||||
$pdo->commit();
|
||||
@@ -356,8 +385,36 @@ function tcp_queue_has_usage(PDO $pdo, string $requestId): bool
|
||||
return (bool)$stmt->fetchColumn();
|
||||
}
|
||||
|
||||
function tcp_queue_expire_queued_before_send(PDO $pdo): void
|
||||
{
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE car_tcp_request_queue
|
||||
SET status = 'expired_before_send',
|
||||
updated_at = :updated_at,
|
||||
tcp_ok = 0,
|
||||
tcp_error = 'queue_expired_before_send',
|
||||
sent_bytes = 0,
|
||||
received_bytes = 0,
|
||||
total_bytes = 0,
|
||||
connect_ms = 0,
|
||||
read_ms = 0,
|
||||
tcp_ms = 0
|
||||
WHERE status = 'queued'
|
||||
AND ui_deadline_ts > 0
|
||||
AND ui_deadline_ts < :now
|
||||
ORDER BY id ASC
|
||||
LIMIT " . TCP_STALE_QUEUE_BATCH_LIMIT
|
||||
);
|
||||
$stmt->execute([
|
||||
':updated_at' => tcp_queue_now(),
|
||||
':now' => microtime(true),
|
||||
]);
|
||||
}
|
||||
|
||||
function tcp_queue_recover_stale(PDO $pdo): void
|
||||
{
|
||||
tcp_queue_expire_queued_before_send($pdo);
|
||||
|
||||
$now = microtime(true);
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT *
|
||||
@@ -684,6 +741,19 @@ function tcp_request(
|
||||
$requestId = substr(bin2hex(random_bytes(16)), 0, 32);
|
||||
}
|
||||
|
||||
if ($cmd === 'se' && $usageSource === 'collector_se') {
|
||||
try {
|
||||
if (tcp_queue_has_pending_collector_se(db(true))) {
|
||||
$tcpError = 'skipped_duplicate_pending_collector_se';
|
||||
return '';
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$tcpError = 'queue_pending_check_failed';
|
||||
record_tcp_usage($usageSource, $cmd, 0, 0, false, $tcpError, $requestId);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
tcp_queue_insert($cmd, $usageSource, $requestId);
|
||||
} catch (Throwable $e) {
|
||||
|
||||
+36
-140
@@ -3,7 +3,9 @@ declare(strict_types=1);
|
||||
|
||||
date_default_timezone_set('Asia/Seoul');
|
||||
|
||||
$carSecretFile = '/home/seo/secret/car.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
|
||||
$carSecretFile = __DIR__ . '/../../config/car.php';
|
||||
if (!is_file($carSecretFile)) {
|
||||
throw new RuntimeException('Missing car secret config: ' . $carSecretFile);
|
||||
}
|
||||
@@ -19,8 +21,6 @@ define('DB_CHARSET', (string)($carDbConfig['charset'] ?? 'utf8mb4'));
|
||||
|
||||
const LOG_LIMIT = 300;
|
||||
const CHART_LIMIT = 500;
|
||||
const CAR_MONITOR_COOKIE = 'car_monitor_access';
|
||||
const CAR_MONITOR_AUTH_TTL = 2592000;
|
||||
const CAR_MONITOR_SETTINGS_COOKIE = 'car_monitor_settings_access';
|
||||
const CAR_MONITOR_SETTINGS_TTL = 900;
|
||||
const CAR_MONITOR_SETTINGS_PASSWORD = '1026!)Corjs';
|
||||
@@ -40,14 +40,13 @@ const DATA_CURRENT_BILLING_USAGE_BYTES = [
|
||||
|
||||
function car_asset_url(string $path): string
|
||||
{
|
||||
$relativePath = preg_replace('#^/car/#', '', $path) ?? ltrim($path, '/');
|
||||
$relativePath = preg_replace('#^/custom/car/#', '', $path) ?? ltrim($path, '/');
|
||||
$fullPath = __DIR__ . '/' . ltrim($relativePath, '/');
|
||||
$version = 'dev';
|
||||
|
||||
if (is_file($fullPath)) {
|
||||
$mtime = filemtime($fullPath) ?: time();
|
||||
$hash = is_readable($fullPath) ? substr(hash_file('sha256', $fullPath) ?: '', 0, 10) : '';
|
||||
$version = $mtime . ($hash !== '' ? '-' . $hash : '');
|
||||
$hash = is_readable($fullPath) ? substr(hash_file('sha256', $fullPath) ?: '', 0, 16) : '';
|
||||
$version = $hash !== '' ? $hash : 'unreadable';
|
||||
}
|
||||
|
||||
return $path . '?v=' . rawurlencode($version);
|
||||
@@ -879,62 +878,13 @@ function car_monitor_cookie_options(int $expires): array
|
||||
{
|
||||
return [
|
||||
'expires' => $expires,
|
||||
'path' => '/car/',
|
||||
'path' => '/custom/car/',
|
||||
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
];
|
||||
}
|
||||
|
||||
function car_monitor_cookie_value(int $expires, bool $admin = false): string
|
||||
{
|
||||
$body = base64_encode(json_encode([
|
||||
'exp' => $expires,
|
||||
'iat' => time(),
|
||||
'admin' => $admin,
|
||||
], JSON_UNESCAPED_SLASHES));
|
||||
$sig = hash_hmac('sha256', $body, car_monitor_cookie_secret());
|
||||
|
||||
return $body . '.' . $sig;
|
||||
}
|
||||
|
||||
function car_monitor_issue_cookie(bool $admin = false): void
|
||||
{
|
||||
$expires = time() + CAR_MONITOR_AUTH_TTL;
|
||||
setcookie(CAR_MONITOR_COOKIE, car_monitor_cookie_value($expires, $admin), car_monitor_cookie_options($expires));
|
||||
}
|
||||
|
||||
function car_monitor_cookie_payload(): ?array
|
||||
{
|
||||
$cookie = $_COOKIE[CAR_MONITOR_COOKIE] ?? '';
|
||||
if (!is_string($cookie) || strpos($cookie, '.') === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
[$body, $sig] = explode('.', $cookie, 2);
|
||||
$expected = hash_hmac('sha256', $body, car_monitor_cookie_secret());
|
||||
if (!hash_equals($expected, $sig)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$decoded = base64_decode($body, true);
|
||||
if ($decoded === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = json_decode($decoded, true);
|
||||
if (!is_array($payload)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int)($payload['exp'] ?? 0) >= time() ? $payload : null;
|
||||
}
|
||||
|
||||
function car_monitor_has_cookie(): bool
|
||||
{
|
||||
return is_array(car_monitor_cookie_payload());
|
||||
}
|
||||
|
||||
function car_monitor_settings_cookie_value(int $expires): string
|
||||
{
|
||||
$body = base64_encode(json_encode([
|
||||
@@ -993,72 +943,22 @@ function car_monitor_launcher_session(): array
|
||||
return $session;
|
||||
}
|
||||
|
||||
$cookieHeader = trim((string)($_SERVER['HTTP_COOKIE'] ?? ''));
|
||||
if ($cookieHeader !== '') {
|
||||
$remoteSession = car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader);
|
||||
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
||||
car_monitor_issue_cookie();
|
||||
$session = ['authenticated' => true];
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
||||
$cookiePayload = car_monitor_cookie_payload();
|
||||
if (is_array($cookiePayload)) {
|
||||
$session = ['authenticated' => true];
|
||||
if (custom_is_site_admin()) {
|
||||
custom_issue_auth_cookie(true);
|
||||
$session = ['authenticated' => true, 'admin' => true];
|
||||
return $session;
|
||||
}
|
||||
|
||||
$session = ['authenticated' => false];
|
||||
if (custom_has_auth_cookie()) {
|
||||
$session = [
|
||||
'authenticated' => true,
|
||||
'admin' => custom_auth_cookie_is_admin(),
|
||||
];
|
||||
return $session;
|
||||
}
|
||||
|
||||
function car_monitor_launcher_api_request(string $method, string $url, ?array $payload = null, string $cookieHeader = ''): ?array
|
||||
{
|
||||
$body = false;
|
||||
|
||||
if (function_exists('curl_init')) {
|
||||
$ch = curl_init($url);
|
||||
if ($ch !== false) {
|
||||
$headers = ['User-Agent: car-monitor-auth/1.0'];
|
||||
if ($cookieHeader !== '') {
|
||||
$headers[] = 'Cookie: ' . $cookieHeader;
|
||||
}
|
||||
if ($payload !== null) {
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
}
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CONNECTTIMEOUT => 2,
|
||||
CURLOPT_TIMEOUT => 4,
|
||||
CURLOPT_CUSTOMREQUEST => strtoupper($method),
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
]);
|
||||
if ($payload !== null) {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
$body = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
}
|
||||
}
|
||||
|
||||
if ($body === false) {
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => strtoupper($method),
|
||||
'timeout' => 4,
|
||||
'header' => ($cookieHeader !== '' ? "Cookie: {$cookieHeader}\r\n" : '')
|
||||
. "User-Agent: car-monitor-auth/1.0\r\n"
|
||||
. ($payload !== null ? "Content-Type: application/json\r\n" : ''),
|
||||
'content' => $payload !== null ? json_encode($payload, JSON_UNESCAPED_UNICODE) : '',
|
||||
],
|
||||
]);
|
||||
$body = @file_get_contents($url, false, $context);
|
||||
}
|
||||
|
||||
$data = is_string($body) ? json_decode($body, true) : null;
|
||||
return is_array($data) ? $data : null;
|
||||
$session = ['authenticated' => false, 'admin' => false];
|
||||
return $session;
|
||||
}
|
||||
|
||||
function car_monitor_has_access(): bool
|
||||
@@ -1069,6 +969,10 @@ function car_monitor_has_access(): bool
|
||||
|
||||
function car_monitor_require_access(bool $json = false): void
|
||||
{
|
||||
if (function_exists('custom_block_login_denied')) {
|
||||
custom_block_login_denied($json);
|
||||
}
|
||||
|
||||
if (car_monitor_has_access()) {
|
||||
return;
|
||||
}
|
||||
@@ -1101,7 +1005,7 @@ function car_monitor_require_access(bool $json = false): void
|
||||
window.addEventListener('DOMContentLoaded', function () {
|
||||
window.CustomAuthPin && window.CustomAuthPin.render({
|
||||
mount: '#findMyShortcut',
|
||||
apiUrl: '/car/monitor.php?mode=auth-login',
|
||||
apiUrl: '/custom/car/monitor.php?mode=auth-login',
|
||||
title: '비밀번호',
|
||||
placeholder: '비밀번호',
|
||||
backLabel: '채건닷컴',
|
||||
@@ -1127,20 +1031,16 @@ function car_monitor_issue_pwa_cookie_if_requested(): void
|
||||
return;
|
||||
}
|
||||
|
||||
$cookieHeader = trim((string)($_SERVER['HTTP_COOKIE'] ?? ''));
|
||||
if ($cookieHeader !== '') {
|
||||
$remoteSession = car_monitor_launcher_api_request('GET', 'https://chaegeon.com/custom/launcher/api.php?session=1', null, $cookieHeader);
|
||||
if (is_array($remoteSession) && !empty($remoteSession['authenticated'])) {
|
||||
car_monitor_issue_cookie();
|
||||
}
|
||||
}
|
||||
|
||||
header('Location: /car/monitor.php', true, 302);
|
||||
header('Location: /custom/car/monitor.php', true, 302);
|
||||
exit;
|
||||
}
|
||||
|
||||
function car_monitor_auth_api(): void
|
||||
{
|
||||
if (function_exists('custom_block_login_denied')) {
|
||||
custom_block_login_denied(true);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['failMessages'])) {
|
||||
json_response(['failMessages' => ['비밀번호가 틀립니다.']]);
|
||||
}
|
||||
@@ -1155,12 +1055,8 @@ function car_monitor_auth_api(): void
|
||||
json_response(['result' => 'fail', 'message' => 'password_digits_only'], 401);
|
||||
}
|
||||
|
||||
$remote = car_monitor_launcher_api_request('POST', 'https://chaegeon.com/custom/launcher/api.php', [
|
||||
'action' => 'login',
|
||||
'password' => $password,
|
||||
]);
|
||||
if (is_array($remote) && ($remote['result'] ?? '') === 'ok') {
|
||||
car_monitor_issue_cookie();
|
||||
if (custom_verify_password($password)) {
|
||||
custom_issue_auth_cookie(false);
|
||||
json_response(['result' => 'ok']);
|
||||
}
|
||||
|
||||
@@ -1350,13 +1246,13 @@ $carMonitorSession = car_monitor_launcher_session();
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<title>Car Monitor</title>
|
||||
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/car/assets/favicon.svg'), ENT_QUOTES, 'UTF-8') ?>" type="image/svg+xml">
|
||||
<link rel="shortcut icon" href="<?= htmlspecialchars(car_asset_url('/car/favicon.ico'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/car/assets/icon-32.png'), ENT_QUOTES, 'UTF-8') ?>" type="image/png" sizes="32x32">
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/car/assets/icon-192.png'), ENT_QUOTES, 'UTF-8') ?>" type="image/png" sizes="192x192">
|
||||
<link rel="apple-touch-icon" href="<?= htmlspecialchars(car_asset_url('/car/assets/apple-touch-icon.png'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<link rel="manifest" href="<?= htmlspecialchars(car_asset_url('/car/assets/site.webmanifest'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<script src="<?= htmlspecialchars(car_asset_url('/car/assets/asset-reload.js'), ENT_QUOTES, 'UTF-8') ?>" data-service="car" defer></script>
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/custom/car/assets/favicon.svg'), ENT_QUOTES, 'UTF-8') ?>" type="image/svg+xml">
|
||||
<link rel="shortcut icon" href="<?= htmlspecialchars(car_asset_url('/custom/car/favicon.ico'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/custom/car/assets/icon-32.png'), ENT_QUOTES, 'UTF-8') ?>" type="image/png" sizes="32x32">
|
||||
<link rel="icon" href="<?= htmlspecialchars(car_asset_url('/custom/car/assets/icon-192.png'), ENT_QUOTES, 'UTF-8') ?>" type="image/png" sizes="192x192">
|
||||
<link rel="apple-touch-icon" href="<?= htmlspecialchars(car_asset_url('/custom/car/assets/apple-touch-icon.png'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<link rel="manifest" href="<?= htmlspecialchars(car_asset_url('/custom/car/assets/site.webmanifest'), ENT_QUOTES, 'UTF-8') ?>">
|
||||
<script src="<?= htmlspecialchars(car_asset_url('/custom/car/assets/asset-reload.js'), ENT_QUOTES, 'UTF-8') ?>" data-service="car" defer></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap" rel="stylesheet">
|
||||
|
||||
+2
-2
@@ -26,11 +26,11 @@ register_shutdown_function(static function () use ($lockFp): void {
|
||||
@fclose($lockFp);
|
||||
});
|
||||
|
||||
db_ensure_tcp_queue_schema(db());
|
||||
db_ensure_tcp_queue_schema(db(true));
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
$job = tcp_queue_claim_next(db());
|
||||
$job = tcp_queue_claim_next(db(true));
|
||||
if (!$job) {
|
||||
usleep(WORKER_IDLE_SLEEP_USEC);
|
||||
continue;
|
||||
|
||||
Reference in new issue
Block a user