release: bump version to 0.53.0
This commit is contained in:
@@ -299,6 +299,17 @@ State semantics:
|
||||
|
||||
AISStream connectivity validation reads the saved collector configuration, environment variables, and `AISSTREAM_API_KEY` in `~/.zshrc` through `datasource_connectivity.py`. For actual collection, the most reliable path is saving the API key in `Settings -> Collector Settings -> AISStream Vessels`; if the key only lives in `~/.zshrc`, confirm that the backend process inherited it.
|
||||
|
||||
The console manages AISStream from `/datasources -> Realtime Streams`, not from the normal finite collection progress bar. The realtime stream API aggregates runtime state, health, configuration preview, and raw observation counters:
|
||||
|
||||
```http
|
||||
GET /api/v1/realtime-sources
|
||||
POST /api/v1/realtime-sources/{source}/start
|
||||
POST /api/v1/realtime-sources/{source}/stop
|
||||
POST /api/v1/realtime-sources/{source}/restart
|
||||
```
|
||||
|
||||
`aisstream_vessels` and custom `source_type=websocket` sources appear in that API. They do not participate in one-click collection percentages; the UI interprets them as long-lived services with message counters, lag, last success, and last error.
|
||||
|
||||
### AIS Raw Observations And Aggregation
|
||||
|
||||
AIS observations do not directly replace final vessel records. They are first saved as raw observations:
|
||||
@@ -318,7 +329,7 @@ GET /api/v1/visualization/vessels/{mmsi}/track
|
||||
GET /api/v1/visualization/vessels/{mmsi}/conflicts
|
||||
```
|
||||
|
||||
`/api/v1/vessels/snapshot` requires `bbox` and `zoom`, defaults to `limit=1000`, and caps `limit` at `5000`. It reads only aggregated `ais_raw_observations`; it no longer merges legacy `vessel_position` / `vessel_static` rows. The old `/api/v1/visualization/geo/vessels` endpoint has been removed and returns `410 Gone`.
|
||||
`/api/v1/vessels/snapshot` requires `bbox` and `zoom`, defaults to `limit=1000`, and caps `limit` at `5000`. It prefers aggregated `ais_raw_observations`; when the current raw window is empty, it can fall back to the latest legacy `vessel_position` / `vessel_static` rows and marks that path with `diagnostics.legacy_fallback_used`. The old `/api/v1/visualization/geo/vessels` route has been removed.
|
||||
|
||||
Realtime deltas are sent through the `/ws` `vessels` channel. Clients must subscribe with the current viewport:
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ Normalization:
|
||||
|
||||
Connectivity validation reads saved configuration, environment variables, and `AISSTREAM_API_KEY` from `~/.zshrc`. For actual collection, prefer saving the API key in collector settings. If the key only lives in `~/.zshrc`, confirm that the backend process inherited it; otherwise validation may pass while the collector runtime cannot read the key.
|
||||
|
||||
Connectivity validation and actual collection are separate actions. A banner such as `AISStream credentials configured, WebSocket endpoint format valid` only means the saved settings can be used for a connection attempt; runtime status may still be `disconnected`. Global AIS data is written locally only while the `aisstream_vessels` collector is `streaming` / `connected` and its message count plus `last_seen_at` keep advancing.
|
||||
Connectivity validation and actual collection are separate actions. A banner such as `AISStream credentials configured, WebSocket endpoint format valid` only means the saved settings can be used for a connection attempt; runtime status may still be `disconnected`. Global AIS data is written locally only while `aisstream_vessels` is `streaming` / `connected` and its realtime stream counters plus `last_seen_at` keep advancing. Start, stop, reconnect, health, and counters are exposed through `/datasources -> Realtime Streams` and `/api/v1/realtime-sources`; AISStream is not counted in normal one-click collection progress.
|
||||
|
||||
The new vessel list entry point is no longer the legacy `/api/v1/visualization/geo/vessels` route. Earth initial state should call:
|
||||
|
||||
@@ -296,7 +296,7 @@ The new vessel list entry point is no longer the legacy `/api/v1/visualization/g
|
||||
GET /api/v1/vessels/snapshot?bbox=lon_min,lat_min,lon_max,lat_max&zoom=12&limit=1000
|
||||
```
|
||||
|
||||
That endpoint reads local aggregated `ais_raw_observations` only. Realtime updates use the `/ws` `vessels` channel; subscriptions must include `bbox`, `zoom`, and `limit`. The server filters updates per connection and merges collector broadcasts every second, keeping only the latest position per MMSI.
|
||||
That endpoint prefers local aggregated `ais_raw_observations`; when the current raw window is empty, it can fall back to the latest legacy `vessel_position` / `vessel_static` rows and exposes that through `diagnostics.legacy_fallback_used`. Realtime updates use the `/ws` `vessels` channel; subscriptions must include `bbox`, `zoom`, and `limit`. The server filters updates per connection and merges collector broadcasts every second, keeping only the latest position per MMSI.
|
||||
|
||||
## Custom REST / WebSocket Mapping Runtime
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ The `earth:compute-center-location-saved` reconciliation pipeline is deliberatel
|
||||
|
||||
The vessel layer now uses `/api/v1/vessels/snapshot` for the initial viewport snapshot and the `/ws` `vessels` channel for realtime deltas. Snapshot requests must include `bbox`, `zoom`, and a bounded `limit`; the backend defaults to `limit=1000` and caps it at `5000`. WebSocket subscriptions must include the same viewport fields so the server can filter updates per connection.
|
||||
|
||||
The legacy `/api/v1/visualization/geo/vessels` endpoint has been removed and returns `410 Gone`. Frontend code should fetch a snapshot for the current viewport when the layer opens, then subscribe to `vessels` deltas. After map pan or zoom, reload the snapshot and send a fresh vessels subscription. The backend no longer merges legacy `vessel_position` / `vessel_static` rows into vessel snapshots, so the frontend must not depend on old BarentsWatch-only fallback rows.
|
||||
The legacy `/api/v1/visualization/geo/vessels` route has been removed. Frontend code should fetch a snapshot for the current viewport when the layer opens, then subscribe to `vessels` deltas. After map pan or zoom, reload the snapshot and send a fresh vessels subscription. The backend only falls back to legacy `vessel_position` / `vessel_static` rows when the current raw window is empty; frontend code can detect that state through `diagnostics.legacy_fallback_used`.
|
||||
|
||||
The new layer API family is `/api/v1/layers/*`, which separates map rendering payloads from aggregate panel statistics. Layer requests must include `bbox`, `zoom`, and a bounded `limit`; responses include `visible_count`, `returned_count`, and `diagnostics`, where `degraded`, `truncated`, and `limit_clamped` are the frontend signals for fallback UI. Right-side aggregate panels should not sum the layer response. They should read `/api/v1/data-products` or `/api/v1/data-products/{product_id}/status`, because those statistics stay global and do not change with the viewport.
|
||||
|
||||
|
||||
@@ -130,11 +130,12 @@ Steps:
|
||||
3. Keep the default endpoint `wss://stream.aisstream.io/v0/stream`
|
||||
4. Click the plug icon to test; confirm it reports `Reachable`
|
||||
5. Save collector settings
|
||||
6. Trigger the `aisstream_vessels` collector from the collection scheduler
|
||||
7. Watch the `AISStream Runtime` panel:
|
||||
6. Open the `Realtime Streams` tab on `/datasources` and find `AISStream Realtime Vessels`
|
||||
7. Use `Start`, `Stop`, or `Reconnect` there. The normal `Collection Tasks` tab does not count AISStream in one-click collection or percentage progress
|
||||
8. Watch the realtime stream panel:
|
||||
- `streaming` / `connected` means the live stream is being consumed
|
||||
- `messages this round` should keep growing
|
||||
- `disconnected` with `ConnectionResetError` means the upstream or network dropped; re-trigger or wait for reconnect
|
||||
- `total stored`, `last 24h`, `last 1h`, and `unique MMSI` show historical collection volume
|
||||
- `disconnected` with a recent error means the upstream or network dropped; click `Reconnect`
|
||||
|
||||
## Configure AI Credentials
|
||||
|
||||
@@ -203,7 +204,7 @@ To let a regular user read developer or operations docs, add `docs_developer` or
|
||||
|
||||
## Data Exploration
|
||||
|
||||
- `/datasources`: source directory. It can be filtered by product domain, layer/module, enabled state, last run status, whether collected records exist, and search text. Selecting rows triggers only those sources; with no selected rows, `Collect current filter` triggers the filtered scope. Clicking a name opens an info drawer showing endpoint, headers, base config, and built-in flag; endpoint/credentials editing happens at `/settings -> Collector Settings`. The `Collecting N` tag under the overall progress can be clicked to expand the current collection task list
|
||||
- `/datasources`: source directory. The `Collection Tasks` tab is for one-shot, scheduled, and finite collectors; it can be filtered by product domain, layer/module, enabled state, last run status, whether collected records exist, and search text. Selecting rows triggers only those sources; with no selected rows, `Collect current filter` triggers the filtered scope. The `Realtime Streams` tab is for AISStream / WebSocket long connections and shows connection health, stored totals, time-window counters, and Start / Stop / Reconnect actions. Clicking a name opens an info drawer showing endpoint, headers, base config, and built-in flag; endpoint/credentials editing happens at `/settings -> Collector Settings`. The `Collecting N` tag under the overall progress can be clicked to expand the current collection task list
|
||||
- `/data`: collected data table — used to verify "did data arrive", "is the freshness right", "does a source emit valid records"
|
||||
- `/bgp`: BGP detail page with list + detail + analysis; complements the BGP layer on Earth
|
||||
- `/alerts/system`, `/alerts/bgp`, `/alerts/situational`: system, BGP, and situational alerts
|
||||
|
||||
@@ -22,10 +22,10 @@ image_exists AND stamp_non_empty AND fingerprint_match
|
||||
|
||||
### Fix
|
||||
|
||||
The stamp file moved to a persistent cache path:
|
||||
The stamp file moved from a temporary location to a persistent cache path:
|
||||
|
||||
```bash
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="$HOME/.cache/planet/aiprovider_build.sha256"
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/planet/aiprovider_build.sha256"
|
||||
```
|
||||
|
||||
Writing the stamp creates the directory first:
|
||||
@@ -92,7 +92,7 @@ COPY aiprovider /app/aiprovider
|
||||
|
||||
### Runtime Configuration
|
||||
|
||||
Before starting AI Provider, `planet.sh` generates a temporary env-file and passes it to Compose or the manual `docker run` fallback. Configuration priority:
|
||||
Before starting AI Provider, `planet.sh` generates a current-user runtime env-file and passes it to Compose or the manual `docker run` fallback. The default path is `${XDG_STATE_HOME:-$HOME/.local/state}/planet/aiprovider_runtime.env`. Configuration priority:
|
||||
|
||||
1. `aiprovider/.env`
|
||||
2. simple `export AI_...=...` or `AI_...=...` lines from `~/.zshrc`
|
||||
@@ -188,6 +188,62 @@ Before the stamp path fix:
|
||||
|
||||
After moving the stamp file, plain `restart` uses the same `stop + start` behavior and the same fingerprint check as `restart -b`.
|
||||
|
||||
## State Files, Logs, and Failed-Start Cleanup
|
||||
|
||||
`planet.sh` no longer writes PID files, logs, or runtime env-files to fixed `/tmp/planet_*` paths. The default state directory is:
|
||||
|
||||
```bash
|
||||
${XDG_STATE_HOME:-$HOME/.local/state}/planet
|
||||
```
|
||||
|
||||
At startup the script creates this directory and tries to set it to `700`. The current files include:
|
||||
|
||||
- `backend.pid` / `frontend.pid` / `motion_agent.pid`
|
||||
- `backend.log` / `frontend.log` / `motion_agent.log`
|
||||
- `aiprovider_build.log`
|
||||
- `aiprovider_runtime.env`
|
||||
- `ports.env`
|
||||
|
||||
PID writes validate that the PID is a positive integer, include a trailing newline, and try to set file mode `600`. PID reads ignore invalid content instead of passing it to `kill`.
|
||||
|
||||
After a successful `start`, the script records the ports in `ports.env`. Later `./planet.sh health` calls prefer the last started ports; if the state file is missing, health checks fall back to the defaults `8000`, `3000`, `8010`, and `8765`. This avoids checking default ports after starting with custom ports.
|
||||
|
||||
Startup now has light failed-start cleanup. If `start` exits before completing, the script only cleans local processes that this run already started: backend, frontend, and Motion Agent. It does not stop services after a successful start. AI Provider, PostgreSQL, and Redis keep their existing container lifecycle behavior.
|
||||
|
||||
## Health Checks and Hardening
|
||||
|
||||
HTTP readiness checks now use `curl -fsS --max-time`, so 4xx and 5xx responses are no longer treated as healthy.
|
||||
|
||||
Process termination now validates:
|
||||
|
||||
- signal names are limited to `TERM`, `KILL`, `INT`, and `HUP`;
|
||||
- PIDs must be positive integers;
|
||||
- process group IDs must be positive integers.
|
||||
|
||||
This prevents bad PID files or invalid signals from reaching `kill`.
|
||||
|
||||
Frontend and Motion Agent startup failures now call `print_port_listener_details()`, matching backend port diagnostics. The Windows-side listener and cleanup path still only runs when WSL is detected.
|
||||
|
||||
## Cross-Platform Notes
|
||||
|
||||
The script is currently Linux-first with WSL enhancements. Normal Linux runs do not execute the PowerShell path; WSL gets extra Windows listener, portproxy, and camera guidance.
|
||||
|
||||
To make this single script fully portable across Linux, macOS, and WSL, the remaining platform differences should be wrapped behind compatibility helpers:
|
||||
|
||||
- `stat --format`, `sort -V`, and `xargs -r` are GNU-style and are not fully compatible with default macOS BSD tools.
|
||||
- `hostname -I`, `ss`, `fuser`, and `systemctl` are usually unavailable on macOS.
|
||||
- `tac` may be missing on macOS; use `awk` or Python as a fallback.
|
||||
- Docker Desktop on macOS does not use `systemctl` daemon diagnostics.
|
||||
- Camera auto-detection relies on `/dev/video*` / `v4l2-ctl`, which is Linux-specific; macOS should use explicit camera URLs or a separate AVFoundation detector.
|
||||
|
||||
The recommended direction is a small platform compatibility layer for port listener detection, version comparison, file metadata, reverse tail, LAN IP discovery, and Docker daemon diagnostics, instead of scattering more platform branches throughout service startup logic.
|
||||
|
||||
## Production Delivery Boundary
|
||||
|
||||
`planet.sh` is a local development convenience script, not the production startup entrypoint. Production delivery should use Kubernetes `Deployment`, `Service`, `Ingress`, and readiness/liveness probes for ports, health checks, restarts, and rolling upgrades. This removes the need for a host script to reclaim local ports and avoids running the Vite dev server in production.
|
||||
|
||||
The production frontend shape is `vite build` static output served by nginx/Caddy or an equivalent HTTP server. Do not use `bun run dev` or `vite preview` in production. The project does not maintain a parallel Webpack build chain; if a future enterprise requirement needs closer Webpack-ecosystem compatibility, run an Rsbuild/Rspack spike first. Electron should only be evaluated when the official target becomes an offline desktop application.
|
||||
|
||||
## Optional Motion Agent Startup
|
||||
|
||||
`planet.sh` can now manage the local Motion Capture Agent. It is disabled by default so ordinary development machines do not fail startup when cameras, OpenCV, or MediaPipe are unavailable.
|
||||
|
||||
@@ -34,7 +34,7 @@ After landing on the `/admin` dashboard, here's a recommended walk-through:
|
||||
|
||||
1. `/settings?tab=collector_credentials`: pick a collector and click the plug icon to test connectivity. Free collectors (e.g. open BGP) usually work right away; credential-bearing ones like `AISStream` or `BarentsWatch` need an API key / client secret first
|
||||
2. `/ai?tab=providers`: fill an LLM provider (e.g. `minimax` / `openai`), model, base URL, API key, and click the plug at the end of the base URL to test. WebSearch / OCR tools are optional
|
||||
3. `/datasources` or `/data`: check whether the collectors have produced data
|
||||
3. `/datasources` or `/data`: check whether collectors have produced data. Use `/datasources -> Collection Tasks` for finite collectors, and `/datasources -> Realtime Streams` for AISStream / WebSocket health and counters
|
||||
4. `/alerts/system`: verify system alerts look right
|
||||
5. `/users` (super_admin only): open accounts for teammates or adjust their groups
|
||||
|
||||
|
||||
@@ -326,6 +326,17 @@ AISStream 使用 `wss://stream.aisstream.io/v0/stream` WebSocket endpoint。默
|
||||
|
||||
AISStream 连接验证会通过 `datasource_connectivity.py` 读取保存的采集器配置、环境变量和 `~/.zshrc` 中的 `AISSTREAM_API_KEY`。正式采集时,最稳妥的方式是把 API Key 保存到“设置 -> 采集器设置 -> AISStream 实时船舶”;如果只放在 `~/.zshrc`,需要确认后端进程实际继承到了该环境变量。
|
||||
|
||||
控制台通过 `/datasources -> 实时流` 管理 AISStream,而不是把它放进普通有限采集任务的进度条。实时流 API 会聚合运行态、健康状态、配置摘要和 raw observation 计数:
|
||||
|
||||
```http
|
||||
GET /api/v1/realtime-sources
|
||||
POST /api/v1/realtime-sources/{source}/start
|
||||
POST /api/v1/realtime-sources/{source}/stop
|
||||
POST /api/v1/realtime-sources/{source}/restart
|
||||
```
|
||||
|
||||
`aisstream_vessels` 和自定义 `source_type=websocket` 数据源会出现在该接口中。它们不参与一键采集百分比;前端按长连接服务展示消息计数、延迟、最近成功和最近错误。
|
||||
|
||||
### AIS 原始观测与聚合
|
||||
|
||||
AIS 观测写入后不会直接替换最终船只记录,而是先保存为 raw observation:
|
||||
@@ -345,7 +356,7 @@ GET /api/v1/visualization/vessels/{mmsi}/track
|
||||
GET /api/v1/visualization/vessels/{mmsi}/conflicts
|
||||
```
|
||||
|
||||
`/api/v1/vessels/snapshot` 必须携带 `bbox` 和 `zoom`,默认 `limit=1000`,最大 `limit=5000`。它只消费 `ais_raw_observations` 聚合结果,不再读取 legacy `vessel_position` / `vessel_static` 作为兜底。旧 `/api/v1/visualization/geo/vessels` 已下线并返回 `410 Gone`。
|
||||
`/api/v1/vessels/snapshot` 必须携带 `bbox` 和 `zoom`,默认 `limit=1000`,最大 `limit=5000`。它优先消费 `ais_raw_observations` 聚合结果;当当前 raw 窗口为空时,会受控回退到 legacy `vessel_position` / `vessel_static` 最新点,并在 `diagnostics.legacy_fallback_used` 中标明。旧 `/api/v1/visualization/geo/vessels` 路由已移除。
|
||||
|
||||
实时增量通过 `/ws` 的 `vessels` channel 推送。客户端订阅时必须带当前视口:
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ AISStream 使用 WebSocket 实时流,采集器只写入 `ais_raw_observations`
|
||||
|
||||
连接验证会读取保存配置、环境变量和 `~/.zshrc` 中的 `AISSTREAM_API_KEY`。正式采集时,推荐把 API Key 保存到采集器设置;如果只写在 `~/.zshrc`,需要确认后端进程实际继承了该变量,否则连接验证可能可用但 collector 运行时拿不到 key。
|
||||
|
||||
连接验证和正式采集是两个不同动作。设置页出现 `AISStream 凭证已配置,WebSocket endpoint 格式有效` 只说明配置可以用于连接;运行状态仍可能是 `disconnected`。只有 `aisstream_vessels` collector 任务处于 `streaming` / `connected`,并且 `本轮消息数`、`last_seen_at` 持续更新时,全球 AIS 数据才会不断写入本地库。
|
||||
连接验证和正式采集是两个不同动作。设置页出现 `AISStream 凭证已配置,WebSocket endpoint 格式有效` 只说明配置可以用于连接;运行状态仍可能是 `disconnected`。只有 `aisstream_vessels` 处于 `streaming` / `connected`,并且实时流计数、`last_seen_at` 持续更新时,全球 AIS 数据才会不断写入本地库。启动、停止、重连、健康状态和计数统一从 `/datasources -> 实时流` 和 `/api/v1/realtime-sources` 查看;AISStream 不再参与普通一键采集进度。
|
||||
|
||||
新版本不再使用 legacy `/api/v1/visualization/geo/vessels` 作为船只列表入口。Earth 初始状态应调用:
|
||||
|
||||
@@ -298,7 +298,7 @@ AISStream 使用 WebSocket 实时流,采集器只写入 `ais_raw_observations`
|
||||
GET /api/v1/vessels/snapshot?bbox=lon_min,lat_min,lon_max,lat_max&zoom=12&limit=1000
|
||||
```
|
||||
|
||||
该接口只查询本地 `ais_raw_observations` 聚合结果。实时更新走 `/ws` 的 `vessels` channel,订阅时必须提供 `bbox`、`zoom` 和 `limit`。服务端按连接过滤 bbox,并对 collector 广播做 1 秒合并,同一 MMSI 只推送最新位置。
|
||||
该接口优先查询本地 `ais_raw_observations` 聚合结果;当当前 raw 窗口为空时,会受控回退到 legacy `vessel_position` / `vessel_static` 最新点,并通过 `diagnostics.legacy_fallback_used` 暴露。实时更新走 `/ws` 的 `vessels` channel,订阅时必须提供 `bbox`、`zoom` 和 `limit`。服务端按连接过滤 bbox,并对 collector 广播做 1 秒合并,同一 MMSI 只推送最新位置。
|
||||
|
||||
## 自定义 REST / WebSocket 映射运行时
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ AIS 船只图层入口:
|
||||
|
||||
AISStream 的 `PositionReport` 常带实时位置和 `MetaData.ShipName`,但船型通常来自低频 `ShipStaticData.Type`。后端会把 `MetaData.ShipName` 补进船名,并将类型码映射为 Cargo / Tanker / Passenger / Fishing / Military;仍缺失的船型需要等待静态 AIS 消息或后续船舶资料 enrichment,不能在前端凭颜色之外的信息臆造细分类。
|
||||
|
||||
旧 `/api/v1/visualization/geo/vessels` 已下线并返回 `410 Gone`。前端打开船只图层时应先按当前视口拉一次 `/api/v1/vessels/snapshot`,再用 WebSocket 接收同一视口内的 upsert 增量;地图拖动或缩放后应重新拉取 snapshot 并重发 vessels 订阅。后端不再把 legacy `vessel_position` / `vessel_static` 合并进船只快照,前端也不应依赖旧表里的 BarentsWatch-only 兜底数据。
|
||||
旧 `/api/v1/visualization/geo/vessels` 路由已移除。前端打开船只图层时应先按当前视口拉一次 `/api/v1/vessels/snapshot`,再用 WebSocket 接收同一视口内的 upsert 增量;地图拖动或缩放后应重新拉取 snapshot 并重发 vessels 订阅。后端只在当前 raw 窗口为空时受控回退到 legacy `vessel_position` / `vessel_static`,前端可通过 `diagnostics.legacy_fallback_used` 识别该状态。
|
||||
|
||||
新的图层接口族是 `/api/v1/layers/*`,用于把地图渲染数据和聚合面板统计分开。地图层请求必须带 `bbox`、`zoom` 和受控 `limit`,响应会返回 `visible_count`、`returned_count` 和 `diagnostics`,其中 `degraded/truncated/limit_clamped` 用于前端提示降级。右侧聚合统计不要从图层响应累加,应读取 `/api/v1/data-products` 或 `/api/v1/data-products/{product_id}/status`,因为这些统计保持全量/全局口径,不随当前视口变化。
|
||||
|
||||
|
||||
@@ -133,11 +133,12 @@
|
||||
3. Endpoint 保持默认 `wss://stream.aisstream.io/v0/stream`
|
||||
4. 点击插头图标进行连接测试,确认显示 `可用`
|
||||
5. 保存采集器设置
|
||||
6. 到采集调度入口运行 `aisstream_vessels` collector
|
||||
7. 在 `AISStream 运行状态` 中观察:
|
||||
- `streaming` / `connected` 表示正在接收实时流
|
||||
- `本轮消息数` 应持续增长
|
||||
- 如果显示 `disconnected` 且错误为 `ConnectionResetError`,需要重新触发或等待重连
|
||||
6. 打开 `/datasources` 的 `实时流` tab,找到 `AISStream 实时船舶`
|
||||
7. 点击 `启动`、`停止` 或 `重连` 管理长连接;这里不显示百分比进度
|
||||
8. 在实时流卡片中观察:
|
||||
- `connected` 表示正在接收实时流
|
||||
- `累计入库`、`近 24h`、`近 1h` 和 `唯一 MMSI` 用于判断历史采集量
|
||||
- 如果显示 `disconnected` 且有最近错误,可以点击 `重连`
|
||||
|
||||
## 配置 AI 凭证
|
||||
|
||||
@@ -206,7 +207,7 @@ Base URL 输入框尾端的插头图标会触发连接测试。测试通过会
|
||||
|
||||
## 数据探索
|
||||
|
||||
- `/datasources`:数据源目录。可以按产品域、层级、启用状态、最近执行状态、是否已有采集数据和关键词筛选;勾选多行后可批量采集选中项,未勾选时“采集当前筛选”只触发当前筛选范围。点击名称打开信息抽屉查看 endpoint、请求头、基础配置和是否内置;接口、凭证、请求头的编辑统一在 `/settings` 的"采集器设置"。总体进度下方的 `采集中 N` 标签可点击,展开当前采集任务列表
|
||||
- `/datasources`:数据源目录。`采集任务` tab 面向一次性/定时采集器,可以按产品域、层级、启用状态、最近执行状态、是否已有采集数据和关键词筛选;勾选多行后可批量采集选中项,未勾选时“一键采集”触发当前筛选范围。`实时流` tab 面向 AISStream / WebSocket 长连接,展示连接健康、累计入库、时间窗统计和启动 / 停止 / 重连操作。点击名称打开信息抽屉查看 endpoint、请求头、基础配置和是否内置;接口、凭证、请求头的编辑统一在 `/settings` 的"采集器设置"。总体进度下方的 `采集中 N` 标签可点击,展开当前采集任务列表
|
||||
- `/data`:采集后数据表,适合排查"数据是否已经进入系统"、"更新时间是否符合预期"、"某个数据源是否产出有效记录"
|
||||
- `/bgp`:BGP 专题页面,列表 + 详情 + 研判,与 Earth 的 BGP 图层互补
|
||||
- `/alerts/system`、`/alerts/bgp`、`/alerts/situational`:系统、BGP、态势告警
|
||||
|
||||
@@ -22,10 +22,10 @@ image_exists AND stamp_non_empty AND fingerprint_match
|
||||
|
||||
### 修复
|
||||
|
||||
将戳文件路径从 `/tmp/` 改到持久路径:
|
||||
将戳文件路径从临时目录改到持久缓存路径:
|
||||
|
||||
```bash
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="$HOME/.cache/planet/aiprovider_build.sha256"
|
||||
AI_PROVIDER_BUILD_STAMP_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/planet/aiprovider_build.sha256"
|
||||
```
|
||||
|
||||
写入时确保目录存在:
|
||||
@@ -94,7 +94,7 @@ COPY aiprovider /app/aiprovider
|
||||
|
||||
### 运行期配置来源
|
||||
|
||||
`planet.sh` 启动 AI Provider 前会生成临时 env-file,并把它传给 Compose 或手动 `docker run` fallback。配置优先来自:
|
||||
`planet.sh` 启动 AI Provider 前会生成受当前用户保护的运行期 env-file,并把它传给 Compose 或手动 `docker run` fallback。默认路径位于 `${XDG_STATE_HOME:-$HOME/.local/state}/planet/aiprovider_runtime.env`。配置优先来自:
|
||||
|
||||
1. `aiprovider/.env`
|
||||
2. `~/.zshrc` 中简单的 `export AI_...=...` 或 `AI_...=...` 行
|
||||
@@ -202,6 +202,62 @@ PY
|
||||
|
||||
修复戳文件路径后,无参 `restart` 同样使用 `stop + start`,fingerprint 检查正常生效,行为与 `restart -b` 完全一致。无需额外代码变更。
|
||||
|
||||
## 状态文件、日志与失败清理
|
||||
|
||||
`planet.sh` 不再把 PID、日志和运行期 env-file 写入固定 `/tmp/planet_*` 路径。默认状态目录为:
|
||||
|
||||
```bash
|
||||
${XDG_STATE_HOME:-$HOME/.local/state}/planet
|
||||
```
|
||||
|
||||
脚本启动时会创建该目录并尽量设置为 `700`。当前使用的文件包括:
|
||||
|
||||
- `backend.pid` / `frontend.pid` / `motion_agent.pid`
|
||||
- `backend.log` / `frontend.log` / `motion_agent.log`
|
||||
- `aiprovider_build.log`
|
||||
- `aiprovider_runtime.env`
|
||||
- `ports.env`
|
||||
|
||||
PID 文件写入前会校验 PID 为正整数,写入时带换行并尽量设置为 `600`。读取 PID 文件时,如果内容不是数字,脚本会忽略该文件,不会把垃圾内容传给 `kill`。
|
||||
|
||||
`start` 成功后会把本次端口写入 `ports.env`。后续执行 `./planet.sh health` 时,会优先检查上次启动端口;如果没有状态文件,则回退到默认端口 `8000`、`3000`、`8010`、`8765`。这避免了用自定义端口启动后,健康检查仍只看默认端口的问题。
|
||||
|
||||
启动过程有轻量失败清理:如果 `start` 中途失败,脚本只清理本轮已经拉起的本地进程(backend、frontend、Motion Agent),不会在正常启动完成后停止服务。AI Provider、PostgreSQL 和 Redis 容器仍按原有容器生命周期管理。
|
||||
|
||||
## 健康检查与安全加固
|
||||
|
||||
HTTP 健康检查统一使用 `curl -fsS --max-time`。因此 `/health` 返回 4xx/5xx 不再被视为在线。
|
||||
|
||||
进程终止路径现在会校验:
|
||||
|
||||
- signal 只允许 `TERM`、`KILL`、`INT`、`HUP`;
|
||||
- PID 必须是正整数;
|
||||
- 进程组 PGID 必须是正整数。
|
||||
|
||||
这可以避免坏 PID 文件或错误 signal 造成不可预期的 `kill` 行为。
|
||||
|
||||
前端和 Motion Agent 启动失败时,现在也会调用 `print_port_listener_details()`,输出与后端一致的端口监听诊断。WSL 下如果端口看起来被 Windows 侧占用,脚本仍只在检测到 WSL 时才调用 PowerShell 诊断或清理路径。
|
||||
|
||||
## 跨平台注意事项
|
||||
|
||||
当前脚本是 Linux-first,并带有 WSL 增强。普通 Linux 不会执行 WSL PowerShell 逻辑;WSL 下会额外提供 Windows listener、portproxy 和摄像头提示。
|
||||
|
||||
如果要把同一份脚本扩展为 Linux、macOS、WSL 三平台通用,还需要继续封装这些命令差异:
|
||||
|
||||
- `stat --format`、`sort -V`、`xargs -r` 是 GNU 风格,macOS 默认 BSD 工具不完全兼容。
|
||||
- `hostname -I`、`ss`、`fuser`、`systemctl` 在 macOS 上通常不可用。
|
||||
- `tac` 在 macOS 上不一定存在,可用 `awk` 或 Python 兜底。
|
||||
- Docker Desktop on macOS 不适用 `systemctl` daemon 诊断。
|
||||
- 摄像头自动发现依赖 `/dev/video*` / `v4l2-ctl`,这是 Linux 路线;macOS 应显式使用 camera URL 或另做 AVFoundation 检测。
|
||||
|
||||
维护方向是增加一个小的 platform compatibility 层,把端口监听检测、版本比较、文件元信息、反向 tail、LAN IP 获取和 Docker daemon 诊断集中处理,而不是在业务启动流程里继续散落平台判断。
|
||||
|
||||
## 正式交付边界
|
||||
|
||||
`planet.sh` 是本地开发便利脚本,不作为正式生产启动入口。正式交付应通过 Kubernetes 的 `Deployment`、`Service`、`Ingress`、readiness/liveness probe 管理端口、健康检查、重启和滚动发布。这样生产环境不需要脚本抢占宿主机端口,也不会依赖 Vite dev server。
|
||||
|
||||
前端生产形态是 `vite build` 生成静态资源,再由 nginx/Caddy 等 HTTP 服务器托管。不要在生产中使用 `bun run dev` 或 `vite preview`。当前不维护 Webpack 双构建链;如果未来需要评估更企业化的构建生态,优先做 Rsbuild/Rspack spike。Electron 仅在正式目标变成离线桌面软件时再单独评估。
|
||||
|
||||
## Motion Agent 可选启动
|
||||
|
||||
`planet.sh` 现在可以管理本地动作捕捉 Agent,但默认不会启动它,避免普通开发机因为没有摄像头、OpenCV 或 MediaPipe 而影响后端/前端启动。
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
1. `/settings?tab=collector_credentials`:选一个采集器,点插头图标做连接测试。免费 collector(开源 BGP 等)通常直接可用;像 `AISStream`、`BarentsWatch` 这类需要凭证的,需要先填 API Key/Client Secret
|
||||
2. `/ai?tab=providers`:填一个 LLM provider(例如 `minimax` / `openai`)、模型名、Base URL、API Key,点 Base URL 末端的插头测试连接。WebSearch / OCR 工具可选
|
||||
3. `/datasources` 或 `/data`:看采集器是否已经产出数据
|
||||
3. `/datasources` 或 `/data`:看采集器是否已经产出数据。有限采集器看 `/datasources -> 采集任务`,AISStream / WebSocket 长连接看 `/datasources -> 实时流` 的健康状态和计数
|
||||
4. `/alerts/system`:看系统告警是否正常
|
||||
5. `/users`(仅 `super_admin`):根据需要给同事开账号或调权限组
|
||||
|
||||
|
||||
Reference in New Issue
Block a user