6.5 KiB
NP Replica Architecture
Goals
NP Replica separates user navigation, durable account data, live queue state, and NUPACK compute processes. Scientific calculation code remains isolated from page rendering and account administration so UI changes do not alter numerical semantics.
Runtime Topology
Browser
|
| HTTPS / OIDC session
v
np-replica (Web/API, 4 GB)
| |
| live state | durable metadata/results
v v
Redis SQLite
|
| job queue
v
np-worker (NUPACK compute, 56 GB)
- Web/API serves the multi-page UI, validates ownership, accepts jobs, and serializes API responses. It does not run Redis-backed NUPACK jobs.
- Redis owns queue order, active job state, heartbeats, duplicate claims, sessions, and temporary result state.
- SQLite owns users, durable job inputs/results, usage totals, and shares.
- Worker consumes Redis jobs and runs NUPACK in isolated child processes.
Frontend Structure
The UI uses a small multi-page application structure. Each page has one primary operational purpose.
| Route | File | Responsibility |
|---|---|---|
/ |
service/home.html |
Queue overview, usage summary, recent jobs |
/workspace |
service/index.html |
Analysis, Design, Utilities, result inspection |
/cloud |
service/cloud.html |
Job search, JSON import/export, result links, cancellation, deletion, shares |
/account |
service/account.html |
Identity, account usage, worker resource information |
/admin |
service/admin-login.html |
Dedicated Admin password login |
/admin/panel |
service/admin.html |
Cross-account task and trash management |
service/static/app-shell.css provides the shared application shell and
responsive operational layout. service/static/portal.js contains shared
request, formatting, navigation, table, Cloud, Account, and Admin controllers.
The calculation workspace retains its self-contained renderer because it
contains specialized structure, heatmap, force-layout, and result-export code.
Backend Boundaries
service/server.py- HTTP routes and authentication gates
- Redis live-job repository and queue
- resource planning and worker orchestration
- NUPACK request validation and calculation adapters
service/account.py- SQLite schema and durable repository
- account-scoped job/share queries
- cross-account Admin queries and trash lifecycle
service/split_strand_svg.py- structure rendering adapter
The next safe backend extraction point is moving Redis job coordination into a
job_repository.py module. NUPACK adapters can then move into separate
analysis_service.py, design_service.py, and utilities_service.py
modules without changing HTTP contracts.
Job Submission And Duplicate Control
Duplicate detection is scoped by user_id and a canonical SHA-256 hash of the
JSON payload. Different users never share duplicate state.
POST /api/jobs
|
+-- no active match --> 202 accepted
|
+-- active match ----> 409 duplicate + existing job metadata
|
+-- user cancels: no write
|
+-- user confirms:
POST /api/jobs?force=1 --> 202 accepted
Redis uses an atomic claim key. Terminal updates delete a claim only when it
still belongs to that job, preventing an older job from deleting a newer forced
submission's claim. The in-memory development backend mirrors this behavior
under JOB_LOCK.
Resource Planning
NP_WORKER_CONCURRENCY=auto selects the smaller of:
- effective CPU capacity divided by
NP_PER_JOB_THREAD_LIMIT; - usable worker memory divided by
NP_ESTIMATED_JOB_MEMORY_GB.
CPU detection considers process affinity and cgroup quota. Memory detection
uses an explicit override, cgroup memory limit, or host memory in that order.
The published plan is visible through /health.
These controls affect scheduling only. They do not change models, sequence constraints, complexes, thermodynamic parameters, or result serialization.
Authentication And Authorization
- Normal pages and account APIs require an OIDC-backed session.
- Job, history, and share APIs enforce ownership by stable OIDC
user_id. - Public share routes expose only the selected shared record.
- Admin uses a dedicated password configured by
NP_ADMIN_TOKENand bypasses OIDC. The password is accepted only in the JSON body ofPOST /api/admin/login; it is never embedded in a route, redirect, cookie, or local storage value. - Successful login creates a random session in Redis (or process memory in development) and sets a short-lived HttpOnly, SameSite=Strict cookie.
- Admin may list all durable job metadata, stop active jobs, move terminal jobs to trash, restore jobs, permanently delete trashed jobs, and configure trash retention. APIs do not return stored payload or result blobs.
The Admin password must be random, kept in the ignored .env, and rotated after
exposure. Keep NP_ADMIN_COOKIE_SECURE=1 in HTTPS deployments.
Trash Lifecycle
Normal user deletion sets deleted_at and purge_after rather than deleting a
job row. Deleted jobs disappear from account history, usage, and result APIs;
all share records for that job are deleted. Admin can inspect the trash, restore a
job, or permanently delete it. Expired rows are purged lazily during job-list
reads. Retention is stored in SQLite app_settings, defaults to two days, and
can be changed from one hour to 365 days.
Persistence And Recovery
- Redis AOF persists live queue state under
runtime/redis. - SQLite WAL persists account data under
runtime/account. - Worker recovery requeues jobs marked running after an interrupted worker.
- Active Redis job records do not expire while heartbeat updates continue;
terminal records use
NP_JOB_TTL_SECONDS.
Back up both runtime directories. SQLite is the durable source for the Cloud and Admin pages; Redis is the source for current queue and heartbeat state.
Deployment
- Set
NP_ADMIN_TOKENin.env. - Validate with
docker compose config --quiet. - Wait for active calculations to finish before recreating
np-worker. - Build and recreate Web and Worker from the same source revision.
- Verify
/health, normal OIDC pages, duplicate confirmation, Admin password login, task controls, and the trash lifecycle.
The Web container may be recreated independently for page-only changes, but backend contract changes should deploy Web and Worker from the same image.