Update car monitor asset reload and telemetry
This commit is contained in:
1 parent
6f965f8f3e
commit
5d75ad81bd
8 files changed
+4334
-4366
No files matched your search
@@ -44,37 +44,37 @@ if (($params['log'] ?? '') == '1') {
|
||||
$cmdRequested = $params['cmd'] ?? 'se';
|
||||
$cmd = normalize_cmd($cmdRequested);
|
||||
|
||||
if ($cmd === 'se') {
|
||||
$latest = db_latest($pdo);
|
||||
|
||||
if (!$latest) {
|
||||
if ($cmd === 'se') {
|
||||
$latest = db_latest($pdo);
|
||||
|
||||
if (!$latest) {
|
||||
json_exit([
|
||||
'request_id' => $requestId,
|
||||
'error' => 'no_latest_data'
|
||||
], 500);
|
||||
}
|
||||
|
||||
$ageSeconds = max(0, time() - strtotime((string)$latest['ts']));
|
||||
$latestUsage = db_latest_usage($pdo);
|
||||
$staleReason = null;
|
||||
if ($ageSeconds > 30 && $latestUsage && (int)$latestUsage['tcp_ok'] === 0) {
|
||||
$staleReason = (string)($latestUsage['tcp_error'] ?? 'tcp_failed');
|
||||
}
|
||||
|
||||
json_exit([
|
||||
'request_id' => $requestId,
|
||||
'cmd_requested' => 'se',
|
||||
'cmd' => $latest['cmd'],
|
||||
'ts' => $latest['ts'],
|
||||
'meta' => [
|
||||
'age_seconds' => $ageSeconds,
|
||||
'stale' => $ageSeconds > 30,
|
||||
'stale_reason' => $staleReason,
|
||||
'latest_tcp' => $latestUsage,
|
||||
],
|
||||
|
||||
'raw_full' => $latest['raw_full'],
|
||||
'raw_trim' => $latest['raw_trim'],
|
||||
], 500);
|
||||
}
|
||||
|
||||
$ageSeconds = max(0, time() - strtotime((string)$latest['ts']));
|
||||
$latestUsage = db_latest_usage($pdo);
|
||||
$staleReason = null;
|
||||
if ($ageSeconds > 30 && $latestUsage && (int)$latestUsage['tcp_ok'] === 0) {
|
||||
$staleReason = (string)($latestUsage['tcp_error'] ?? 'tcp_failed');
|
||||
}
|
||||
|
||||
json_exit([
|
||||
'request_id' => $requestId,
|
||||
'cmd_requested' => 'se',
|
||||
'cmd' => $latest['cmd'],
|
||||
'ts' => $latest['ts'],
|
||||
'meta' => [
|
||||
'age_seconds' => $ageSeconds,
|
||||
'stale' => $ageSeconds > 30,
|
||||
'stale_reason' => $staleReason,
|
||||
'latest_tcp' => $latestUsage,
|
||||
],
|
||||
|
||||
'raw_full' => $latest['raw_full'],
|
||||
'raw_trim' => $latest['raw_trim'],
|
||||
|
||||
'data' => [
|
||||
'boundary' => (int)$latest['boundary'],
|
||||
@@ -110,26 +110,26 @@ if ($requestMethod !== 'POST') {
|
||||
], 405);
|
||||
}
|
||||
|
||||
$tcpMs = 0;
|
||||
$connectMs = 0;
|
||||
$readMs = 0;
|
||||
$tcpError = '';
|
||||
$trimError = '';
|
||||
$sentBytes = 0;
|
||||
$receivedBytes = 0;
|
||||
|
||||
$rawFull = tcp_request(
|
||||
$cmd,
|
||||
$tcpMs,
|
||||
$connectMs,
|
||||
$readMs,
|
||||
$tcpError,
|
||||
'api_control',
|
||||
$requestId,
|
||||
$sentBytes,
|
||||
$receivedBytes
|
||||
);
|
||||
$execMs = (int)round((microtime(true) - $tsStart) * 1000);
|
||||
$tcpMs = 0;
|
||||
$connectMs = 0;
|
||||
$readMs = 0;
|
||||
$tcpError = '';
|
||||
$trimError = '';
|
||||
$sentBytes = 0;
|
||||
$receivedBytes = 0;
|
||||
|
||||
$rawFull = tcp_request(
|
||||
$cmd,
|
||||
$tcpMs,
|
||||
$connectMs,
|
||||
$readMs,
|
||||
$tcpError,
|
||||
'api_control',
|
||||
$requestId,
|
||||
$sentBytes,
|
||||
$receivedBytes
|
||||
);
|
||||
$execMs = (int)round((microtime(true) - $tsStart) * 1000);
|
||||
|
||||
if ($rawFull === '') {
|
||||
json_exit([
|
||||
@@ -141,16 +141,16 @@ if ($rawFull === '') {
|
||||
'client_ip' => $clientIp,
|
||||
'ua' => $userAgent,
|
||||
'tcp_ok' => 0,
|
||||
'tcp_ms' => $tcpMs,
|
||||
'connect_ms' => $connectMs,
|
||||
'read_ms' => $readMs,
|
||||
'sent_bytes' => $sentBytes,
|
||||
'received_bytes' => $receivedBytes,
|
||||
'total_bytes' => $sentBytes + $receivedBytes,
|
||||
'tcp_error' => ($tcpError !== '' ? $tcpError : 'timeout_or_empty'),
|
||||
'error' => 'CONTROL_CMD_SEND_FAILED'
|
||||
], 502);
|
||||
}
|
||||
'tcp_ms' => $tcpMs,
|
||||
'connect_ms' => $connectMs,
|
||||
'read_ms' => $readMs,
|
||||
'sent_bytes' => $sentBytes,
|
||||
'received_bytes' => $receivedBytes,
|
||||
'total_bytes' => $sentBytes + $receivedBytes,
|
||||
'tcp_error' => ($tcpError !== '' ? $tcpError : 'timeout_or_empty'),
|
||||
'error' => 'CONTROL_CMD_SEND_FAILED'
|
||||
], 502);
|
||||
}
|
||||
|
||||
$rawTrim = make_trim($rawFull, $trimError);
|
||||
$data = ($rawTrim !== '') ? parse_trim($rawTrim) : null;
|
||||
@@ -174,16 +174,16 @@ json_exit([
|
||||
'client_ip' => $clientIp,
|
||||
'ua' => $userAgent,
|
||||
'tcp_ok' => 1,
|
||||
'tcp_ms' => $tcpMs,
|
||||
'connect_ms' => $connectMs,
|
||||
'read_ms' => $readMs,
|
||||
'sent_bytes' => $sentBytes,
|
||||
'received_bytes' => $receivedBytes,
|
||||
'total_bytes' => $sentBytes + $receivedBytes,
|
||||
'tcp_error' => $tcpError,
|
||||
'tcp_ms' => $tcpMs,
|
||||
'connect_ms' => $connectMs,
|
||||
'read_ms' => $readMs,
|
||||
'sent_bytes' => $sentBytes,
|
||||
'received_bytes' => $receivedBytes,
|
||||
'total_bytes' => $sentBytes + $receivedBytes,
|
||||
'tcp_error' => $tcpError,
|
||||
'accepted' => true,
|
||||
'ack_only' => ($rawTrim === ''),
|
||||
'raw_full' => $rawFull,
|
||||
'raw_trim' => $rawTrim,
|
||||
'data' => $data
|
||||
]);
|
||||
]);
|
||||
+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"
|
||||
|
||||
+14
-14
@@ -62,19 +62,19 @@ function collect_once(): bool
|
||||
$tcpError = '';
|
||||
$trimError = '';
|
||||
|
||||
$sentBytes = 0;
|
||||
$receivedBytes = 0;
|
||||
$rawFull = tcp_request(
|
||||
'se',
|
||||
$tcpMs,
|
||||
$connectMs,
|
||||
$readMs,
|
||||
$tcpError,
|
||||
'collector_se',
|
||||
null,
|
||||
$sentBytes,
|
||||
$receivedBytes
|
||||
);
|
||||
$sentBytes = 0;
|
||||
$receivedBytes = 0;
|
||||
$rawFull = tcp_request(
|
||||
'se',
|
||||
$tcpMs,
|
||||
$connectMs,
|
||||
$readMs,
|
||||
$tcpError,
|
||||
'collector_se',
|
||||
null,
|
||||
$sentBytes,
|
||||
$receivedBytes
|
||||
);
|
||||
if ($rawFull === '') {
|
||||
return false;
|
||||
}
|
||||
@@ -105,4 +105,4 @@ if (!is_fast_poll_state() && should_skip_non_driving()) {
|
||||
}
|
||||
|
||||
mark_attempt();
|
||||
collect_once();
|
||||
collect_once();
|
||||
+750
-680
File diff suppressed because it is too large.
Load diff
+3452
-3556
File diff suppressed because it is too large.
Load diff
+37
-37
@@ -1,44 +1,44 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/common.php';
|
||||
|
||||
const WORKER_IDLE_SLEEP_USEC = 200000;
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
fwrite(STDERR, "tcp_worker.php must run from CLI\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$lockFp = fopen('/tmp/car_tcp_worker.lock', 'c');
|
||||
if ($lockFp === false) {
|
||||
fwrite(STDERR, "failed to open worker lock\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!flock($lockFp, LOCK_EX | LOCK_NB)) {
|
||||
fwrite(STDERR, "worker already running\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
register_shutdown_function(static function () use ($lockFp): void {
|
||||
@flock($lockFp, LOCK_UN);
|
||||
@fclose($lockFp);
|
||||
});
|
||||
|
||||
db_ensure_tcp_queue_schema(db());
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/common.php';
|
||||
|
||||
const WORKER_IDLE_SLEEP_USEC = 200000;
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
fwrite(STDERR, "tcp_worker.php must run from CLI\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$lockFp = fopen('/tmp/car_tcp_worker.lock', 'c');
|
||||
if ($lockFp === false) {
|
||||
fwrite(STDERR, "failed to open worker lock\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!flock($lockFp, LOCK_EX | LOCK_NB)) {
|
||||
fwrite(STDERR, "worker already running\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
register_shutdown_function(static function () use ($lockFp): void {
|
||||
@flock($lockFp, LOCK_UN);
|
||||
@fclose($lockFp);
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
tcp_worker_process_job($job);
|
||||
} catch (Throwable $e) {
|
||||
fwrite(STDERR, date('c') . ' ' . $e->getMessage() . "\n");
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
|
||||
tcp_worker_process_job($job);
|
||||
} catch (Throwable $e) {
|
||||
fwrite(STDERR, date('c') . ' ' . $e->getMessage() . "\n");
|
||||
usleep(1000000);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user