Async-Event-Interval
view release on metacpan or search on metacpan
- shared_scalar() no longer stores tied refs inside %events;
%events now holds an arrayref of hex key strings instead,
eliminating a same-process FETCH deadlock in IPC::Shareable
- $SIG{__WARN__} moved to local inside _event() so it no longer
silently replaces the caller's handler at module load; $SIG{CHLD}
remains at file scope (children outlive _event(), need auto-reap)
- Add write-path tests and automated source audit to t/09-locking.t
- Extract _run_callback() from _event() to deduplicate the eval +
error-capture + store pattern and isolate $@ preservation
- Add _end() clean_up_protected coverage test; fix _end() mock-counter
test that was silently destroying the semaphore set, causing 11
subsequent tests to be skipped; fix events() deep-copy still treating
shared_scalars as a hashref instead of the new arrayref
- Fix fork failure silently falling through to child path and running
the callback in the parent process; now croaks with "fork() failed"
- Wrap _run_callback in eval inside _event() and always call
_pm->finish($@ ? 1 : 0) so ForkManager isn't left with a stale
child record when the callback dies
- Guard _end() with a local SIGALRM (END_LOCK_TIMEOUT, default 2s)
so process exit doesn't block forever on _events_read' LOCK_SH if
a peer still holds LOCK_EX on the events knot
- stop() now polls kill(0) at STOP_KILL_POLL_INTERVAL (0.05s) for up
to STOP_KILL_TIMEOUT (1s) instead of always sleeping a fixed 1s;
returns as soon as the target process is gone (full test suite
wallclock roughly halved)
- Refactor error()/status() to remove their mutual-recursion
side-effect chain. Crash detection now lives in a private
_detect_crash helper that both methods call independently
- Retire the undocumented -99 PID sentinel that marked crashes
- stop() now sends SIGTERM first (STOP_TERM_TIMEOUT 0.5s) and escalates
to SIGKILL only if the child is still alive; _signal_and_wait() helper
encapsulates the signal-and-poll logic
- Replace mutable module-level $is_child_process flag with
$$ != $creator_pid check in DESTROY; a forked child inherently has
a different PID than the process that loaded the module, so no
mutable state that mock-fork tests can corrupt is needed
- Replace lexical $id counter with shared _id_counter in %events to
prevent duplicate IDs across forked processes
- Closes #15; Add _stop_requested cooperative flag in shared %events so the
child's interval loop can break cleanly and call finish() instead of being
killed by SIGTERM; stop() sets it, start() clears it, the loop checks it
on each iteration
- Closes #14; Add timeout() accessor so a callback that exceeds the
specified number of whole seconds self-terminates with an error.
Accepts a non-negative integer or undef; fractional seconds are
not supported
- Closes #9; Add immediate() method. Set a flag to have the event fire
immediately on start rather than waiting for the first interval to be
reached
- Adopt IPC::Shareable's testing_set/clean_up_testing API to brand all
test-suite segments and purge orphans from prior crashed runs; bump
IPC::Shareable prereq to 1.17
- Fixes and enhancements to the local VM test infrastructure
- Pin Parallel::ForkManager to < 2.00 on Perl < 5.14 to avoid Moo XS
compile failures on macOS
- Guard DESTROY's _events_write in eval and clear stale _lock on
failure to prevent EAGAIN from IPC::Shareable's unlock() leaking
IPC segments on Linux
- Ensure counters are properly cleaned up in _end() cleanup
- Use Time::HiRes wall-clock time in _signal_and_wait so stop() timeout
is accurate on busy/VM systems where select() jitter accumulates
- Relax t/15-interval.t exact-count timing checks to >= so slow macOS VMs
don't fail before the first callback fires
- _detect_crash no longer marks cleanly-exited one-shot events as
crashed; child writes _clean_exit flag to shared %events before
finish(0) so the parent can distinguish normal completion from a crash
- Fix flaky t/90 on macOS CI by replacing nested-hash shared memory
writes with flat keys, eliminating child-segment race between forks
- Fix shared memory leak on SIGINT/SIGTERM: install signal handlers
that run _end() cleanup before re-raising; _end() now unconditionally
stops children and removes protected segments instead of skipping
when _event_count > 0
- Fix _end() SIGALRM deadlock: clear SA_RESTART via POSIX::sigaction so
the alarm actually interrupts blocked semop(); split the single 2s alarm
into per-phase evals so each cleanup step runs even when an earlier one
times out; add @all_pids fallback so children are killed even when the
%events read-lock is stuck
- Add 'error' and 'waiting' fields to events() and info() snapshots
- Add wait() method that polls until the event is dormant (optional
poll interval, default 0.01s)
1.13 2024-03-04
- Added ability to send in per-callback call parameters via the start()
method (closes #10)
- Add prereq of Test::SharedFork to keep tests in order in t/46
- Bumped prereq version of IPC::Shareable to 1.13
1.12 2022-03-31
- Only remove the Async::Event::Interval protected shared %events hash
if it doesn't contain keys (ie. event objects). When running in things
like 'plackup', END{} was being called on each browser session close,
but there were still objects, so we were trashing the %events
infrastructure prematurely
- Each unit test file now does pre-and-post segment counts and displays
them if PRINT_SEGS env var is true, and the suite itself has a before
and after count comparison to ensure the suite leaked no segments or
semaphores
- Fix issue where we were trying to set a _pid() on an undefined value,
causing IPC::Shareable to complain that "Can't STORE on undef val"
1.11 2022-03-09
- Modified tests to run only on valid CI platforms
1.10 2022-03-07
- Add tests to ensure that all shared memory segments created during the
unit test suite run get cleaned up ok
- Bump prereq of IPC::Shareable to 1.11 due to bug fix where child shared
memory segments created under one process weren't being registered if the
parent was created in a different process
1.09 2022-03-05
- Bump prereq IPC::Shareable to 1.08 due to a fix in creating random SHM
keys in forked environments, major improvements of its _shm_key_rand()
function, and its ability to set a 'protected' option so our global shared
%events hash doesn't get cleaned up automatically
- Modified examples/shared.pl so it doesn't leak segments and semaphores
after completion
- We now remove %events hash in END instead of DESTROY. This way we can have
objects go out of scope in a script without blowing away the global shared
data
- Added _end() so that we can test the END block in unit tests. END{} calls
( run in 1.270 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )