Changelog ========= 0.1.3 - 2026-06-03 ------------------ Correctness and safety release for WorkGrinder validation, event-loop ownership, cross-thread APIs, cancellation cleanup, partial batch submission handling, and process log forwarding. Changed ~~~~~~~ * WorkGrinder now validates ``batch_size_threshold`` as a strict positive integer. Fractional values, booleans, strings, zero, and negative values are rejected instead of being silently coerced. * WorkGrinder now validates ``max_wait_seconds`` and ``lease_seconds`` as finite positive durations. ``NaN`` and infinity are rejected at construction time. * ``LeasedExecutorManager.start()``, ``stop()``, and ``acquire()`` now enforce owning event-loop usage after the manager has started. * ``WorkGrinder.submit_from_thread()`` and ``stats_from_thread()`` now fail fast when called from the owning event-loop thread. Use the async APIs from the owning event loop. * Process log forwarding now defaults to a non-fork multiprocessing context when no explicit ``mp_context`` is provided, preferring ``forkserver`` and then ``spawn``. Fixed ~~~~~ * Fixed wrong-loop ``LeasedExecutorManager.stop()`` calls mutating manager state before failing. * Fixed wrong-loop ``LeasedExecutorManager.acquire()`` calls waiting on loop-bound state and potentially missing wakeups. * Fixed cancelled pending WorkGrinder items remaining in the pending queue until threshold, timeout, or shutdown. * Fixed partial WorkGrinder batch submission failures so already-submitted work receives its real result or exception, while only unsubmitted work receives the submission error. 0.1.2 ----- Stability release focused on executor lifecycle correctness, shutdown behavior, validation, and WorkGrinder safety. Fixed: * prevented ``LeasedExecutorManager.acquire()`` from returning a new lease while the manager is stopping or stopped; * woke the checker when new leases are acquired so short lease expiries are not delayed by a long ``check_interval``; * prevented expired leases from recycling their executors; * added lease draining so executors with submitted futures are not returned to the pool until those futures finish; * retired broken executors instead of returning them to the pool; * deferred executor shutdown from future callbacks to avoid callback-thread deadlocks or hangs; * validated integer sizing options without silent float truncation; * rejected negative, zero where invalid, NaN, and infinite timing values; * rejected non-positive or non-finite ``check_interval`` values; * fixed ``WorkGrinder.stop(cancel_pending=True)`` so it can cancel a grinder task blocked in lease acquisition or waiting for executor work; * added WorkGrinder event-loop ownership checks. Testing: * added regression coverage for manager shutdown races; * added regression coverage for lease expiry scheduling and expired release; * added regression coverage for draining leases with pending futures; * added regression coverage for broken thread, process, and Python 3.14+ interpreter executors; * added regression coverage for validation edge cases; * added regression coverage for WorkGrinder cancellation and cross-thread APIs. 0.1.0 ----- Initial planned release. Features: * leased executor manager; * thread backend; * process backend; * future interpreter backend selector for Python 3.14+; * lease expiry and revocation; * acquire backpressure with ``wait`` and ``timeout``; * adaptive sizing with ``size_provider`` and ``notify_scale_changed()``; * ``WorkGrinder`` batching; * process-worker log forwarding; * public exceptions; * examples pack; * Sphinx documentation.