Skip to content

Remove Transducers extension, always await spawned loader tasks - #229

Merged
CarloLucibello merged 1 commit into
mainfrom
cl/remove-transducers-ext
Jun 14, 2026
Merged

Remove Transducers extension, always await spawned loader tasks#229
CarloLucibello merged 1 commit into
mainfrom
cl/remove-transducers-ext

Conversation

@CarloLucibello

@CarloLucibello CarloLucibello commented Jun 14, 2026

Copy link
Copy Markdown
Member

Follow-up to #215.

Remove the Transducers extension

#215 moved Transducers to a weakdep + TransducersExt, which provided a Transducers.__foldl__ method for DataLoader. This PR removes that extension entirely:

  • Deletes ext/TransducersExt.jl and the [weakdeps]/[extensions]/[compat] Transducers entries.
  • Drops Transducers from the test dependencies and the using Transducers import.
  • Removes the "Transducers foldl" testset (the only consumer of the protocol).

Rationale: the fold protocol was never documented — there's no mention of Transducers/foldl/eduction in the docs, the DataLoader docstring, or the README, and eachobsparallel/Loader are internal. It was only exercised by that one testset. After this change MLUtils precompiles with no reference to Transducers at all.

Always await the right-half spawned task

Hardens the parallel Loader divide-and-conquer (_spawn_foreach): the @spawned right half is now awaited via try/finally, so it never outlives the call when the left half throws.

  • Happy path: unchanged — wait still propagates a right-half failure.
  • Error path: the outer handler's close(ch, e) unblocks any put! the right half is parked on, so it terminates instead of leaking as an orphaned task (which could surface as a stray "unhandled task failure" log).

Testing

  • eachobsparallel testset: 9/9 pass.
  • DataLoader testset passes (Transducers foldl testset removed).
  • Package precompiles cleanly without Transducers.
  • Error-propagation / deadlock stress test: a getobs that throws partway, across 1/2/4/8 threads × 50 reps × 7 size/fail-point configs — every case propagates the error to the consumer with no hang, and the happy path stays correct and complete.

🤖 Generated with Claude Code

Drops the `TransducersExt` weakdep extension entirely. It provided a
`Transducers.__foldl__` method for `DataLoader`, but that capability was
never documented (no mention in the docs, the `DataLoader` docstring, or
the README) and was only exercised by a single testset. Removing it
clears the last `Transducers` reference from the package, so `MLUtils`
now precompiles with no dependency on it.

Also hardens the parallel `Loader`'s divide-and-conquer: the right-half
`@spawn`ed task is now awaited via `try`/`finally`, so it never outlives
the call when the left half throws. The happy path is unchanged (`wait`
still propagates a right-half failure); on the error path the outer
handler's `close(ch, e)` unblocks any `put!` the right half is parked on
so it can terminate instead of leaking as an orphan.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CarloLucibello
CarloLucibello merged commit bfebb3f into main Jun 14, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant