-
Notifications
You must be signed in to change notification settings - Fork 409
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make DROP DATABASE properly wait for connections to drop (#6782)
DROP DATABASE attempts to wait in a retry loop for all incoming connections to be dropped, but it doesn't quite work, and so we have hacked around it with another retry loop in the test suite. One problem was that we were looking for the *edgedb* database name in pg_stat_activity, not the *postgres* database name. The other source of issues was that, as I suspected in #4567, the connection pool was establishing new connections to the database we were trying to close. This came in two forms: * Transfers scheduled *after* we closed all the connections (since now the db was under quota!): this we fix by setting a flag to prevent. * Transfers that are *already* in flight. This we fix by waiting for all of the pending connections to complete, and then closing them too. Once those issues were fixed, there were some failures in the test suite where DROP failed because of remaining *edgedb* connections. The problem there turned out to be in the test suite, where we were cancelling some connections which resulted in non-synchronous closes. Fixes #4567.
- Loading branch information
Showing
5 changed files
with
113 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# | ||
# This source file is part of the EdgeDB open source project. | ||
# | ||
# Copyright 2018-present MagicStack Inc. and the EdgeDB authors. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
|
||
from __future__ import annotations | ||
from typing import * | ||
|
||
import asyncio | ||
|
||
|
||
_T = TypeVar('_T') | ||
|
||
|
||
async def deferred_shield(arg: Awaitable[_T]) -> _T: | ||
'''Wait for a future, deferring cancellation until it is complete. | ||
If you do | ||
await deferred_shield(something()) | ||
it is approximately equivalent to | ||
await something() | ||
except that if the coroutine containing it is cancelled, | ||
something() is protected from cancellation, and *additionally* | ||
CancelledError is not raised in the caller until something() | ||
completes. | ||
This can be useful if something() contains something that | ||
shouldn't be interrupted but also can't be safely left running | ||
asynchronously. | ||
''' | ||
task = asyncio.ensure_future(arg) | ||
|
||
ex = None | ||
while not task.done(): | ||
try: | ||
await asyncio.shield(task) | ||
except asyncio.CancelledError as cex: | ||
if ex is not None: | ||
cex.__context__ = ex | ||
ex = cex | ||
except Exception: | ||
if ex: | ||
raise ex from None | ||
raise | ||
|
||
if ex: | ||
raise ex | ||
return task.result() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters