Migrate to utopia-php/http resources/context API#12220
Conversation
Greptile Summary
Confidence Score: 4/5Safe to merge for all non-GraphQL paths; GraphQL correctness depends on the Swoole coroutine-context key matching the updated library's internal key, which is untested. All mechanically-replaced call sites are correct and verified by existing tests. The single P1 concern is the utopia key in Swoole.php — it is an intentional coordinated change with the library but lacks a GraphQL e2e test to prove it. src/Appwrite/Promises/Swoole.php — the REQUEST_CONTAINER_CONTEXT_KEY rename is the only unverified runtime assumption in the PR. Important Files Changed
Reviews (5): Last reviewed commit: "Avoid incidental bumps to utopia-php/dat..." | Re-trigger Greptile |
✨ Benchmark resultsComparing 1.9.x (before) to feat/utopia-http-resources-context (after). Before
After
Delta
Top API waits
|
🔄 PHP-Retry SummaryFlaky tests detected across commits: Commit
|
| Test | Retries | Total Time | Details |
|---|---|---|---|
UsageTest::testStorageStats |
1 | 10.28s | Logs |
FunctionsCustomServerTest::testErrorPages |
1 | 173ms | Logs |
Commit 4218528 - 26 flaky tests
| Test | Retries | Total Time | Details |
|---|---|---|---|
UsageTest::testStorageStats |
1 | 10.29s | Logs |
WebhooksCustomServerTest::testDeleteDeployment |
1 | 14ms | Logs |
WebhooksCustomServerTest::testDeleteFunction |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateCollection |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateAttributes |
1 | 11ms | Logs |
WebhooksCustomServerTest::testCreateDocument |
1 | 12ms | Logs |
WebhooksCustomServerTest::testUpdateDocument |
1 | 10ms | Logs |
WebhooksCustomServerTest::testDeleteDocument |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateTable |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateColumns |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateRow |
1 | 11ms | Logs |
WebhooksCustomServerTest::testUpdateRow |
1 | 11ms | Logs |
WebhooksCustomServerTest::testDeleteRow |
1 | 11ms | Logs |
WebhooksCustomServerTest::testCreateStorageBucket |
1 | 6ms | Logs |
WebhooksCustomServerTest::testUpdateStorageBucket |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateBucketFile |
1 | 23ms | Logs |
WebhooksCustomServerTest::testUpdateBucketFile |
1 | 6ms | Logs |
WebhooksCustomServerTest::testDeleteBucketFile |
1 | 6ms | Logs |
WebhooksCustomServerTest::testDeleteStorageBucket |
1 | 13ms | Logs |
WebhooksCustomServerTest::testCreateTeam |
1 | 7ms | Logs |
WebhooksCustomServerTest::testUpdateTeam |
1 | 9ms | Logs |
WebhooksCustomServerTest::testUpdateTeamPrefs |
1 | 10ms | Logs |
WebhooksCustomServerTest::testDeleteTeam |
1 | 5ms | Logs |
WebhooksCustomServerTest::testCreateTeamMembership |
1 | 13ms | Logs |
WebhooksCustomServerTest::testDeleteTeamMembership |
1 | 10ms | Logs |
WebhooksCustomServerTest::testWebhookAutoDisable |
1 | 25ms | Logs |
Commit 822c740 - 26 flaky tests
| Test | Retries | Total Time | Details |
|---|---|---|---|
UsageTest::testStorageStats |
1 | 10.33s | Logs |
WebhooksCustomServerTest::testDeleteDeployment |
1 | 19ms | Logs |
WebhooksCustomServerTest::testDeleteFunction |
1 | 21ms | Logs |
WebhooksCustomServerTest::testCreateCollection |
1 | 14ms | Logs |
WebhooksCustomServerTest::testCreateAttributes |
1 | 12ms | Logs |
WebhooksCustomServerTest::testCreateDocument |
1 | 9ms | Logs |
WebhooksCustomServerTest::testUpdateDocument |
1 | 10ms | Logs |
WebhooksCustomServerTest::testDeleteDocument |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateTable |
1 | 9ms | Logs |
WebhooksCustomServerTest::testCreateColumns |
1 | 10ms | Logs |
WebhooksCustomServerTest::testCreateRow |
1 | 9ms | Logs |
WebhooksCustomServerTest::testUpdateRow |
1 | 9ms | Logs |
WebhooksCustomServerTest::testDeleteRow |
1 | 9ms | Logs |
WebhooksCustomServerTest::testCreateStorageBucket |
1 | 5ms | Logs |
WebhooksCustomServerTest::testUpdateStorageBucket |
1 | 9ms | Logs |
WebhooksCustomServerTest::testCreateBucketFile |
1 | 9ms | Logs |
WebhooksCustomServerTest::testUpdateBucketFile |
1 | 5ms | Logs |
WebhooksCustomServerTest::testDeleteBucketFile |
1 | 5ms | Logs |
WebhooksCustomServerTest::testDeleteStorageBucket |
1 | 12ms | Logs |
WebhooksCustomServerTest::testCreateTeam |
1 | 6ms | Logs |
WebhooksCustomServerTest::testUpdateTeam |
1 | 8ms | Logs |
WebhooksCustomServerTest::testUpdateTeamPrefs |
1 | 9ms | Logs |
WebhooksCustomServerTest::testDeleteTeam |
1 | 4ms | Logs |
WebhooksCustomServerTest::testCreateTeamMembership |
1 | 12ms | Logs |
WebhooksCustomServerTest::testDeleteTeamMembership |
1 | 8ms | Logs |
WebhooksCustomServerTest::testWebhookAutoDisable |
1 | 25ms | Logs |
Commit 11ba023 - 2 flaky tests
| Test | Retries | Total Time | Details |
|---|---|---|---|
UsageTest::testStorageStats |
1 | 10.57s | Logs |
TeamsConsoleClientTest::testUpdateMembershipWithSession |
1 | 439ms | Logs |
Commit da1768b - 2 flaky tests
| Test | Retries | Total Time | Details |
|---|---|---|---|
UsageTest::testStorageStats |
1 | 10.43s | Logs |
FunctionsScheduleTest::testCreateScheduledAtExecution |
1 | 126.47s | Logs |
Note: Flaky test results are tracked for the last 5 commits
This comment has been minimized.
This comment has been minimized.
Adopts the new split DI containers in utopia-php/http: `resources()` for boot-time wiring (shared across requests) and `context()` for per-request state. Replaces the removed `getResource()`/`setResource()`/`getContainer()` helpers throughout the HTTP entry point, controllers, GraphQL layer, and installer. Bumps the dependency chain accordingly: utopia-php/http to the dev branch (aliased to 0.34.25 to satisfy platform's exact pin), servers 0.4.*, queue 0.18.*, and pulled-along cli/platform/database upgrades. Also tightens app/init/resources/request.php by collapsing single-return factories to arrow functions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both callbacks were doing `new Http($swoole, 'UTC')` purely as a vehicle to reach DI -- never configuring it, never calling ->run(). Now that the adapter exposes resources() directly, drop the Http construction and use the resources container straight. createDatabase() takes Container instead of Http to match. Also rename $swooleAdapter to $swoole. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
$swoole->resources() returns the same object we passed in via the Server constructor's resources: param. No need to round-trip through the adapter when the container is already in scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Promises\Swoole was already propagating the request container into child coroutines, but using its own pre-existing key (__utopia_http_request_container) rather than the new utopia-php/http key (__utopia__). With the keys mismatched, the propagation was dead code and resolvers spawned from webonyx coroutines saw an empty context, failing every GraphQL query with 'Dependency utopia:graphql not found'. Align the key so child coroutines actually inherit the request's container (wrapped as a child Container, so request-scoped overrides in the resolver can't bleed back into the outer request). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the dev-branch alias for utopia-php/http now that 2.0.0-rc1 is released, and bump utopia-php/platform to 1.0.0-rc1 which targets the new resources/context API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The composer update -W cycles to land utopia-php/http and platform also pulled forward database 5.4.2 -> 5.6.0, storage 2.0.1 -> 2.0.2, and migration 1.9.6 -> 1.9.7. Pin them back to the 1.9.x baseline -- those upgrades aren't part of this PR's scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
749b80a to
da1768b
Compare
| class Swoole extends Promise | ||
| { | ||
| private const REQUEST_CONTAINER_CONTEXT_KEY = '__utopia_http_request_container'; | ||
| private const REQUEST_CONTAINER_CONTEXT_KEY = '__utopia__'; |
There was a problem hiding this comment.
Coroutine context key must match the library's internal key
Swoole::execute() reads Coroutine::getContext()['__utopia__'] to get the parent request container and writes a child container under the same key in every spawned coroutine. For this to work, Http::context() in utopia-php/http must resolve the per-request container by reading Coroutine::getContext()['__utopia__']. If the library uses a different key, $parentContainer will always be null and every GraphQL resolver coroutine spawned via Swoole will fail to find request-scoped resources — silently returning nothing or throwing at ->get(...) call sites. The test plan doesn't include any GraphQL e2e coverage to exercise this path; adding a basic GraphQL query test would confirm the key is correct.
Summary
Adopts the new split DI containers in
utopia-php/http(PR:dev-feat-resources-and-context):resources()— long-lived container, shared across every request. Used at boot for config, clients, and shared services.context()— per-request child container, falling through toresources(). The library writesrequest,response,route,errorinto it.Replaces all the removed APIs (
getResource(),setResource(),getContainer(),getResources()) across the HTTP entry point, controllers, GraphQL layer, and installer.Changes
utopia-php/http:dev-feat-resources-and-context as 0.34.25(aliased to satisfyplatform 0.13.2's exact pin)utopia-php/servers:0.3.*→0.4.*utopia-php/queue:0.17.*→0.18.*cli 0.23.3,platform 0.13.2,database 5.6.0,migration 1.9.7,storage 2.0.2app/http.php:Server(... container:)→Server(... resources:)$swooleAdapter->getContainer()(boot/request) →$swooleAdapter->context()$app->getResource(name)→$app->context()->get(name)(8 sites)$registerRequestResourcesto$bindContext; collapsed$requestContainerintermediateapp/controllers/general.php: 3 defensive$utopia->getResource(...)→$utopia->context()->get(...)(kept under try/catch since they live insideHttp::error())src/Appwrite/Platform/Installer/Server.php:$adapter->getContainer()→$adapter->resources()(boot-time)Resolvers.php,Schema.php,Mapper.php): ~22getResource(...)→context()->get(...)inside per-query coroutines;getResources(array)(removed) reimplemented inline viaarray_mapapp/init/resources/request.php: collapsed single-return factories to arrow functions (~40 lines saved); no behavior changesCaveat on the alias
The
dev-feat-resources-and-context as 0.34.25shim makes Composer treat the dev branch as functionally equivalent to released 0.34.25 — needed becauseutopia-php/platform 0.13.2exact-pinshttpat0.34.25. Once a real platform release targets the new http API, drop theas 0.34.25and pin to a stable tag.Test plan
composer analyze(PHPStan level 3) — no errorsdocker compose up -d --force-recreate --build— all 14 workers + main HTTP container start cleanly, databases create on bootdocker compose exec appwrite test tests/unit/— 532 tests passdocker compose exec appwrite test tests/e2e/Services/Health— 22 tests pass (exercises queue resources, DB, storage)curl /v1/health/version→200 {"version":"1.9.3"}POST /v1/account/sessions/emailw/ short password) →400with proper error body, exercising theHttp::error()defensivecors/userlookups without crashing🤖 Generated with Claude Code