NAME
Try::ALRM - Provides alarm
semantics similar to Try::Catch
.
SYNOPSIS
use Try::ALRM;
timeout 5;
try {
local $|=1; #autoflush for STDOUT
print qq{ doing something that might timeout ...\n};
sleep 6;
}
ALRM {
print qq{ Wake Up!!!!\n};
};
Is equivalent to,
local $SIG{ALRM} = sub { print qq{ Wake Up!!!!\n} };
alarm 5;
local $|=1; #autoflush for STDOUT
print qq{ doing something that might timeout ...\n};
sleep 6;
alarm 0; # reset alarm, end of 'try' block implies this "reset"
DESCRIPTION
Provides try/catch-like semantics for handling code being guarded by alarm
. Because it's localized and potentially expected, ALRM
signals can be treated as exceptions.
alarm
is extremely useful, but it can be cumbersome do add in code. The goal of this module is to make it more idiomatic, and therefore more accessible. It also allows for the ALRM
signal itself to be treated more semantically as an exception. Which makes it a more natural to write and read in Perl. That's the idea, anyway.
Internally, the keywords are implemented as prototypes and uses the same sort of coersion of a lexical bloc to a subroutine reference that is used in Try::Tiny
.
USAGE
Try::ALRM
doesn't really have options, it's more of a structure. So this section is meant to descript that structure and ways to control it.
try
-
This familiar idiom include the block of code that may run longer than one wishes and is need of an
alarm
signal.# default timeout is $Try::ALRM::TIMEOUT try { this_subroutine_call_may_timeout(); };
If just
try
is used here, what happens is functionall equivalent to:alarm 60; # e.g., the default value of $Try::ALRM::TIMEOUT this_subroutine_call_may_timeout(); alarm 0;
And the default handler for
$SIG{ALRM}
is invoked if anALRM
is ssued. ALRM
-
This keyword is for setting
$SIG{ALRM}
with the block that gets passed to it; e.g.:# default timeout is $Try::ALRM::TIMEOUT try { this_subroutine_call_may_timeout(); } ALRM { print qq{ Alarm Clock!!!!\n}; };
The addition of the
ALRM
block above is functionally equivalent to the typical idiom of usingalarm
and setting$SIG{ALRM}
,local $SIG{ALRM} = sub { print qq{ Alarm Clock!!!!\n}; alarm 60; # e.g., the default value of $Try::ALRM::TIMEOUT this_subroutine_call_may_timeout(); alarm 0;
So while this module present
alarm
with try/catch semantics, there are no actualy exceptions getting thrown viadie
; the traditional signal handling mechanism is being invoked as the exception handler.
SETTING TIMEOUT
The timeout value passed to alarm
internally is controlled with the package variable, $Try::ALRM::TIMEOUT
. This module presents 2 different ways to control the value of this variable.
timeout
-
Due to limitations with the way Perl prototypes work for creating syntactical structures, the most idiomatic solution is to use a setter/getter function to update the package variable:
timeout 10; # changes $Try::ALRM::TIMEOUT to 10 try { this_subroutine_call_may_timeout(); } ALRM { print qq{ Alarm Clock!!!!\n}; };
If used without an input value,
timeout
returns the current value of$Try::ALRM::TIMEOUT
. - Trailing value after the
ALRM
block -
try { this_subroutine_call_may_timeout(); } ALRM { print qq{ Alarm Clock!!!!\n}; } 10; # NB: no comma; applies temporarily!
This approach utilizes the effect of defining a Perl prototype,
&
, which coerces a lexical block into a subroutine reference (i.e.,CODE
).The addition of this timeout affects $Try::ALRM::TIMEOUT for the duration of the
try
block, internally is usinglocal
to set$Try::ALRM::TIMEOUT
. The reason for this is so thattimeout
may continue to function properly as a getter inside of thetry
block.
Example
Using the two methods above, the following code demonstrats the usage of timeout
and the effect of the trailing timeout value,
# set timeout (persists)
timeout 5;
printf qq{now %d seconds timeout\n}, timeout;
# try/ALRM
try {
local $|=1;
printf qq{ doing something that might timeout before %d seconds are up ...\n}, timeout;
sleep 6;
}
ALRM {
print qq{Alarm Clock!!\n};
} 1; # <~ trailing timeout
# will still be 5 seconds
printf qq{now %d seconds timeout\n}, timeout;
The output of this block is,
default timeout is 60 seconds
timeout is set globally to 5 seconds
timeout is now set locally to 1 seconds
Alarm Clock!!
timeout is set globally to 5 seconds
Bugs
Very likey.
MMV. If found, please file issue on GH repo.
AUTHOR
oodler577
ACKNOWLEDGEMENTS
"To the least you among of all of us. You make more of a difference than any of you will ever know." -Anonymous
COPYRIGHT AND LICENSE
Copyright (C) 2022 by oodler577
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.30.0 or, at your option, any later version of Perl 5 you may have available.