diff --git a/CHANGELOG.md b/CHANGELOG.md index 572ff4a0..96a92565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ADDED +- Added `OrchestrationQuery.instance_id_prefix` to retrieve orchestration +instances whose IDs begin with a specified prefix. - Added the optional `new_version` argument to `OrchestrationContext.continue_as_new()` so continued orchestrations can switch to a new version. diff --git a/azure-functions-durable/CHANGELOG.md b/azure-functions-durable/CHANGELOG.md index f5e4adf3..4d19faec 100644 --- a/azure-functions-durable/CHANGELOG.md +++ b/azure-functions-durable/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +ADDED + +- Added inherited `OrchestrationQuery.instance_id_prefix` support to retrieve +orchestration instances whose IDs begin with a specified prefix. + ## v2.0.0b2 ADDED diff --git a/durabletask-azuremanaged/CHANGELOG.md b/durabletask-azuremanaged/CHANGELOG.md index dde10137..6e671cd1 100644 --- a/durabletask-azuremanaged/CHANGELOG.md +++ b/durabletask-azuremanaged/CHANGELOG.md @@ -7,6 +7,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## Unreleased +ADDED + +- Added inherited `OrchestrationQuery.instance_id_prefix` support to retrieve +orchestration instances whose IDs begin with a specified prefix. + ## v1.9.0 CHANGED diff --git a/durabletask/client.py b/durabletask/client.py index a5974749..b88df604 100644 --- a/durabletask/client.py +++ b/durabletask/client.py @@ -196,6 +196,7 @@ class OrchestrationQuery: # results instead. max_instance_count: int | None = (1 << 31) - 1 fetch_inputs_and_outputs: bool = False + instance_id_prefix: str | None = None @dataclass diff --git a/durabletask/internal/client_helpers.py b/durabletask/internal/client_helpers.py index fe0c828b..d3c51181 100644 --- a/durabletask/internal/client_helpers.py +++ b/durabletask/internal/client_helpers.py @@ -103,6 +103,7 @@ def build_query_instances_req( runtimeStatus=[status.value for status in orchestration_query.runtime_status] if orchestration_query.runtime_status else None, createdTimeFrom=helpers.new_timestamp(orchestration_query.created_time_from) if orchestration_query.created_time_from else None, createdTimeTo=helpers.new_timestamp(orchestration_query.created_time_to) if orchestration_query.created_time_to else None, + instanceIdPrefix=helpers.get_string_value(orchestration_query.instance_id_prefix), maxInstanceCount=orchestration_query.max_instance_count, fetchInputsAndOutputs=orchestration_query.fetch_inputs_and_outputs, continuationToken=continuation_token diff --git a/tests/durabletask/test_batch_actions.py b/tests/durabletask/test_batch_actions.py index 65637df0..24989746 100644 --- a/tests/durabletask/test_batch_actions.py +++ b/tests/durabletask/test_batch_actions.py @@ -12,6 +12,7 @@ import pytest from durabletask import client, entities, task from durabletask.client import TaskHubGrpcClient +from durabletask.internal.client_helpers import build_query_instances_req from durabletask.testing import create_test_backend from durabletask.worker import TaskHubGrpcWorker @@ -163,6 +164,47 @@ def test_get_orchestration_state_by_time_range(backend): assert len([o for o in orchestrations_outside_range if o.instance_id == id]) == 0 +def test_get_orchestration_state_by_instance_id_prefix(backend): + worker = TaskHubGrpcWorker(host_address=HOST) + + worker.add_orchestrator(empty_orchestrator) + worker.start() + + try: + with TaskHubGrpcClient(host_address=HOST) as c: + matching_id = "prefix-match" + non_matching_id = "other-instance" + c.schedule_new_orchestration(empty_orchestrator, instance_id=matching_id) + c.schedule_new_orchestration(empty_orchestrator, instance_id=non_matching_id) + c.wait_for_orchestration_completion(matching_id, timeout=30) + c.wait_for_orchestration_completion(non_matching_id, timeout=30) + + query = client.OrchestrationQuery(instance_id_prefix="prefix-") + orchestrations = c.get_all_orchestration_states(query) + finally: + worker.stop() + + assert [orchestration.instance_id for orchestration in orchestrations] == [matching_id] + + +def test_orchestration_query_serializes_instance_id_prefix(): + request = build_query_instances_req( + client.OrchestrationQuery(instance_id_prefix="prefix-"), + continuation_token=None, + ) + + assert request.query.HasField("instanceIdPrefix") + assert request.query.instanceIdPrefix.value == "prefix-" + + +def test_orchestration_query_preserves_positional_argument_order(): + query = client.OrchestrationQuery(None, None, None, None, True) + + assert query.max_instance_count is None + assert query.fetch_inputs_and_outputs is True + assert query.instance_id_prefix is None + + def test_get_orchestration_state_pagination_succeeds(backend): # Create a custom handler to capture log messages log_records = []