升级 NUPACK 4.1 并支持混合材料设计

This commit is contained in:
Lihatoo 2026-08-20 16:33:16 +08:00
parent 5daa60a464
commit c6189d857d
33 changed files with 5830 additions and 466 deletions

159
docs/ARCHITECTURE.md Normal file
View file

@ -0,0 +1,159 @@
# 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
```text
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.
```text
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_TOKEN` and bypasses
OIDC. The password is accepted only in the JSON body of
`POST /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
1. Set `NP_ADMIN_TOKEN` in `.env`.
2. Validate with `docker compose config --quiet`.
3. Wait for active calculations to finish before recreating `np-worker`.
4. Build and recreate Web and Worker from the same source revision.
5. 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.