Skip to content

[pull] main from appwrite:main - #217

Merged
pull[bot] merged 9 commits into
djacidfx:mainfrom
appwrite:main
Sep 2, 2026
Merged

[pull] main from appwrite:main#217
pull[bot] merged 9 commits into
djacidfx:mainfrom
appwrite:main

Conversation

@pull

@pull pull Bot commented Sep 2, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

lohanidamodar and others added 9 commits August 31, 2026 16:40
buildDuration falls back to wall clock since the deployment was created
when a build never stamped buildStartedAt, so queue wait was billed as
build compute and flowed into builds.mbSeconds.

Zero buildDuration and mbSeconds in that case. Both StatsUsage workers
skip zero-valued metrics, so the compute rows drop out while the build
counters and storage metrics still land.
* fix(builds): cap the billed build duration at the build timeout

Jobs::duration() measures wall clock from buildStartedAt, which the first
log callback stamps — so a build that never streamed a line falls back to
the deployment's creation time and measures its whole queue wait. That
value is what Usage\Build::publish() bills, at memory x duration x cpus,
and it is billed for 'failed' exactly as for 'ready'.

The executor backend could not produce this: it measured microtime()
around the build's own execution, so queue wait was structurally
unbillable. Since builds moved to the jobs-service the mean billed
duration of a *failed* build has gone 111s (Jun) -> 157s (Jul) -> 491s
(Aug) while successful builds held at ~52s, and failed builds are now 57%
of all billed build compute fleet-wide.

One production project shows the shape plainly: 2,286 of its 2,311 failed
August builds have buildStartedAt NULL, empty buildLogs, "exit code -1",
and durations at 904-912s. On s-2vcpu-2gb that is ~1.0 GB-hour billed per
build that never ran — 1,869 of its 1,878 billed GB-hours for the month.

Clamp to _APP_COMPUTE_BUILD_TIMEOUT, the same ceiling Deployments hands
the jobs-service as timeoutSeconds: no job outlives it, so nothing past it
can have been build time. Guarded so a 0 or negative value leaves the
measurement alone rather than zeroing every build.

This is a ceiling, not the whole fix — a starved build still bills the
full timeout. Billing 0 when buildStartedAt is NULL, and the build fan-out
that starves them, are follow-ups.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(builds): drop the build duration cap test

Removed at request; the cap in Jobs::duration() is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore(compute): drop the cp into /mnt/code from runtime entrypoints

The executor now declares OPEN_RUNTIMES_CODE_PATH on runtime containers
(open-runtimes/executor#253), so the start helper extracts the archive
straight from the /tmp mount and the copy is dead weight on cold starts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: bump openruntimes/executor to 0.29.0

Ships OPEN_RUNTIMES_CODE_PATH on runtime containers
(open-runtimes/executor#253), which the entrypoints now rely on.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Requested in review; the guard is a two-line branch and the layer has no
other unit coverage.
The index list filtered the `indexes` metadata collection on the `databaseId`
and `collectionId` strings while every sibling path (attribute list, the
cursor lookup three lines below, the create-time limit count, and the worker's
delete cascade) keys on `databaseInternalId`/`collectionInternalId`. A
recreated database keeps its id but takes a new sequence, so whenever an
earlier incarnation's index rows outlive it, the list returns them next to the
live ones under the same key.

The 109-point GA campaign hit this on r30 PR-95 (rv109a-vdb-ded, dedicated
VectorsDB): r28 and r29 had left `idx_embeddings` rows at `processing`
(the pool-identity denial fixed in cloud#5573 threw in the worker before
createIndex could mark them `failed`, and the same denial stopped the
delete-database job before its cascade reached them). r30 created the index
cleanly (worker createIndex 0.43s, `available`), the similarity query ranked
correctly, yet the list kept reporting the stale `processing` rows and the row
failed on "index never left processing" for a third round. PR-93 on the same
prefix passed because the attribute list already filters on the sequences.

Both metadata collections carry `_key_db_collection` on the sequence pair, so
the corrected filter is the indexed one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rnal-ids

fix(databases): list indexes by database and collection sequence, not id
…hout-start

fix(usage): don't bill build compute when buildStartedAt is null
@pull pull Bot locked and limited conversation to collaborators Sep 2, 2026
@pull pull Bot added the ⤵️ pull label Sep 2, 2026
@pull
pull Bot merged commit 0fac0f3 into djacidfx:main Sep 2, 2026
0 of 6 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants