Skip to content

Commit cc0cd89

Browse files
authored
Merge branch 'main' into andystaples-failure-details-properties
2 parents ddaa948 + 95e0747 commit cc0cd89

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
@@ -14,6 +14,9 @@ ADDED
1414
properties to activity, entity, and orchestration failures. Failure
1515
properties and recursive inner failures are available through
1616
`FailureDetails`, task-failure exceptions, orchestration state, and history.
17+
- Added the optional `new_version` argument to
18+
`OrchestrationContext.continue_as_new()` so continued orchestrations can
19+
switch to a new version.
1720

1821
## v1.9.0
1922

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

5760
FIXED
5861

62+
- Fixed `TaskHubGrpcWorker` leaving its background event loop unclosed after
63+
shutdown, which could retain resources and emit delayed `ResourceWarning`
64+
messages.
5965
- Fixed `AsyncTaskHubGrpcClient` failing during construction when no current
6066
event loop was set. SDK-owned async gRPC channels are now created on first use,
6167
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
@@ -418,12 +418,14 @@ def new_complete_orchestration_action(
418418
status: pb.OrchestrationStatus,
419419
result: str | None = None,
420420
failure_details: pb.TaskFailureDetails | None = None,
421-
carryover_events: list[pb.HistoryEvent] | None = None) -> pb.OrchestratorAction:
421+
carryover_events: list[pb.HistoryEvent] | None = None,
422+
new_version: str | None = None) -> pb.OrchestratorAction:
422423
completeOrchestrationAction = pb.CompleteOrchestrationAction(
423424
orchestrationStatus=status,
424425
result=get_string_value(result),
425426
failureDetails=failure_details,
426-
carryoverEvents=carryover_events)
427+
carryoverEvents=carryover_events,
428+
newVersion=get_string_value(new_version))
427429

428430
return pb.OrchestratorAction(id=id, completeOrchestration=completeOrchestrationAction)
429431

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
@@ -765,9 +765,7 @@ def start(self):
765765
self._shutdown.clear()
766766

767767
def run_loop() -> None:
768-
loop = asyncio.new_event_loop()
769-
asyncio.set_event_loop(loop)
770-
loop.run_until_complete(self._async_run_loop())
768+
asyncio.run(self._async_run_loop())
771769

772770
self._logger.info(f"Starting gRPC worker that connects to {self._host_address}")
773771
self._runLoop = Thread(target=run_loop)
@@ -1534,6 +1532,7 @@ def __init__(self,
15341532
self._received_events: dict[str, list[str | None]] = {}
15351533
self._pending_events: dict[str, list[task.CancellableTask[Any]]] = {}
15361534
self._new_input: Any | None = None
1535+
self._new_version: str | None = None
15371536
self._save_events = False
15381537
self._encoded_custom_status: str | None = None
15391538
self._parent_trace_context: pb.TraceContext | None = None
@@ -1642,7 +1641,8 @@ def set_failed(self, ex: Exception | pb.TaskFailureDetails):
16421641
)
16431642
self._pending_actions[action.id] = action
16441643

1645-
def set_continued_as_new(self, new_input: Any, save_events: bool):
1644+
def set_continued_as_new(self, new_input: Any, save_events: bool,
1645+
new_version: str | None = None):
16461646
if self._is_complete:
16471647
return
16481648

@@ -1656,6 +1656,7 @@ def set_continued_as_new(self, new_input: Any, save_events: bool):
16561656
# self._pending_actions.clear() # Cancel any pending actions
16571657
self._completion_status = pb.ORCHESTRATION_STATUS_CONTINUED_AS_NEW
16581658
self._new_input = new_input
1659+
self._new_version = new_version
16591660
self._save_events = save_events
16601661

16611662
def get_actions(self) -> list[pb.OrchestratorAction]:
@@ -1680,6 +1681,7 @@ def get_actions(self) -> list[pb.OrchestratorAction]:
16801681
result=self._data_converter.serialize(self._new_input),
16811682
failure_details=None,
16821683
carryover_events=carryover_events,
1684+
new_version=self._new_version,
16831685
)
16841686
# We must return the existing tasks as well, to capture entity unlocks
16851687
current_actions.append(action)
@@ -2158,11 +2160,12 @@ def send_event(self, instance_id: str, event_name: str, *,
21582160
),
21592161
)
21602162

2161-
def continue_as_new(self, new_input: Any, *, save_events: bool = False) -> None:
2163+
def continue_as_new(self, new_input: Any, *, save_events: bool = False,
2164+
new_version: str | None = None) -> None:
21622165
if self._is_complete:
21632166
return
21642167

2165-
self.set_continued_as_new(new_input, save_events)
2168+
self.set_continued_as_new(new_input, save_events, new_version)
21662169

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

0 commit comments

Comments
 (0)