feat(schedule): name the schedule a reconcile failure belongs to by ChiragAgg5k · Pull Request #13746 · appwrite/appwrite · GitHub
Skip to content

feat(schedule): name the schedule a reconcile failure belongs to - #13746

Merged
ChiragAgg5k merged 3 commits into
mainfrom
feat/schedule-error-row-context
Sep 17, 2026
Merged

ChiragAgg5k merged 3 commits into
mainfrom
feat/schedule-error-row-context

Conversation

@ChiragAgg5k

Copy link
Copy Markdown
Member

What

Bumps utopia-php/schedule to ^0.3.0 and uses the row it now hands the error handler, so a reconcile failure tags the project, resource and schedule it was building.

onError: function (\Throwable $error, ?Row $row = null): void {
    Span::init('schedule.functions.reconcile');
    if ($row?->data instanceof Document) {
        Span::add('project.id', (string) $row->data->getAttribute('projectId'));
        Span::add('resource.id', (string) $row->data->getAttribute('resourceId'));
        Span::add('schedule.id', $row->id);
    }
    Span::current()?->finish(error: $error);
},

Same in ScheduleFunctions, ScheduleExecutions and ScheduleMessages.

Why

These failures arrive in Sentry as a message and a region and nothing else — Collection not found, region = fra — for one of several thousand schedules. Identifying the row behind one of them meant writing a task to re-derive it from the database.

The attributes are the same ones the enqueue path in ScheduleFunctions already records on the success side:

Span::init('schedule.functions.enqueue');
Span::add('project.id', $schedule['project']->getId());
Span::add('function.id', $schedule['resource']->getId());
Span::add('schedule.id', $schedule['$id'] ?? '');

The error path simply never had the row to record them from. utopia-php/monorepo#296 (released as schedule/0.3.0) passes it through.

Dependency

^0.2.0 → ^0.3.0. Under caret semantics on 0.x a minor bump is a breaking boundary, so this constraint change is required — 0.3.0 is otherwise not installable. The library change itself is backward compatible: PHP ignores the extra argument, so a one-parameter handler still works.

Tests

None. There is no assertion to make here that would not be asserting the telemetry double against itself — the attributes either reach Sentry or they don't, and that is visible on the first failure after deploy. The three blocks are identical and the behaviour they add is guarded by a single instanceof.

composer lint passes. PHPStan is clean on the three changed files; a repo-wide run is currently blocked by parse errors in app/sdks/console-cli/internal/typegen/testdata/*.php, which are gitignored fixtures unrelated to this change.

Follow-up

appwrite-labs/cloud has a fourth handler, ScheduleBackups, which needs the same treatment once this is released.

A reconcile failure reported the throwable and nothing else, so an error
like "Collection not found" arrived carrying its region and no way to tell
which of several thousand schedules produced it. Finding one meant writing
a task to re-derive it from the database.

utopia-php/schedule 0.3.0 passes the rejected row to the handler, so each
of the three schedulers now tags the project, resource and schedule it was
building -- the same attributes the enqueue path already records on the
success side.
@greptile-apps

greptile-apps Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Comment thread src/Appwrite/Platform/Tasks/ScheduleFunctions.php Outdated
@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → feat/schedule-error-row-context (after).

Metric Before After Change
🚀 Requests/sec 215.43 214.01 ⚪ -0.7%
⏱️ Latency P50 81.07 ms 81.97 ms ⚪ +1.1%
⏱️ Latency P95 192.96 ms 189.14 ms ⚪ -2%
Per-scenario breakdown & investigation details

Metrics below reflect the current branch (after). Δ P95 compares against the base.

Scenario P50 (ms) P95 (ms) Requests RPS Δ P95 (ms)
API total 81.97 189.14 13,623 214.01 -3.82
Account 152.06 289.99 717 11.94 -1.33
TablesDB 78.95 146.68 7,409 119.47 +0.26
Storage 76.34 172.74 3,585 59.39 +6.37
Functions 113.6 230.85 1,912 32.27 +4.02

Top API waits (after)

API request Max wait (ms)
account.name.update 571.19
functions.variables.update 446.38
functions.variables.create 429.41
storage.files.create 422.79
account.prefs.update 388.62

Row::id is the sequence Source\Database::rows() builds it from, while the
enqueue path tags $schedule['$id']. Reporting the sequence under the same
key sent operators looking for an id that is not on the document.
@ChiragAgg5k
ChiragAgg5k merged commit addb770 into main Sep 17, 2026
51 checks passed
@ChiragAgg5k
ChiragAgg5k deleted the feat/schedule-error-row-context branch September 17, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants