Skip to content

postgres_reliable_reporting_service always builds the base ReliableReportingService, so adopters can't use a subclass #1588

Description

@bokelley

Observed

ReliableReportingService.memory(...) constructs cls, so an adopter's subclass gets an in-memory service of its own type. adcp_reporting_storage.postgres_reliable_reporting_service(...) replaced ReliableReportingService.postgres(...) in 9.0.0 (#1557), and it always constructs the base ReliableReportingService:

from psycopg_pool import AsyncConnectionPool

from adcp.reporting import ReliableReportingService
from adcp_reporting_storage import postgres_reliable_reporting_service


class HostReportingService(ReliableReportingService):
    async def get_reporting_status(self, request, context=None):
        ...  # host-specific error translation / alerting


def account_context(*_args, **_kwargs):
    raise NotImplementedError


memory = HostReportingService.memory(account_context=account_context)
pg = postgres_reliable_reporting_service(
    pool=AsyncConnectionPool("postgresql://unused", open=False), account_context=account_context
)
print("memory():", type(memory).__name__)
print("postgres_reliable_reporting_service():", type(pg).__name__)

With adcp 9.0.0 and adcp-reporting-storage 0.1.0b1 (built from the #1571 branch):

memory(): HostReportingService
postgres_reliable_reporting_service(): ReliableReportingService

Expected

The PostgreSQL factory can build an adopter's subclass, as memory() and the 9.0 betas' ReliableReportingService.postgres() classmethod could. For example, a service_class: type[ReliableReportingService] = ReliableReportingService keyword.

Impact

install() routes the reporting tools to the service's methods, so overriding them on a subclass is how a host translates errors and adds alerting around get_reporting_status, sync_reporting_status and get_revision_content. Without a way to pick the class, the Embedded Sales Agent copies the factory body: it builds PgReportingLedgerStore, PgReportingStagingStore and PgReportingSealStore and passes staging=, seals= and initialize_source_storage= itself. That copy silently drifts whenever the factory gains a store, for example when production= composes PgReportingProductionStore.

Found while moving the Embedded Sales Agent from 9.0.0b4 to 9.0.0. Since adcp-reporting-storage hasn't had its first release yet, this could land before 0.1.0b1 publishes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions