arc-kernel 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/Install.md +93 -10
  2. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/PKG-INFO +1 -1
  3. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/__init__.py +1 -1
  4. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/cli.py +512 -112
  5. arc_kernel-0.1.2/arc/deploy.py +673 -0
  6. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/doctor.py +75 -1
  7. arc_kernel-0.1.2/arc/log.py +636 -0
  8. arc_kernel-0.1.2/arc/log_collector.py +401 -0
  9. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/settings.py +34 -25
  10. arc_kernel-0.1.2/arc/sizing.py +341 -0
  11. arc_kernel-0.1.2/arc/status.py +514 -0
  12. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/store.py +34 -33
  13. arc_kernel-0.1.2/arc/supervision.py +150 -0
  14. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/pyproject.toml +1 -1
  15. arc_kernel-0.1.2/tests/test_cli_run_console.py +149 -0
  16. arc_kernel-0.1.2/tests/test_connection_budget.py +174 -0
  17. arc_kernel-0.1.2/tests/test_connection_plan_cli.py +319 -0
  18. arc_kernel-0.1.2/tests/test_deploy_sizing.py +239 -0
  19. arc_kernel-0.1.2/tests/test_deploy_split.py +350 -0
  20. arc_kernel-0.1.2/tests/test_log.py +107 -0
  21. arc_kernel-0.1.2/tests/test_log_collector.py +604 -0
  22. arc_kernel-0.1.2/tests/test_logs_serve.py +128 -0
  23. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_settings.py +69 -0
  24. arc_kernel-0.1.2/tests/test_status.py +358 -0
  25. arc_kernel-0.1.2/tests/test_supervision.py +255 -0
  26. arc_kernel-0.1.1/arc/deploy.py +0 -410
  27. arc_kernel-0.1.1/arc/log.py +0 -225
  28. arc_kernel-0.1.1/arc/sizing.py +0 -74
  29. arc_kernel-0.1.1/tests/test_cli_run_console.py +0 -76
  30. arc_kernel-0.1.1/tests/test_log.py +0 -29
  31. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/.gitignore +0 -0
  32. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/LICENSE +0 -0
  33. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/README.md +0 -0
  34. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/_state.py +0 -0
  35. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/codec.py +0 -0
  36. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/crypto.py +0 -0
  37. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/events.py +0 -0
  38. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/health.py +0 -0
  39. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/healthcmd.py +0 -0
  40. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/kernel.py +0 -0
  41. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/metrics.py +0 -0
  42. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/plugin_cli.py +0 -0
  43. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/py.typed +0 -0
  44. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/registry.py +0 -0
  45. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/resolver.py +0 -0
  46. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/runtime.py +0 -0
  47. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/secrets.py +0 -0
  48. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/stubs.py +0 -0
  49. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/tracing.py +0 -0
  50. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/tz.py +0 -0
  51. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/update.py +0 -0
  52. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/arc/uuid7.py +0 -0
  53. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/docs/arc-kernel.MD +0 -0
  54. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/setup.sh +0 -0
  55. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/__init__.py +0 -0
  56. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/conftest.py +0 -0
  57. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_boot.py +0 -0
  58. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_cli_perform.py +0 -0
  59. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_cli_restart.py +0 -0
  60. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_crypto.py +0 -0
  61. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_events.py +0 -0
  62. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_kernel.py +0 -0
  63. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_metrics.py +0 -0
  64. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_new_plugin_scaffold.py +0 -0
  65. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_process_registry.py +0 -0
  66. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_resolver_versions.py +0 -0
  67. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_run_async.py +0 -0
  68. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_run_lock.py +0 -0
  69. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_tracing.py +0 -0
  70. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_tz.py +0 -0
  71. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_update.py +0 -0
  72. {arc_kernel-0.1.1 → arc_kernel-0.1.2}/tests/test_uuid7.py +0 -0
@@ -43,7 +43,7 @@ Then: [verify](#verify-everything), [keep it running and put it on the internet]
43
43
 
44
44
  You do not need a compiler or any `-dev` libraries: every Python dependency installs from a prebuilt wheel.
45
45
 
46
- **How this guide was checked.** The steps below were run from an empty directory against a freshly initialised, private PostgreSQL 14.24 and Redis 6.0.16, on Ubuntu 22.04 with Python 3.12, Node 20.20.2 and Yarn 1.22.22 — ending in a real login and successful calls to the Admin API. In that run the repositories were cloned from local copies confirmed to be at the same commits as GitHub's `main`. Step 3 was then checked separately against the real PyPI package: `pip install arc-kernel` inside a Python 3.12 virtualenv, `uv tool install arc-kernel`, and the failure quoted there on Python 3.10; then `arc init` with the kernel cloned straight from GitHub, `arc install` of `pgdb` from GitHub, and `arc doctor` (the later steps were not repeated on that second project). Things that were **not** run are marked *(not run)*: the `arc deploy` commands, the server-wide `setup.sh`, Valkey, and every OS other than Ubuntu.
46
+ **How this guide was checked.** The steps below were run from an empty directory against a freshly initialised, private PostgreSQL 14.24 and Redis 6.0.16, on Ubuntu 22.04 with Python 3.12, Node 20.20.2 and Yarn 1.22.22 — ending in a real login and successful calls to the Admin API. In that run the repositories were cloned from local copies confirmed to be at the same commits as GitHub's `main`. Step 3 was then checked separately against the published PyPI package, version 0.1.1: `pip install arc-kernel` inside a Python 3.12 virtualenv, `uv tool install arc-kernel`, and the failure quoted there on Python 3.10; then `arc init` with the kernel cloned straight from GitHub (it wrote `.vscode/settings.json` and `.gitignore` excluded the settings store), `arc install` of `pgdb` from GitHub, and `arc doctor` (the later steps were not repeated on that second project). Things that were **not** run are marked *(not run)*: `arc deploy prod` (system-wide units, nginx and certbot — its units were checked with `systemd-analyze verify` and unit tests only), the server-wide `setup.sh`, Valkey, and every OS other than Ubuntu. `arc deploy dev` was run against a scratch project and driven through crash tests under a real `systemd --user` manager, and `arc deploy dev --enable` was used to switch a running server from the old single `arc run` unit (about 9 seconds of downtime for the switch).
47
47
 
48
48
  ---
49
49
 
@@ -105,7 +105,7 @@ arc --help
105
105
  **The `pip` has to belong to Python 3.12 or newer** — the package declares `Requires-Python >=3.12`. Check with `pip --version`: it should end in `(python 3.12)` or later. On Ubuntu 22.04, whose default Python is 3.10, pip refuses with:
106
106
 
107
107
  ```
108
- ERROR: Ignored the following versions that require a different python version: 0.1.0 Requires-Python >=3.12
108
+ ERROR: Ignored the following versions that require a different python version: 0.1.0 Requires-Python >=3.12; 0.1.1 Requires-Python >=3.12
109
109
  ERROR: Could not find a version that satisfies the requirement arc-kernel (from versions: none)
110
110
  ERROR: No matching distribution found for arc-kernel
111
111
  ```
@@ -124,7 +124,9 @@ uv tool install arc-kernel
124
124
 
125
125
  If your shell says `arc: command not found` after (b), run `uv tool update-shell` and open a new shell. Avoid `sudo pip install arc-kernel` into the system Python: recent distributions (Ubuntu 24.04, Debian 12) mark it "externally managed" and refuse global `pip install`s *(not run)*, which is what the virtualenv in (a) sidesteps.
126
126
 
127
- This global `arc` only bootstraps projects. `arc init` (step 5) clones the kernel into your project, and from then on the project's own copy is the `arc` you use. So the published package can lag behind the kernel on GitHub without harm, apart from one small gap that step 5 shows how to close.
127
+ Use version **0.1.1 or newer** (`pip show arc-kernel`; upgrade with `pip install -U arc-kernel`). 0.1.0 is older than the kernel `arc init` clones, and its `arc init` writes a `.gitignore` that does not exclude `.arc/arc.store.db`, the encrypted settings store.
128
+
129
+ This global `arc` only bootstraps projects. `arc init` (step 5) clones the kernel into your project, and from then on the project's own copy is the `arc` you use.
128
130
 
129
131
  > Setting up a shared server where several people will each create projects? `setup.sh` in this repository installs `uv`, Python 3.12 and `arc` system-wide for every user *(not run)*:
130
132
  > `sudo ARC_KERNEL_REPO=https://github.com/vignesh-ramsh/arc.git ./setup.sh`
@@ -178,8 +180,6 @@ Run this as your normal user, not with `sudo`. To avoid typing the URL every tim
178
180
  | `pyproject.toml`, `.venv/` | a [uv workspace](https://docs.astral.sh/uv/concepts/projects/workspaces/) tying the kernel and every plugin into one virtual environment |
179
181
  | `.gitignore` | already excludes the master key, the settings store, `.venv/`, `arc/` and `plugins/*/` |
180
182
 
181
- > **Look for `Wrote …/.vscode/settings.json` in the output.** If it is missing, the `arc` you installed from PyPI is older than the kernel it just cloned. An older `arc init` does not yet write that file (it enables the red-underline checks for table and field names in VS Code), and its `.gitignore` leaves out `.arc/arc.store.db`, the encrypted settings store, so `git add .` would commit it. With the project's virtualenv active (as above), run `arc init .` once more — it is safe to repeat: it keeps your master key and existing files and only adds what is missing.
182
-
183
183
  > **Back up `.arc/arc.mkey`.** It encrypts every secret ARC stores, including your database password. Lose it and those secrets cannot be recovered — ARC will report `Could not decrypt secret … wrong master key, or the store is corrupt`. `arc init` keeps it out of git on purpose; keep a copy somewhere safe.
184
184
 
185
185
  ## 6. Install the plugins
@@ -315,6 +315,7 @@ arc health
315
315
 
316
316
  - `arc doctor` prints the plugin load order and ends with **`Boot resolution OK.`** Two lines starting `warning: optional ordering skipped` are normal and expected — they describe a harmless dependency cycle, not a problem.
317
317
  - `arc pgdb status` and `arc redix status` should each print `OK` with a latency.
318
+ - `arc status` (once you have deployed with `arc deploy`) shows every process that should be running and whether it is; it exits 1 if anything is off.
318
319
  - `arc health` lists each capability with `ok: yes`. For a deeper check that really opens connections and reports pool sizes and settings drift, use `arc doctor --deep`.
319
320
 
320
321
  From another terminal, a quick end-to-end check:
@@ -330,23 +331,92 @@ A `403` on `/whoami` before logging in is correct, not a fault.
330
331
 
331
332
  ## Keep it running and put it on the internet
332
333
 
333
- `arc run` stops when you close the terminal. These two commands turn it into a service *(not run — read from the commands' own `--help`)*.
334
+ `arc run` stops when you close the terminal, and if one of its processes keeps crashing it stops everything. For a server people use, let systemd supervise **each process on its own**. Both commands below install one unit per process — the log writer, the gateway, the background-job workers (one set per queue), the scheduler — grouped under `arc-<project>.target`. systemd restarts exactly the process that died; a process that keeps crashing ends as one `failed` unit (5 starts in 120 s) while the rest keep running. In testing against a real `systemd --user` manager, killing a job worker, a web worker, the gateway or the log writer never took the site down for longer than the gateway's own restart (about 4.5 s when the gateway master itself dies), and the other units' restart counters stayed at 0. The user-level commands were run; the system-wide ones need root, so they were checked with systemd's own `systemd-analyze verify` and unit tests, but not run *(not run)*.
334
335
 
335
- **A per-user systemd service** — no root needed:
336
+ **Development or a small server: a per-user service** — no root needed:
336
337
 
337
338
  ```bash
338
339
  arc deploy dev --enable
339
340
  ```
340
341
 
341
- This installs a `systemd --user` unit whose command is `arc run`, starts it, keeps it running across logouts, and sets `restart_command` so `arc restart` works.
342
+ This runs **2 web workers, 1 worker per queue and 1 scheduler**, keeps them running across logouts and reboots, and sets `restart_command` so `arc restart` works. Without `--enable` it only writes the units and never changes what is running.
342
343
 
343
- **nginx and HTTPS in front of it** — needs root:
344
+ **Production: system-wide units plus nginx and HTTPS** — needs root:
344
345
 
345
346
  ```bash
346
347
  sudo "$(command -v arc)" deploy prod --domain app.example.com
347
348
  ```
348
349
 
349
- This writes an nginx site for that domain that proxies to `arc run`, and obtains a Let's Encrypt certificate with certbot. Use `--no-ssl` for plain HTTP, and `--port` if you changed `arc run`'s port. It only touches its own nginx site file. Run it from inside your project with the virtualenv active: `sudo` does not inherit your `PATH`, so a bare `sudo arc` usually cannot find a user-installed `arc`, and `"$(command -v arc)"` hands `sudo` the full path to the project's copy.
350
+ This writes an nginx site for that domain that proxies to the app and obtains a Let's Encrypt certificate with certbot (`--no-ssl` for plain HTTP; `--port` to change the app's internal port, default 8001). It then installs the same units under `/etc/systemd/system`, run as the project's owner (never root), started on boot, **sized from the machine**: as many web workers as the CPU and memory allow (never more than 8 automatically), and the same number of job workers in total, shared out over the queues with at least one each. The app starts last, so it comes up with the final settings. `arc restart` runs `sudo systemctl restart arc-<project>.target`, so the project's owner needs passwordless sudo for exactly that command. It only touches this project's own units and nginx site. Run it from inside your project with the virtualenv active: `sudo` does not inherit your `PATH`, and `"$(command -v arc)"` hands it the full path to the project's copy.
351
+
352
+ **Choosing how many workers.** The defaults are only a starting point. Set what you want, then run the same `arc deploy` command again — the counts are read when it runs, and it removes the units of workers you no longer have:
353
+
354
+ | Setting | Meaning |
355
+ |---|---|
356
+ | `gateway_workers` | web worker processes (any number; yours wins over the default in both modes) |
357
+ | `lineup_workers_per_queue` | job workers for **every** queue |
358
+ | `lineup_workers_<queue>` | job workers for one queue, e.g. `arc settings set lineup_workers_mail 3` |
359
+
360
+ The scheduler is always exactly one: more would fire every cron job twice.
361
+
362
+ **Database connections.** Every process holds its own connection pool, so a deployment opens *(processes × pool size)* connections, and PostgreSQL refuses the ones past its limit. You do not have to work that out: `arc deploy` (and `arc run`) ask PostgreSQL what this application may open, keep a few free for yourself, and split the rest over the processes. It reads the real limit — `max_connections` minus the superuser reserve, or the role's or database's own `CONNECTION LIMIT` if that is lower — never an assumed 100. For the dev sizing on a default server it prints:
363
+
364
+ ```
365
+ Database connections: 97 usable (max_connections 100 − 3 reserved for superusers), 10 kept free
366
+ gateway-worker 2 × 10 = 20
367
+ lineup-worker 2 × 5 = 10
368
+ lineup-scheduler 1 × 2 = 2
369
+ 32 of 87 available for the application
370
+ ```
371
+
372
+ If the processes would not fit even at the smallest useful pool (2 per web or job worker, 1 for the scheduler), the command stops before it writes anything and says by how much; run fewer workers or raise `max_connections`. If the pools only fit by shrinking, they are all shrunk together, and what is left over goes back to the web workers first.
373
+
374
+ | Setting | Meaning |
375
+ |---|---|
376
+ | `pgdb_connection_reserve` | Connections kept free for migrations, `arc console`, backups and your own `psql` (default 10) |
377
+ | `pgdb_connection_budget` | Total connections ARC may use, when PostgreSQL's own numbers are not the real limit — behind PgBouncer, or on a managed database that hides them. Default `0` = ask the server. *(PgBouncer itself was not run; the setting replaces the number read from the server and nothing else.)* |
378
+ | `pgdb_pool_max_size_<role>` | Fix one kind of process's pool yourself — `gateway_worker`, `lineup_worker` or `lineup_scheduler` (e.g. `pgdb_pool_max_size_lineup_worker`). Counted first; a deployment never changes it |
379
+ | `lineup_concurrency` | How many jobs one worker process runs at once. Default `0` = as many as its pool has connections |
380
+
381
+ A job worker runs no more jobs at once than it has connections, so a burst of jobs waits in the queue instead of piling up inside the workers. If PostgreSQL's limit is lowered after you deployed, every process notices when it starts and shrinks its pool to a share that fits (it logs a warning); run `arc deploy` again to make the new numbers official. If a request still finds every connection busy for `pgdb_pool_acquire_timeout_ms` (10 s), it gets **HTTP 503 with `Retry-After`**, not a 500 and not a traceback.
382
+
383
+ Measured on one machine, PostgreSQL's default 100 connections, 8 web workers and 8 job workers: 600 queued jobs each holding a connection for 2 s, while 64 clients read records for 30 s. Before: connections peaked at 97, PostgreSQL turned away 83 attempts and **1,438 requests failed with HTTP 500**. After: the plan was 82 connections, the peak was 81, and **all 119,790 requests returned 200**; every job ran. With a deliberately tiny pool, the requests that could not get a connection all got 503 + `Retry-After: 2` (95,245 of them in two runs) and none a 500.
384
+
385
+ **Adding a queue later** (a new plugin that declares one): run the `arc deploy` command again, or nothing consumes it and its jobs just wait. `arc doctor --deep` tells you if that happened: *"queue(s) mail have no worker unit, so jobs for them are never consumed."*
386
+
387
+ **Checking it.** `arc status` is the one command that answers *how many web workers, which queues, how many schedulers are running*, and whether that is what was deployed:
388
+
389
+ ```bash
390
+ arc status
391
+ ```
392
+
393
+ ```
394
+ arc-desk — per-user systemd units, dev sizing
395
+ ┏━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
396
+ ┃ process ┃ expected ┃ running ┃ restarts ┃ configured by ┃
397
+ │ gateway (web workers) │ 2 │ 2 │ - │ dev default │
398
+ │ queue default │ 1 │ 1 │ - │ dev default │
399
+ │ queue mail │ 1 │ 1 │ - │ dev default │
400
+ │ scheduler │ 1 │ 1 │ - │ fixed (one only) │
401
+ │ log writer │ 1 │ 1 │ - │ fixed │
402
+ units: 6 of 6 active, 0 failed · restarts since they started: 0
403
+ database connections: 6 open now · PostgreSQL lets this application open 97, 10 kept free
404
+ plan: 2 gateway-worker × 10 + 1 lineup-scheduler × 2 + 2 lineup-worker × 5 = 32 of the 87 available when it was made
405
+ Everything matches.
406
+ ```
407
+
408
+ *Expected* is read from the unit files `arc deploy` wrote; *running* comes from systemd and from the process list `arc ps` shows. It flags a failed unit (with the command to recover it), a count that does not match, a leftover `arc run` running workers a second time, and a setting you changed but have not applied yet (*"settings give 4 web worker(s) but the units run 2 — run `arc deploy dev` to apply"*). It also checks the connection plan against PostgreSQL as it is *now*: a plan made for other worker counts, or one larger than a limit that was lowered since (*"the plan uses 32 connections but PostgreSQL now allows 20 — run `arc deploy dev` to re-plan"*). It is read-only, does not boot the kernel (it opens one short database connection to read the limits), and exits 1 when anything is wrong, so it also works as a monitoring check; `--json` gives the same thing for scripts. `arc ps` alone lists the processes; `arc doctor --deep` additionally compares the queues your plugins declare with the queues that have workers.
409
+
410
+ **Running it.** For a production install drop `--user` and use `sudo` where needed:
411
+
412
+ ```bash
413
+ systemctl --user list-units 'arc-*' # everything, and which are failed
414
+ systemctl --user status arc-<project>-gateway # one process
415
+ journalctl --user -u arc-<project>-worker-mail-1 # its output
416
+ systemctl --user reset-failed arc-<project>-worker-mail-1 && systemctl --user start arc-<project>-worker-mail-1
417
+ ```
418
+
419
+ An older install that used a single `arc run` unit is switched over by running the new command with `--enable` (it stops and disables the old unit, and leaves its file in place).
350
420
 
351
421
  **Before going public**, review these settings (`arc settings set <key> <value>`):
352
422
 
@@ -356,6 +426,10 @@ This writes an nginx site for that domain that proxies to `arc run`, and obtains
356
426
  | `gateway_trusted_proxies` | The IP of your reverse proxy, so the real client IP is read from `X-Forwarded-For` rather than being nginx's address. Login rate limiting is keyed on the pair (client IP, account), so without this ARC sees nginx's address for everyone and that per-source separation is lost. |
357
427
  | `gateway_cors_origins` | Left empty, CORS is disabled — the safe default. Only list origins that genuinely need cross-origin access. |
358
428
  | `gateway_metrics_token` | Left empty, `/metrics` is open to anyone who can reach the port. Set a token if it is reachable. |
429
+ | `gateway_access_log` | Where each request's access line goes. `file` (the default) writes it to `logs/gateway.jsonl` only; `console` also prints it through `arc run` (handy on a dev machine, but at thousands of requests per second that relay becomes the bottleneck); `off` disables the line. Request metrics are kept in every mode. Restart to apply. |
430
+ | `log_max_bytes`, `log_backup_count` | Size of each `logs/<category>.jsonl` before it rotates (default 10 MB) and how many rotated copies are kept (default 5). The access log is one ~370-byte line per request, so at several thousand requests per second the defaults hold only tens of seconds of history. Raise both if you need longer. |
431
+ | `log_collector` | `true` (default): `arc run` starts one writer for `logs/*.jsonl`, so no line is lost to rotation races between workers (8 processes at ~8,000 requests per second: every line kept). `false`: every process writes the files itself. If the collector goes away while the stack is running, each process keeps logging to files of its own, `logs/<category>.fallback-<pid>.jsonl`, and never to the shared ones. Restart to apply. |
432
+ | `log_flush_ms` | How long (ms) each process accumulates log lines before sending them to the collector, and how long the collector accumulates before one write (default 10). Lower means lines reach disk sooner; higher means fewer writes. |
359
433
  | `arc_server_timezone` | Defaults to `UTC`; set an IANA name such as `Asia/Kolkata` if you want naive date-times interpreted in local time. |
360
434
 
361
435
  Keep `arc run` on `127.0.0.1` (the default) and let nginx be the only public listener. Back up `.arc/` (especially `arc.mkey`) and dump the database with `pg_dump`.
@@ -394,9 +468,18 @@ nginx is up but nothing is listening on the port it proxies to — `arc run` is
394
468
  **Port 8001 is already in use**
395
469
  `arc run --port 9000`. If you use `arc deploy prod`, pass the same `--port`.
396
470
 
471
+ **`Connection budget: ... connections are needed at the very least`** from `arc deploy` or `arc run`
472
+ The workers you asked for cannot fit in the connections PostgreSQL allows (the message says how many are needed and how many exist). Run fewer workers (`gateway_workers`, `lineup_workers_per_queue`), raise `max_connections` in `postgresql.conf` (then restart PostgreSQL), or lower `pgdb_connection_reserve`. If a pooler such as PgBouncer sits in front, set `pgdb_connection_budget` to what it can serve.
473
+
474
+ **Requests fail with `503` and `Retry-After`, log says `no database connection available`**
475
+ Every connection in that process's pool was busy for `pgdb_pool_acquire_timeout_ms`. It is capacity, not a bug, and clients can retry. Check `arc status` for the pool sizes and how many connections are open; the usual fixes are fewer concurrent jobs (`lineup_concurrency`), a slow query holding connections (`slow_query_threshold_ms` logs it), or more connections (see *Database connections* above).
476
+
397
477
  **`uv sync` removed all my plugins**
398
478
  A bare `uv sync` at the project root uninstalls every workspace member. Always use `uv sync --all-packages`. ARC's own commands already do.
399
479
 
480
+ **`lineup scheduler: cannot reach Redis`**
481
+ The scheduler keeps running and retries (every 1 s, backing off to every 10 s) until Redis answers, then takes the leader lock again; it does not exit, so systemd never marks it failed because of an outage. A second scheduler waits as a standby (`another scheduler is the leader — standing by`) and takes over when the first stops. Check `redis-cli ping`. If a scheduler that is leading can no longer confirm its lock (a renewal failed), it stops dispatching at once and says so (`no longer sure it is the leader`), then contends again — so two schedulers never fire the same cron job. Any other error that ends a scheduler is printed and exits with code 1.
482
+
400
483
  **`redix: FAILED to connect`**
401
484
  Check `redis-cli ping`, then re-run `arc redix setup`. If Redis has a password, enter it there.
402
485
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: arc-kernel
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: ARC kernel — capability-based Python platform
5
5
  Project-URL: Homepage, https://github.com/vignesh-ramsh/arc
6
6
  Project-URL: Repository, https://github.com/vignesh-ramsh/arc
@@ -28,7 +28,7 @@ from .kernel import ( # noqa: F401
28
28
  from .resolver import BootPlan, PluginSpec, ResolutionError # noqa: F401
29
29
  from .runtime import BootError, boot, find_project_root, shutdown # noqa: F401
30
30
 
31
- __version__ = "0.1.1"
31
+ __version__ = "0.1.2"
32
32
 
33
33
 
34
34
  def __getattr__(name: str) -> Any: