Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1154 +/- ##
==========================================
+ Coverage 93.79% 93.99% +0.20%
==========================================
Files 54 54
Lines 3803 3899 +96
==========================================
+ Hits 3567 3665 +98
+ Misses 236 234 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
5bbadc2 to
033624c
Compare
7322d8e to
7c3d462
Compare
7c3d462 to
6f9300e
Compare
6f9300e to
c2f5a87
Compare
Pijukatel
left a comment
There was a problem hiding this comment.
I am struggling a lot with the variable naming in this PR. Reading this with fresh eyes the variable names gave me a lot of false leads instead of building a helpful mental model.
The usage of word slot here had a very confusing effect on me. One time it was for an asyncio.Condition and the second time for a very custom context manager that uses the first one inside...
On top of it, slot has its own established meaning in Python, but here it is not related in any manner.
… and applies a new limit
Pijukatel
left a comment
There was a problem hiding this comment.
Thanks. It reads way better with new names. Just two more nits, otherwise good.
|
Btw. not using RecoverableState for persitence? |
Refactored to use it. |
| """ | ||
| return self._child_run_registry.run_clients(self.apify_client) | ||
|
|
||
| def set_named_child_run_limits(self, *, max_concurrent_runs: int | None) -> None: |
There was a problem hiding this comment.
It feels rather arbitrary to be able to limit only the named runs.
If we unzoom from the rest of the composability PRs, this option / method could work on its own imo (Actor.setMaxChildRunCount(10) -> there's a local queue of runs that allows for at most 10 concurrent runs).
There was a problem hiding this comment.
I'm not sure this is a good idea.
Everything we added for Actor composability up until now (reattach, resurrect, abort_with_parent, Actor.child_runs) works through run_name. The run name is what lets the SDK find the run again after a migration.
Without a name, the count of running children exists only in memory. So after a migration the count is gone, and the limit stops working (the old unnamed runs would keep running, and new starts would not wait for them). A limit that holds only until the first migration is half working feature, maybe I wouldn't be afraid call it a broken feature since beginning 😄 , definitely something you can't rely on.
So I'd rather keep the limit for named runs only and document that runs without run_name aren't counted. The same as the other composability features.
In the next major version, I'd even be for making run_name a required argument. A child run without a name can't survive a migration (you lose track of it, to be more precise), so IMO there isn't a good reason to start one.
Or am I missing something?
…urrency-limit # Conflicts: # src/apify/_child_runs.py
Adds
Actor.set_named_child_run_limits(max_concurrent_runs=...). While that many named child runs areREADY,RUNNING,ABORTINGorTIMING-OUT, a namedActor.start,Actor.call,Actor.start_taskorActor.call_taskthat would start or resurrect a run waits for one of them to finish. Reattaching to a recorded run never waits, and runs without arun_namearen't counted.The count comes from the child run registry, so children started before a migration count too. A child's status is fetched again before counting once it's more than 10 seconds old, so a finished run nobody waited on stops counting.
Actor.callandActor.call_taskstop counting their run as soon as it finishes. A start counts toward the limit until its run is recorded, which keeps concurrent starts under different names within the limit.The limit lives in memory, so the Actor sets it again after a migration. Once the parent receives
ABORTING, a start still waiting under the limit raises aRuntimeErrorwithout starting a run. Waiting further would block the abort of the other children.The child run registry is also persisted through crawlee's
RecoverableState. It still saves on every change, under the same key and in the same JSON shape.Closes: #1138
✍️ Drafted by Claude Code