You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/adr/ADR-004_MWL_Daily_Backup_And_Reset.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,22 +12,22 @@ The worklist is inherently ephemeral: appointments are scheduled per clinic, and
12
12
13
13
The gateway MWL is not intended to be a canonical or long-term data store. Retaining worklist items indefinitely would cause the database to grow to unwieldy proportions and would give a false impression of data durability.
14
14
15
+
The gateway runs as a Python process on a Windows VM managed by Azure Arc. Scheduling therefore belongs in the infrastructure layer (Windows Task Scheduler, configurable via Arc).
16
+
15
17
## Decision
16
18
17
-
Reset the MWL database on a configurable schedule (default: daily at 02:00 UTC) by:
19
+
Reset the MWL database on a schedule managed by Windows Task Scheduler by:
18
20
19
21
1. Backing up the database before clearing it, using SQLite's native `conn.backup()` API
20
22
2. Deleting all rows from `worklist_items`
21
23
22
-
This runs as a dedicated `reset` container (`reset_main.py` / `MWLResetScheduler`).
23
-
24
-
The schedule is configured via a cron expression (`MWL_RESET_SCHEDULE`), which allows any cadence (daily, weekly, etc) to be expressed in a single environment variable without code changes.
24
+
`reset_main.py` is performs these two steps and exits. Windows Task Scheduler (registered via `scripts/bat/schtasks.bat`) invokes it on whatever schedule is configured in infrastructure.
25
25
26
26
**Alternatives considered:**
27
27
28
-
-**Reset on startup only** — would not handle long-running deployments where the container is not restarted between clinics
28
+
-**In-process Python scheduler** (`croniter` sleep loop) — puts scheduling logic in application code; duplicates a facility the OS already provides; requires a long-running process that serves no other purpose
29
+
-**Reset on startup only** — would not handle long-running deployments where the process is not restarted between clinics
29
30
-**No reset** — leads to unbounded growth and stale data visible to the modality
30
-
-**Interval-based env vars** (`RESET_INTERVAL=daily`, `RESET_TIME=02:00`, `RESET_DAY=monday`) — more verbose config, requires code changes to support new intervals; cron expression is more expressive in a single value
31
31
32
32
## Consequences
33
33
@@ -36,11 +36,11 @@ The schedule is configured via a cron expression (`MWL_RESET_SCHEDULE`), which a
36
36
- Worklist is clean at the start of each clinic with no manual intervention
37
37
- Database size remains bounded
38
38
- Backup before clear means data is recoverable if needed
39
-
- Schedule is fully configurable via env var without code changes
40
-
-Follows the existing one-process-per-container pattern
39
+
- Schedule is owned by infrastructure (Arc / Task Scheduler), not application code — no code change needed to adjust timing
40
+
-`reset_main.py` is a simple, testable, one-shot script with no scheduler machinery
41
41
42
42
### Negative Consequences
43
43
44
-
-Adds a fifth service to the deployment
44
+
-Schedule configuration lives outside the codebase; requires infrastructure access to change
45
45
- Any worklist items written very close to the reset time could be cleared before the modality queries them. This is mitigated by choosing a reset time well outside clinic hours
46
46
- Backups accumulate on disk and will need periodic pruning; this is not currently automated
@@ -45,27 +45,25 @@ The MWL server is a lightweight, production-ready DICOM worklist solution that:
45
45
3.**Filtering**: MWL server filters by modality, date, patient ID, status
46
46
4.**Response**: Server returns matching worklist items to modality
47
47
5.**Status Updates**: C-STORE receipt transitions items from `SCHEDULED` to `IN PROGRESS`; [MPPS](https://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_F) transitions items to `COMPLETED` or `DISCONTINUED`
48
-
6.**Reset**: Reset scheduler backs up and clears the database on a configurable schedule
48
+
6.**Daily Reset**: Windows Task Scheduler invokes `reset_main.py`, which backs up and clears the database
49
49
50
50
## Running the MWL Server
51
51
52
-
The MWL server runs in a separate container:
52
+
The gateway runs as a Python process on a Windows VM:
53
53
54
54
```bash
55
-
# Start all services
56
-
docker compose up -d
55
+
# Start the MWL server
56
+
uv run python -m mwl_main
57
57
58
-
# Start only the MWL server and reset scheduler
59
-
docker compose up -d mwl reset
60
-
61
-
# View MWL server logs
62
-
docker compose logs -f mwl
58
+
# Run a one-shot backup and reset (normally invoked by Task Scheduler)
59
+
uv run python -m reset_main
60
+
```
63
61
64
-
# View reset scheduler logs
65
-
docker compose logs -f reset
62
+
For local development, Docker Compose is available:
The `MWL_RESET_SCHEDULE` value is a standard cron expression. Examples:
88
+
The reset schedule is configured in Windows Task Scheduler (registered via `scripts/bat/schtasks.bat`), not in the application.
89
+
90
+
## Scheduling the daily reset (Windows)
91
+
92
+
Register the scheduled task (run once, on the gateway VM):
93
+
94
+
```bat
95
+
scripts\bat\schtasks.bat
96
+
```
92
97
93
-
| Expression | Schedule |
94
-
|------------|----------|
95
-
|`0 2 * * *`| Daily at 02:00 UTC (default) |
96
-
|`0 2 * * 1`| Every Monday at 02:00 UTC |
97
-
|`0 2 1 * *`| First day of each month at 02:00 UTC |
98
+
This creates a Task Scheduler task that runs `reset_main.py` daily at midnight. The schedule can be adjusted in Task Scheduler or via Azure Arc without any code change.
@@ -158,29 +159,12 @@ uv run pytest tests/integration/test_c_find_returns_worklist_items.py -v
158
159
uv run pytest tests/integration/test_request_cfind_on_worklist.py -v
159
160
```
160
161
161
-
## Multi-container architecture
162
-
163
-
The MWL-related services run in separate containers. See [ADR-003: Separate containers for PACS and MWL](../adr/ADR-003_Separate_containers_for_PACS_and_MWL.md) and [ADR-004: Daily backup and reset of the MWL database](../adr/ADR-004_MWL_Daily_Backup_And_Reset.md) for the architectural decisions.
SCHEDULED ──(first C-STORE)──▶ IN PROGRESS ──(MPPS N-SET)──▶ COMPLETED
184
166
│
185
167
└────────(MPPS N-SET)──▶ DISCONTINUED
186
168
```
169
+
170
+
See [ADR-003: Separate containers for PACS and MWL](../adr/ADR-003_Separate_containers_for_PACS_and_MWL.md) and [ADR-004: Daily backup and reset of the MWL database](../adr/ADR-004_MWL_Daily_Backup_And_Reset.md) for architectural decisions.
0 commit comments