Split databases and Redis — prepare infrastructure for per-domain isolation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m20s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 3m20s
Redis: per-app DB index (0-5) with shared auth DB 15 for SSO keys; flushdb replaces flushall so deploys don't wipe cross-app auth state. Postgres: drop 13 cross-domain FK constraints (migration v2t0p8q9r0), remove dead ORM relationships, add explicit joins for 4 live ones. Multi-engine sessions (account + federation) ready for per-domain DBs via DATABASE_URL_ACCOUNT / DATABASE_URL_FEDERATION env vars. All URLs initially point to the same appdb — zero behaviour change until split-databases.sh is run to migrate data to per-domain DBs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,72 @@ async def get_session():
|
||||
await sess.close()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Cross-domain sessions — account + federation
|
||||
#
|
||||
# Initially DATABASE_URL_ACCOUNT / DATABASE_URL_FEDERATION point to the same
|
||||
# DB as DATABASE_URL (zero behaviour change). When per-domain DBs are ready,
|
||||
# switch the env vars to the new connection strings.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DATABASE_URL_ACCOUNT = (
|
||||
os.getenv("DATABASE_URL_ACCOUNT") or DATABASE_URL
|
||||
)
|
||||
|
||||
DATABASE_URL_FEDERATION = (
|
||||
os.getenv("DATABASE_URL_FEDERATION") or DATABASE_URL
|
||||
)
|
||||
|
||||
# Engines are created lazily — only allocate a pool if the URL differs
|
||||
_account_engine = (
|
||||
_engine if DATABASE_URL_ACCOUNT == DATABASE_URL
|
||||
else create_async_engine(
|
||||
DATABASE_URL_ACCOUNT,
|
||||
future=True, echo=False, pool_pre_ping=True,
|
||||
pool_size=3, max_overflow=5,
|
||||
)
|
||||
)
|
||||
_AccountSession = async_sessionmaker(
|
||||
bind=_account_engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
|
||||
_federation_engine = (
|
||||
_engine if DATABASE_URL_FEDERATION == DATABASE_URL
|
||||
else create_async_engine(
|
||||
DATABASE_URL_FEDERATION,
|
||||
future=True, echo=False, pool_pre_ping=True,
|
||||
pool_size=3, max_overflow=5,
|
||||
)
|
||||
)
|
||||
_FederationSession = async_sessionmaker(
|
||||
bind=_federation_engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def get_account_session():
|
||||
"""Session targeting the account database (users, grants, oauth codes)."""
|
||||
sess = _AccountSession()
|
||||
try:
|
||||
yield sess
|
||||
finally:
|
||||
await sess.close()
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def get_federation_session():
|
||||
"""Session targeting the federation database (ap_activities, etc.)."""
|
||||
sess = _FederationSession()
|
||||
try:
|
||||
yield sess
|
||||
finally:
|
||||
await sess.close()
|
||||
|
||||
|
||||
def register_db(app: Quart):
|
||||
|
||||
@app.before_request
|
||||
|
||||
Reference in New Issue
Block a user