Skip to content

azure-functions-durable: native sync durable client binding (SyncDurableFunctionsClient) #181

Description

@andystaples

Summary

Add a first-class synchronous durable-client binding to azure-functions-durable so history export and scheduled-tasks code can obtain a sync durabletask client directly, instead of building one from the async binding.

Background

durable_client_input injects the async DurableFunctionsClient (an AsyncTaskHubGrpcClient). But several features use the sync durabletask clients:

  • history-export activities use a sync TaskHubGrpcClient;
  • ScheduledTaskClient and ExportHistoryClient are built on the sync client.

Today, route handlers and the export activities build a sync client from the async binding's config (rpcBaseUrl / taskHubName / requiredQueryStringParameters) via an async→sync adapter (_sync_client / _build_sync_client). That adapter is duplicated and a bit awkward.

Proposal

Add a sync client binding that injects a sync client built from the same host client-config JSON, removing the adapter. A sync consumer still needs the Functions conveniences (create_http_management_payload, create_check_status_response), so the injected type should be a real SyncDurableFunctionsClient carrying those helpers — not a bare TaskHubGrpcClient.

Naming: keep DurableFunctionsClient = async (avoids a breaking rename / v1 compat), add SyncDurableFunctionsClient. Retire the sync client once durabletask ships async ScheduledTaskClient / ExportHistoryClient.

Groundwork already merged (PR #155)

  • _add_rich_client is generic over the client constructor.
  • wrap_activity leaves native multi-binding activities untouched (so an activity can carry a durable-client binding).
  • The durable-client middleware invokes synchronous user functions (awaits only awaitable results).

So the remaining work is: a sync client class + a sync binding decorator + lifecycle/caching design.

Open design questions

  • Decorator shape: durable_client_input(..., sync=True) vs a separate durable_client_input_sync (the injected type differs).
  • Which Functions helpers / v1 shims the sync client carries.
  • Per-process caching and gRPC channel lifecycle (export fans out many activity invocations).

Context

Follow-up from #155.

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