diff --git a/.github/workflows.src/build.inc.yml b/.github/workflows.src/build.inc.yml index 81f7e495b1e..f34e5cf229d 100644 --- a/.github/workflows.src/build.inc.yml +++ b/.github/workflows.src/build.inc.yml @@ -1,8 +1,8 @@ <% macro workflow(targets, publications, subdist="", publish_all=False) %> prep: runs-on: ubuntu-latest - outputs: <% if subdist == "nightly" %> + outputs: <% for tgt in targets.linux + targets.macos %> if_<< tgt.name.replace('-', '_') >>: ${{ steps.scm.outputs.if_<< tgt.name.replace('-', '_') >> }} <% endfor %> diff --git a/.github/workflows/dryrun.yml b/.github/workflows/dryrun.yml index 6743410f2b6..52ba415c8a0 100644 --- a/.github/workflows/dryrun.yml +++ b/.github/workflows/dryrun.yml @@ -7,8 +7,8 @@ on: jobs: prep: runs-on: ubuntu-latest - outputs: + outputs: if_debian_buster_x86_64: ${{ steps.scm.outputs.if_debian_buster_x86_64 }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 62c2c1a8f25..c3330e59874 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -12,8 +12,8 @@ on: jobs: prep: runs-on: ubuntu-latest - outputs: + outputs: if_debian_buster_x86_64: ${{ steps.scm.outputs.if_debian_buster_x86_64 }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9bdf49912f9..be60290ea45 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,6 @@ on: jobs: prep: runs-on: ubuntu-latest - outputs: steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index a328b2aafc7..2b34e6ce546 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -7,7 +7,6 @@ on: jobs: prep: runs-on: ubuntu-latest - outputs: steps: - uses: actions/checkout@v4 diff --git a/edb/server/dbview/dbview.pyi b/edb/server/dbview/dbview.pyi index caac4e4171b..f26fd0d7186 100644 --- a/edb/server/dbview/dbview.pyi +++ b/edb/server/dbview/dbview.pyi @@ -118,6 +118,9 @@ class Database: def lookup_config(self, name: str) -> Any: ... + def is_introspected(self) -> bool: + ... + class DatabaseConnectionView: def in_tx(self) -> bool: ... diff --git a/edb/server/dbview/dbview.pyx b/edb/server/dbview/dbview.pyx index ed376cf16ba..af3336de0e2 100644 --- a/edb/server/dbview/dbview.pyx +++ b/edb/server/dbview/dbview.pyx @@ -453,6 +453,9 @@ cdef class Database: if self.user_schema_pickle is None: await self.tenant.introspect_db(self.name) + def is_introspected(self): + return self.user_schema_pickle is not None + def lookup_config(self, name: str): spec = self._index._sys_config_spec if self.user_config_spec is not None: diff --git a/edb/server/net_worker.py b/edb/server/net_worker.py index 3a8b3f3e2bd..df632092a79 100644 --- a/edb/server/net_worker.py +++ b/edb/server/net_worker.py @@ -120,7 +120,7 @@ async def http(server: edbserver.BaseServer) -> None: tasks.append( tenant.create_task( _http_task(tenant, tenant_http[tenant]), - interruptable=False, + interruptable=True, ) ) # Remove unused tenant_http entries @@ -310,7 +310,7 @@ async def gc(server: edbserver.BaseServer) -> None: while True: tasks = [ tenant.create_task( - _gc(tenant, NET_HTTP_REQUEST_TTL), interruptable=False + _gc(tenant, NET_HTTP_REQUEST_TTL), interruptable=True ) for tenant in server.iter_tenants() if tenant.accept_new_tasks diff --git a/edb/server/protocol/auth_ext/email.py b/edb/server/protocol/auth_ext/email.py index bffe9f1f5c4..826ae5bb111 100644 --- a/edb/server/protocol/auth_ext/email.py +++ b/edb/server/protocol/auth_ext/email.py @@ -131,7 +131,7 @@ async def noop_coroutine() -> None: async def _protected_send( coro: Coroutine[Any, Any, None], tenant: tenant.Tenant ) -> None: - task = tenant.create_task(coro, interruptable=False) + task = tenant.create_task(coro, interruptable=True) # Prevent timing attack await asyncio.sleep(random.random() * 0.5) # Expose e.g. configuration errors diff --git a/edb/server/protocol/auth_ext/pkce.py b/edb/server/protocol/auth_ext/pkce.py index a8acfdc5752..b4d1c5ddde8 100644 --- a/edb/server/protocol/auth_ext/pkce.py +++ b/edb/server/protocol/auth_ext/pkce.py @@ -193,7 +193,7 @@ async def gc(server: edbserver.BaseServer) -> None: while True: try: tasks = [ - tenant.create_task(_gc(tenant), interruptable=False) + tenant.create_task(_gc(tenant), interruptable=True) for tenant in server.iter_tenants() if tenant.accept_new_tasks ] diff --git a/edb/server/tenant.py b/edb/server/tenant.py index d0ce0c0ecb1..948e39fbc62 100644 --- a/edb/server/tenant.py +++ b/edb/server/tenant.py @@ -591,6 +591,18 @@ def stop_accepting_connections(self) -> None: def accept_new_tasks(self): return self._accept_new_tasks + def is_db_ready(self, dbname: str) -> bool: + if not self._accept_new_tasks: + return False + + if ( + not (db := self.maybe_get_db(dbname=dbname)) + or not db.is_introspected() + ): + return False + + return True + def create_task( self, coro: Coroutine, @@ -962,7 +974,8 @@ def allow_database_connections(self, dbname: str) -> None: def is_database_connectable(self, dbname: str) -> bool: return ( - dbname != defines.EDGEDB_TEMPLATE_DB + self._running + and dbname != defines.EDGEDB_TEMPLATE_DB and dbname not in self._block_new_connections ) @@ -1662,7 +1675,7 @@ async def task(): self.create_task(task(), interruptable=True) def on_remote_ddl(self, dbname: str) -> None: - if not self._accept_new_tasks: + if not self.is_db_ready(dbname): return # Triggered by a postgres notification event 'schema-changes' @@ -1826,7 +1839,7 @@ def on_remote_query_cache_change( dbname: str, keys: Optional[list[str]], ) -> None: - if not self._accept_new_tasks: + if not self.is_db_ready(dbname): return async def task():