mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
fix: handle PostgreSQL race condition in shared mode project creation
PostgreSQL adapter throws non-Duplicate exceptions when a table/index already exists during concurrent createCollection. Catch Throwable and attempt metadata-only creation as fallback. Also increase Realtime coroutine attribute polling timeout from 30s to 60s. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
09c963abda
commit
341aabb942
@@ -276,14 +276,37 @@ class Create extends Action
|
||||
try {
|
||||
$dbForProject->createCollection($key, $attributes, $indexes);
|
||||
} catch (Duplicate) {
|
||||
$dbForProject->createDocument(Database::METADATA, new Document([
|
||||
'$id' => ID::custom($key),
|
||||
'$permissions' => [Permission::create(Role::any())],
|
||||
'name' => $key,
|
||||
'attributes' => $attributes,
|
||||
'indexes' => $indexes,
|
||||
'documentSecurity' => true
|
||||
]));
|
||||
try {
|
||||
$dbForProject->createDocument(Database::METADATA, new Document([
|
||||
'$id' => ID::custom($key),
|
||||
'$permissions' => [Permission::create(Role::any())],
|
||||
'name' => $key,
|
||||
'attributes' => $attributes,
|
||||
'indexes' => $indexes,
|
||||
'documentSecurity' => true
|
||||
]));
|
||||
} catch (Duplicate) {
|
||||
// Metadata already exists from concurrent creation
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// PostgreSQL adapter may throw a non-Duplicate exception when
|
||||
// a table or index already exists during concurrent project
|
||||
// creation in shared mode. Treat as duplicate if metadata
|
||||
// can be created successfully.
|
||||
try {
|
||||
$dbForProject->createDocument(Database::METADATA, new Document([
|
||||
'$id' => ID::custom($key),
|
||||
'$permissions' => [Permission::create(Role::any())],
|
||||
'name' => $key,
|
||||
'attributes' => $attributes,
|
||||
'indexes' => $indexes,
|
||||
'documentSecurity' => true
|
||||
]));
|
||||
} catch (Duplicate) {
|
||||
// Metadata already exists from concurrent creation
|
||||
} catch (\Throwable) {
|
||||
throw $e; // Rethrow original if metadata creation also fails
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3802,7 +3802,7 @@ class RealtimeCustomClientTest extends Scope
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]));
|
||||
$this->assertEquals('available', $response['body']['status']);
|
||||
}, 30000, 250);
|
||||
}, 60000, 500);
|
||||
|
||||
$creates = [
|
||||
['name' => 'Doc A'],
|
||||
|
||||
Reference in New Issue
Block a user