Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions specs/002-analysis-report/contracts/service.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,30 @@ already call. The address and parameters are today's.
`{species}` is a name (any case, `_` as a space), a taxonomy id or a database id.
`{filename}` is ignored.

| Status | When | Body |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| 200 | the report is made | `application/pdf`, `Content-Disposition: attachment; filename="report.pdf"`, sent once complete |
| 404 | the species is not in the graph (checked before the token) | JSON `{ "code": 404, "reason": "Not Found", "messages": [ … ] }` |
| 404 | the analysis service does not know the token | as above |
| 410 | the token's result was deleted by a release | JSON, code 410 |
| as today's | a number or flag that is not one | as today's, recorded by the replay (research R5) |
| 500 | making the PDF fails | JSON, code 500 |
| 503 | the analysis service, the graph or the render service cannot answer, or the service is at its limit, or past its time budget | JSON, code 503, with `Retry-After` |
| Status | When | Body |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 200 | the report is ready (made within the request's wait, or earlier) | `application/pdf`, `Content-Disposition: attachment; filename="report.pdf"`, sent once complete |
| 202 | the report is being made and was not ready within the request's wait (30 s by default) | `Retry-After: 10`; JSON `{ "code": 202, "reason": "Accepted", "messages": [ … ] }`, or for a request accepting `text/html` a page that asks the same address again after 10 s |
| 404 | the species is not in the graph (checked before the token) | JSON `{ "code": 404, "reason": "Not Found", "messages": [ … ] }` |
| 404 | the analysis service does not know the token | as above |
| 410 | the token's result was deleted by a release | JSON, code 410 |
| as today's | a number or flag that is not one | as today's, recorded by the replay (research R5) |
| 500 | making the PDF fails | JSON, code 500 |
| 503 | the analysis service, the graph or the render service cannot answer, or the service is at its limit, or past its time budget | JSON, code 503, with `Retry-After` |

- **The order of checks:** the species, then the token, then the rest.
- **No message carries a path, a host, a name or a submitted identifier.**
- **Limits** (FR-210): two reports at once by default, a bounded queue, and a time
budget of what the edge's 100 s leaves after the queues (research R4).
- **In the background** (FR-210, research R4): a request starts the report, or joins
the one being made for the same token and parameters (`number` after clamping,
`resource` after defaulting, `importableOnly`, the species' database id), and waits
up to 30 s. The same address answers 202 until the report is ready, then 200 with the
PDF; a report that failed answers its error once, and is then forgotten so that the
next request starts it again.
- **Kept** (FR-211): a finished report for one hour, or until a release clears its
token; then deleted.
- **Limits** (FR-210): two reports at once by default, a bounded queue (503 beyond it),
and a time budget of 5 minutes a report, past which it is abandoned (503 when asked
for again).
- **A figure that cannot be drawn** leaves its part without it, logged; the report is
still 200.
- **Characters no font draws:** spec 001 FR-017 for PDFs made on request.
Expand Down
16 changes: 9 additions & 7 deletions specs/002-analysis-report/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ and the render stub; the fixture graph (R8).

**Project Type**: a route in spec 001's web service.

**Performance Goals**: SC-203 against today's report on the same private services; the
budget is what the edge's 100 s leaves after the gateway's wait (R4), likely too little
for a cold report; the plan measures it first.
**Performance Goals**: SC-203 against today's report on the same private services. A
report is made in the background behind its address (FR-210, R4): the edge's 100 s
bounds a request, not a report.

**Constraints**: the analysis service's API only (FR-202); no submitted identifier logged
or kept (FR-211); FR-017 for characters; constitution 1.2.0.
Expand Down Expand Up @@ -114,9 +114,8 @@ else (constitution I).
its time and size (SC-203's baseline);
- a cold report, stage by stage, on a private stack: the analysis calls (R1's call 4
for a large expression dataset), the figures (spec 001's T005, part c), layout and
printing (twice, for the contents);
- **then the time budget's decision with the user** (R4), before the service is
built to one answer.
printing (twice, for the contents); - the time budget is decided (R4): the report is made in the background; these
measurements set SC-203's baseline and check its 2- and 4-minute targets.
2. **Spec 001's foundations first:** this spec builds on modules spec 001's tasks have
not built yet: the analysis stub (its T010), the analysis client (T020, T021) and the
service (T022), besides the layout and printing already merged. Its own work starts
Expand All @@ -131,7 +130,10 @@ else (constitution I).
figure's overlay checked (quickstart §3), SC-203's timing,
SC-205's search of logs and files; each shown failing.
8. **The website's part** (WebsiteAngular's specs): the gateway's report lane sent to
pdf-export, and the render service's `resource` (the overlay wait is step 0).
pdf-export, and the render service's `resource` (the overlay wait is step 0). The
"PDF Result" button opens the report's address in a new tab rather than downloading
it, so the page shown while it is made (202) is seen, not saved as `report.pdf`; the
gateway's lane passes a 202 and its `Retry-After` through unchanged.

## Complexity Tracking

Expand Down
53 changes: 35 additions & 18 deletions specs/002-analysis-report/research.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ are the same; otherwise it is a listed difference (spec, Expected differences).
**Render slots.** A report holding both of the render service's slots for minutes slows
the website's own image downloads meanwhile; R4's choices weigh this.

## R4. The time budget: likely over, to be measured first
## R4. The time budget: over, so the report is made in the background

**What bounds it.** The gateway's report lane runs one report at a time, queues up to 40,
and answers "unavailable" to a request that has waited 60 s. The edge closes a request
Expand All @@ -206,23 +206,40 @@ analysis calls (R1's call 4 may be large), layout and printing (spec 001's print
twice when there is a contents list, and a report always has one). That is well over
40 s. A 25-pathway report, the website's default, is about half that, still over.

**Decision.** Measure first, on a private stack (Order of work, step 1): a cold report of
25 and of 50 pathways, stage by stage (the analysis calls, the figures, layout,
printing), for a small and a large expression dataset. If it is over, bring the user
the choices, with the numbers:

- a shorter wait on the gateway's report lane, so more of the 100 s is left;
- more render concurrency for report figures (the host's memory sets the limit);
- a lower SC-203 target, or a smaller default number of pathways;
- the report made in the background and fetched when ready (a different contract:
a 202 with where to fetch it, and the website's button changed to poll);
- sending the answer's status early and the PDF as it is made, as today's main build
does: the edge then waits only for the first byte (by its documented behaviour, not
tested here), but a failure part way could no longer be answered 500, which FR-203
asks for.

**Rationale.** The numbers decide between these, and some (the background job) change
what the website and people's scripts see.
**Measured (spec 001 T007, 2 Nov 2026):** one diagram with an analysis token, cold, at
the render service's website settings: 4.5 s alone; 4.8 s for the slower of two at once;
9.1 s for the last of four; 19.6 s for the last of eight, each pair waiting for the
service's two slots. So a report's figures alone take about a minute for 25 pathways (26
figures) and about two for 50, against the 40 s the edge leaves. More render concurrency
does not change this: the service is limited by the host's processors (spec 001 T005).

**Decision (the user left it to us):** the report is made in the background, behind
today's address (FR-210, contracts/service.md): a request starts or joins it and waits
up to 30 s; then 200 with the PDF, or 202 with `Retry-After` and, for a browser, a page
that asks again; a finished report is kept for an hour.

**Rationale.**

- It keeps the address and its parameters, and the PDF is still sent only once
complete, so a failure can still be answered with its error (FR-203).
- A browser sees a page, then its PDF; a script that follows `Retry-After` gets the
PDF; one that does not gets a 202 it can tell from an error.
- It does not depend on the edge's limit, the gateway's wait, or the host's processors,
and needs no change to the analysis service.

**Alternatives considered.**

- _A shorter wait on the gateway's lane, more render concurrency, a smaller default:_
none brings 26 figures at 4.5 s each, two at once, under 40 s.
- _A lower SC-203 target alone:_ does not change the edge's 100 s.
- _Sending the status early and the PDF as it is made:_ a failure part way could no
longer be answered with its error (FR-203).
- _A new address for the finished report:_ changes what people's scripts call; the same
address answering 202 then 200 does not.

**What it costs.** The service keeps a report for an hour (FR-211, amended): the
analysis's results, under its token, as the analysis service itself keeps them. The
website's button opens the address in a tab rather than downloading it (plan, step 8).

## R5. Errors, and how they are compared

Expand Down
57 changes: 32 additions & 25 deletions specs/002-analysis-report/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ the statuses, the file names and the reports.
3. **Given** a number of pathways out of range, **Then** it is clamped to 1–50; **given**
a resource the result lacks, **Then** the result's default is used, as today.
4. **Given** more requests at once than the service makes, **When** they arrive, **Then**
they wait in a bounded queue, and beyond it, or past their time budget, are answered
"unavailable" with a time to retry, never left hanging.
they wait in a bounded queue, and beyond it, or past their time budget, are answered "unavailable" with a time to retry, never left hanging.
5. **Given** a report not ready within a request's wait, **When** it is asked for,
**Then** the answer is "accepted" with a time to ask again (for a browser, a page
that asks again by itself), and the same address answers the PDF once it is ready.

---

Expand Down Expand Up @@ -296,18 +298,23 @@ working files for the submitted identifiers.
- **FR-209**: The text that is not the analysis's data (introduction, captions, the
explanations of each part) MUST be the website's current wording, or written anew;
nothing is copied from `analysis-report`.
- **FR-210**: The service MUST make at most a set number of reports at once (two by
default, as today), queue a bounded number more, and answer "unavailable" with a time
to retry beyond that; a report that takes longer than its time budget is abandoned
and answered "unavailable". On the website's path the analysis gateway's queue comes
first; the service's own limit protects it from callers that do not pass the gateway.
The PDF is sent only once it is complete, and the edge closes a request after 100 s,
so the budget is what is left of those 100 s after the longest wait in the gateway's
queue and the service's own.
- **FR-210**: The service MUST make a report in the background, behind today's address:
a request starts the report (or joins the one already being made for the same token
and parameters) and waits for it up to a set time (30 s by default); a report ready
by then is sent as the PDF; one that is not is answered "accepted", with a time to
ask again, and the same address then answers the PDF once it is ready, or the error
that ended it. A browser is given a page that asks again by itself. The service makes
at most a set number of reports at once (two by default, as today) and queues a
bounded number more, answering "unavailable" with a time to retry beyond that; a
report that takes longer than its time budget (5 minutes by default) is abandoned,
and asking for it again answers "unavailable". The PDF is sent only once it is
complete. On the website's path the analysis gateway's queue comes first; no request
waits longer than the edge's 100 s allows.
- **FR-211**: The service MUST log, for each report, the token, the species, the number
of pathways, its time, its size and any character FR-207 replaced, and no submitted
identifier and nothing about the client. It keeps no file of a report after sending
it.
identifier and nothing about the client. A finished report is kept, for its token and
parameters only, for one hour or until a release clears its token, whichever is
sooner, then deleted; nothing else of it is kept.
- **FR-212**: Every dependency MUST pass spec 001's licence check (FR-009, SC-006).
- **FR-213**: Fixtures and samples MUST use made-up identifiers and placeholder names
for the authors and curators a report names (constitution Principle VII; spec 001
Expand Down Expand Up @@ -336,10 +343,10 @@ working files for the submitted identifiers.
only listed or recorded differences.
- **SC-202**: Every request in the replayed set of User Story 2 gets the same status and
file name as today's, but where Assumptions lists a difference.
- **SC-203**: A report of 25 pathways is made in no more time than today's for the same
token on the same private services, and one of 50 within a budget the plan sets from
that measurement and FR-210's limit (what is left of the edge's 100 s after the
queues); the time is measured with the render service's cache empty.
- **SC-203**: A report of 25 pathways is ready (the PDF answered at its address) in no
more time than today's takes for the same token on the same private services, or
within 2 minutes if today's is faster, and one of 50 within 4 minutes; the time is
measured with the render service's cache empty, from the first request.
- **SC-204**: Every colour and typeface in the report's own text and layout is one spec
001 SC-009 allows, as its check shows.
- **SC-205**: No submitted identifier is found in the service's logs or working files
Expand Down Expand Up @@ -376,13 +383,11 @@ working files for the submitted identifiers.
(several samples, its own statistics) is a later spec.
- **Measured privately:** against a private analysis service on a private copy of the
graph, with made-up identifiers; no production requests, and no real ReactomeGSA runs.
- **An open risk for the plan, to settle with the user:** the time FR-210 leaves is
about 40 s (the edge's 100 s less the gateway's wait of up to 60 s). The render
service's measured times (about 5–7 s for a diagram with a token, two at a time)
suggest a cold report of 50 pathways needs about 2 minutes. The plan measures it
(spec 001's T005 part c) and, if it is over, brings the user the choices: a shorter
wait on the gateway's report lane, more render concurrency, a lower SC-203 target, or
a report made in the background and fetched when ready.
- **Made in the background (decided, research R4):** a report cannot be drawn within
the edge's 100 s: one figure with a token takes 4.5 s cold and the render service
draws two at once (spec 001 T007), so 26 figures take about a minute and 51 about two,
before the analysis calls and the print. The user left the choice to us; FR-210 makes
the report in the background behind the same address.
- **The website's button** is labelled "PDF Result" today and is hidden for ReactomeGSA
results; the address serves any token.
- **Expected differences from today's report** (FR-208):
Expand Down Expand Up @@ -414,8 +419,10 @@ working files for the submitted identifiers.
- a failure while making the PDF answered 500 in the analysis service's JSON form,
before any of the PDF is sent, where today's ends the answer early (main) or, for
a failure of the PDF library, answers 500 with the framework's default body (the
unmerged branch) (the Background);
- a request beyond the queue or past its time budget answered "unavailable", where
unmerged branch) (the Background); - a request beyond the queue or past its time budget answered "unavailable", where
today's waits without limit;
- a report not ready within a request's wait answered "accepted" (202) and fetched
again from the same address, where today's answers in one request however long it
takes (FR-210);
- today's service also sends each report's timing, with the client's address and
browser, to a separate reporting service; the new one logs only what FR-211 lists.
Loading