Skip to content

Commit c71cec2

Browse files
authored
Merge branch 'main' into andystaples-query-instance-prefix
2 parents 5d6c4f2 + 95e0747 commit c71cec2

12 files changed

Lines changed: 82 additions & 36 deletions

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
groups:
6+
github-actions:
7+
patterns: ["*"]
8+
schedule:
9+
interval: "weekly"
10+
cooldown:
11+
default-days: 7

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
5858
steps:
5959
- name: Checkout repository
60-
uses: actions/checkout@v4
60+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
6161

6262
# Add any setup steps before running the `github/codeql-action/init` action.
6363
# This includes steps like installing compilers or runtimes (`actions/setup-node`
@@ -67,7 +67,7 @@ jobs:
6767

6868
# Initializes the CodeQL tools for scanning.
6969
- name: Initialize CodeQL
70-
uses: github/codeql-action/init@v4
70+
uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
7171
with:
7272
languages: ${{ matrix.language }}
7373
build-mode: ${{ matrix.build-mode }}
@@ -96,6 +96,6 @@ jobs:
9696
exit 1
9797
9898
- name: Perform CodeQL Analysis
99-
uses: github/codeql-action/analyze@v4
99+
uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6
100100
with:
101101
category: "/language:${{matrix.language}}"

.github/workflows/durabletask-azurefunctions.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
lint:
1818
runs-on: ubuntu-latest
1919
steps:
20-
- uses: actions/checkout@v4
20+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2121
- name: Set up Python 3.13
22-
uses: actions/setup-python@v5
22+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2323
with:
2424
python-version: 3.13
2525
- name: Install dependencies
@@ -38,10 +38,10 @@ jobs:
3838
runs-on: ubuntu-latest
3939
steps:
4040
- name: Checkout repository
41-
uses: actions/checkout@v4
41+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4242

4343
- name: Set up Python ${{ matrix.python-version }}
44-
uses: actions/setup-python@v5
44+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
4545
with:
4646
python-version: ${{ matrix.python-version }}
4747

@@ -70,15 +70,15 @@ jobs:
7070
name: e2e-tests (strict-typing=${{ matrix.strict-typing }})
7171
steps:
7272
- name: Checkout repository
73-
uses: actions/checkout@v4
73+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
7474

7575
- name: Set up Python 3.13
76-
uses: actions/setup-python@v5
76+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
7777
with:
7878
python-version: "3.13"
7979

8080
- name: Set up Node.js (needed for Azurite and Functions Core Tools)
81-
uses: actions/setup-node@v4
81+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
8282
with:
8383
node-version: "22.x"
8484

@@ -106,7 +106,7 @@ jobs:
106106
# pytest summary does not surface, so upload it for diagnosis.
107107
- name: Upload Functions host logs
108108
if: failure()
109-
uses: actions/upload-artifact@v4
109+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
110110
with:
111111
name: func-host-logs-strict-${{ matrix.strict-typing }}
112112
path: tests/azure-functions-durable/e2e/apps/*/_func_host.log

.github/workflows/durabletask-azuremanaged.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
lint:
1818
runs-on: ubuntu-latest
1919
steps:
20-
- uses: actions/checkout@v4
20+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2121
- name: Set up Python 3.14
22-
uses: actions/setup-python@v5
22+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2323
with:
2424
python-version: 3.14
2525
- name: Install dependencies
@@ -38,10 +38,10 @@ jobs:
3838
runs-on: ubuntu-latest
3939
steps:
4040
- name: Checkout repository
41-
uses: actions/checkout@v4
41+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4242

4343
- name: Set up Python ${{ matrix.python-version }}
44-
uses: actions/setup-python@v5
44+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
4545
with:
4646
python-version: ${{ matrix.python-version }}
4747

.github/workflows/durabletask.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
lint-and-unit-tests:
1818
runs-on: ubuntu-latest
1919
steps:
20-
- uses: actions/checkout@v4
20+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2121
- name: Set up Python 3.14
22-
uses: actions/setup-python@v5
22+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2323
with:
2424
python-version: 3.14
2525
- name: Install dependencies
@@ -38,20 +38,20 @@ jobs:
3838
runs-on: ubuntu-latest
3939
steps:
4040
- name: Checkout repository
41-
uses: actions/checkout@v4
41+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4242

4343
- name: Set up Python ${{ matrix.python-version }}
44-
uses: actions/setup-python@v5
44+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
4545
with:
4646
python-version: ${{ matrix.python-version }}
4747

4848
- name: Set up Node.js (needed for Azurite)
49-
uses: actions/setup-node@v4
49+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
5050
with:
5151
node-version: '22.x'
5252

5353
- name: Cache npm
54-
uses: actions/cache@v3
54+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
5555
with:
5656
path: ~/.npm
5757
key: ${{ runner.os }}-npm-azurite

.github/workflows/typecheck.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ jobs:
2020
runs-on: ubuntu-latest
2121
steps:
2222
- name: Checkout repository
23-
uses: actions/checkout@v4
23+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2424

2525
- name: Set up Python 3.10 (lowest supported)
26-
uses: actions/setup-python@v5
26+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
2727
with:
2828
python-version: "3.10"
2929

@@ -39,10 +39,10 @@ jobs:
3939
runs-on: ubuntu-latest
4040
steps:
4141
- name: Checkout repository
42-
uses: actions/checkout@v4
42+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
4343

4444
- name: Set up Python 3.13 (lowest supported by azure-functions-durable)
45-
uses: actions/setup-python@v5
45+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
4646
with:
4747
python-version: "3.13"
4848

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ ADDED
1111

1212
- Added `OrchestrationQuery.instance_id_prefix` to retrieve orchestration
1313
instances whose IDs begin with a specified prefix.
14+
- Added the optional `new_version` argument to
15+
`OrchestrationContext.continue_as_new()` so continued orchestrations can
16+
switch to a new version.
1417

1518
## v1.9.0
1619

@@ -53,6 +56,9 @@ import paths, `__all__`, `dir()`, and star-imports behave exactly as before.
5356

5457
FIXED
5558

59+
- Fixed `TaskHubGrpcWorker` leaving its background event loop unclosed after
60+
shutdown, which could retain resources and emit delayed `ResourceWarning`
61+
messages.
5662
- Fixed `AsyncTaskHubGrpcClient` failing during construction when no current
5763
event loop was set. SDK-owned async gRPC channels are now created on first use,
5864
binding them to the event loop that performs the RPC.

durabletask/internal/helpers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,14 @@ def new_complete_orchestration_action(
300300
status: pb.OrchestrationStatus,
301301
result: str | None = None,
302302
failure_details: pb.TaskFailureDetails | None = None,
303-
carryover_events: list[pb.HistoryEvent] | None = None) -> pb.OrchestratorAction:
303+
carryover_events: list[pb.HistoryEvent] | None = None,
304+
new_version: str | None = None) -> pb.OrchestratorAction:
304305
completeOrchestrationAction = pb.CompleteOrchestrationAction(
305306
orchestrationStatus=status,
306307
result=get_string_value(result),
307308
failureDetails=failure_details,
308-
carryoverEvents=carryover_events)
309+
carryoverEvents=carryover_events,
310+
newVersion=get_string_value(new_version))
309311

310312
return pb.OrchestratorAction(id=id, completeOrchestration=completeOrchestrationAction)
311313

durabletask/task.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ def send_event(self, instance_id: str, event_name: str, *,
389389
)
390390

391391
@abstractmethod
392-
def continue_as_new(self, new_input: Any, *, save_events: bool = False) -> None:
392+
def continue_as_new(self, new_input: Any, *, save_events: bool = False,
393+
new_version: str | None = None) -> None:
393394
"""Continue the orchestration execution as a new instance.
394395
395396
Parameters
@@ -398,6 +399,8 @@ def continue_as_new(self, new_input: Any, *, save_events: bool = False) -> None:
398399
The new input to use for the new orchestration instance.
399400
save_events : bool
400401
A flag indicating whether to add any unprocessed external events in the new orchestration history.
402+
new_version : str | None
403+
An optional version to assign to the new orchestration instance.
401404
"""
402405
pass
403406

durabletask/worker.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -760,9 +760,7 @@ def start(self):
760760
self._shutdown.clear()
761761

762762
def run_loop() -> None:
763-
loop = asyncio.new_event_loop()
764-
asyncio.set_event_loop(loop)
765-
loop.run_until_complete(self._async_run_loop())
763+
asyncio.run(self._async_run_loop())
766764

767765
self._logger.info(f"Starting gRPC worker that connects to {self._host_address}")
768766
self._runLoop = Thread(target=run_loop)
@@ -1523,6 +1521,7 @@ def __init__(self,
15231521
self._received_events: dict[str, list[str | None]] = {}
15241522
self._pending_events: dict[str, list[task.CancellableTask[Any]]] = {}
15251523
self._new_input: Any | None = None
1524+
self._new_version: str | None = None
15261525
self._save_events = False
15271526
self._encoded_custom_status: str | None = None
15281527
self._parent_trace_context: pb.TraceContext | None = None
@@ -1619,7 +1618,8 @@ def set_failed(self, ex: Exception | pb.TaskFailureDetails):
16191618
)
16201619
self._pending_actions[action.id] = action
16211620

1622-
def set_continued_as_new(self, new_input: Any, save_events: bool):
1621+
def set_continued_as_new(self, new_input: Any, save_events: bool,
1622+
new_version: str | None = None):
16231623
if self._is_complete:
16241624
return
16251625

@@ -1633,6 +1633,7 @@ def set_continued_as_new(self, new_input: Any, save_events: bool):
16331633
# self._pending_actions.clear() # Cancel any pending actions
16341634
self._completion_status = pb.ORCHESTRATION_STATUS_CONTINUED_AS_NEW
16351635
self._new_input = new_input
1636+
self._new_version = new_version
16361637
self._save_events = save_events
16371638

16381639
def get_actions(self) -> list[pb.OrchestratorAction]:
@@ -1657,6 +1658,7 @@ def get_actions(self) -> list[pb.OrchestratorAction]:
16571658
result=self._data_converter.serialize(self._new_input),
16581659
failure_details=None,
16591660
carryover_events=carryover_events,
1661+
new_version=self._new_version,
16601662
)
16611663
# We must return the existing tasks as well, to capture entity unlocks
16621664
current_actions.append(action)
@@ -2135,11 +2137,12 @@ def send_event(self, instance_id: str, event_name: str, *,
21352137
),
21362138
)
21372139

2138-
def continue_as_new(self, new_input: Any, *, save_events: bool = False) -> None:
2140+
def continue_as_new(self, new_input: Any, *, save_events: bool = False,
2141+
new_version: str | None = None) -> None:
21392142
if self._is_complete:
21402143
return
21412144

2142-
self.set_continued_as_new(new_input, save_events)
2145+
self.set_continued_as_new(new_input, save_events, new_version)
21432146

21442147
def new_uuid(self) -> str:
21452148
NAMESPACE_UUID: str = "9e952958-5e33-4daf-827f-2fa12937b875"

0 commit comments

Comments
 (0)