Amazon-SQS-Client
view release on metacpan or search on metacpan
bin/QueueDaemon.pl view on Meta::CPAN
########################################################################
package main;
########################################################################
use Class::Inspector;
use Class::Unload;
use Cwd;
use Data::Dumper;
use English qw(-no_match_vars);
use File::Basename qw(fileparse);
use Getopt::Long qw(:config no_ignore_case);
use List::Util qw(max min);
use Log::Log4perl;
use Log::Log4perl::Level;
use Pod::Usage;
use Proc::Daemon;
use Proc::PID::File;
use Module::Load qw(autoload);
use Amazon::SQS::Config;
use Amazon::SQS::Client;
use Readonly;
Readonly::Scalar our $TRUE => 1;
Readonly::Scalar our $FALSE => 0;
Readonly::Scalar our $DEFAULT_SLEEP_TIME => 5;
Readonly::Scalar our $MAX_SLEEP_TIME => 60;
Readonly::Scalar our $APPENDER_NAME => 'LOGFILE';
Readonly::Scalar our $LOGFILE_CONFIG => <<'END_OF_LOGGER';
log4perl.rootLogger=INFO, LOGFILE
log4perl.appender.LOGFILE=Log::Log4perl::Appender::File
log4perl.appender.LOGFILE.filename=%s
log4perl.appender.LOGFILE.mode=append
log4perl.appender.LOGFILE.layout=PatternLayout
log4perl.appender.LOGFILE.layout.ConversionPattern=%%d (%%r,%%R) (%%p/%%c) [%%P] [%%M:%%L] - %%m%%n
END_OF_LOGGER
Readonly::Scalar our $SCREEN_CONFIG => <<'END_OF_LOGGER';
log4perl.rootLogger=INFO, SCREEN
log4perl.appender.SCREEN=Log::Log4perl::Appender::Screen
log4perl.appender.SCREEN.stderr=%s
log4perl.appender.SCREEN.layout=PatternLayout
log4perl.appender.SCREEN.layout.ConversionPattern=%%d (%%r,%%R) (%%p/%%c) [%%P] [%%M:%%L] - %%m%%n
END_OF_LOGGER
our $KEEP_GOING = $TRUE;
our $RELOAD = $FALSE;
########################################################################
sub get_options {
########################################################################
my @option_specs = qw(
config|c=s
create-queue|C
daemonize|d!
delete-when|D=s
exit-when|E=s
endpoint_url|e=s
help|h
logfile|L=s
loglevel|l=s
max-children|m=i
max-sleep-time=i
max-messages=i
pidfile|p=s
queue|q=s
queue-interval|I=i
handler|H=s
message-type|M=s
visibility-timeout|v=i
wait-time|w=i
);
# default options
my %options = (
daemonize => $TRUE,
'exit-when' => 'never',
'delete-when' => 'true', # delete message if handled successfully
handler => 'Amazon::SQS::QueueHandler',
);
my $retval = GetOptions( \%options, @option_specs );
if ( !$retval || $options{help} ) {
pod2usage(1);
}
die "set 'wait-time' or 'queue-interval' but not both\n"
if $options{'wait-time'} && $options{'queue-interval'};
return %options;
}
########################################################################
sub main {
########################################################################
my %options = get_options();
die sprintf "no such file %s\n", $options{config}
if $options{config} && ( !-e $options{config} || !-r $options{config} );
my $config = load_config( \%options );
if ( !defined $options{'wait-time'} && !defined $options{'queue-interval'} ) {
$options{'queue-interval'} = $DEFAULT_SLEEP_TIME;
}
if ( $options{'queue-interval'} && !defined $options{'max-sleep-time'} ) {
$options{'max-sleep-time'} = $MAX_SLEEP_TIME;
}
my $logger = init_logger( \%options );
$logger->trace(
Dumper(
[ config => $config,
options => \%options
bin/QueueDaemon.pl view on Meta::CPAN
return;
}
########################################################################
sub load_config {
########################################################################
my ($options) = @_;
return
if !$options->{config};
my $config = Amazon::SQS::Config->new( file => $options->{config} );
$options->{loglevel} //= $config->get_log_level;
$options->{logfile} //= $config->get_log_file;
$options->{logfile} //= 'stderr';
$options->{'delete-when'} //= $config->get_error_delete;
$options->{'exit-when'} //= $config->get_error_exit;
$options->{handler} //= $config->get_handler_class;
$options->{'max-sleep-time'} //= $config->get_queue_max_wait;
$options->{'max-messages'} //= $config->get_queue_max_messages // 1;
$options->{queue} //= $config->get_queue_name;
$options->{'queue-url'} //= $config->get_queue_url;
$options->{'queue-interval'} //= $config->get_queue_interval;
$options->{'create-queue'} //= $config->get_queue_create_queue // $FALSE;
$options->{'visibility-timeout'} //= $config->get_queue_visibility_timeout;
$options->{'wait-time'} //= $config->get_queue_wait_time;
return $config;
}
########################################################################
sub load_handler {
########################################################################
my %args = @_;
my ( $config, $options, $logger, $credentials ) = @args{qw(config options logger credentials)};
if ( Class::Inspector->loaded( $options->{handler} ) ) {
Class::Unload->unload( $options->{handler} );
}
autoload $options->{handler};
my $handler = $options->{handler}->new(
config => $config,
logger => $logger,
endpoint_url => $options->{endpoint_url},
name => $options->{queue},
url => $options->{'queue-url'},
message_type => $options->{'message-type'},
create_queue => $options->{'create-queue'},
wait_time => $options->{'wait-time'},
visibility_timeout => $options->{'visibility-timeout'},
credentials => $credentials,
);
die "not an Amazon::SQS::QueueHandler\n"
if !$handler->isa('Amazon::SQS::QueueHandler');
return $handler;
}
########################################################################
sub sleep_time {
########################################################################
my ( $sleep, $options ) = @_;
$sleep //= 0;
return $sleep + $options->{'queue-interval'};
}
exit main();
1;
__END__
=pod
=head1 NAME
QueueDaemon.pl - wrapper for queue handler daemons
=head1 SYNOPSIS
QueueDaemon.pl options
Read and process SQS messages.
=head1 DESCRIPTION
Implements a daemon that reads from Amazon's Simple Queue Service
(SQS).
=head1 OPTIONS
-h, --help help
-c, --config config file name
-C, --create-queue create the queue if it does not exist
-d, --daemonize daemonize the script (default)
--no-daemonize
-D, --delete-when never, always, error
-E, --exit-when never, always, error, false
-e, --endpoint-url default: https://sqs.amazonaws.com
-L, --logfile name of logfile
-l, --loglevel log level (trace, debug, info, warn, error)
-H, --handler name of the handler class, default: Amazon::SQS::QueueHandler
-m, --max-children not implemented (default: 1)
-s, --max-sleep-time default: 5 seconds
--max-messages fixed at 1 currently
-M, --message-type mime type of messages (text/plain, application/json,
application/x-www-form-encoded), default: text/plain
-q, --queue queue name (not url)
--queue-interval amount of time to sleep
-p, --pidfile fully qualified path of pid file, default: /var/run/QueueDaemon.pl.in
-v, --visibility-timeout visibility timeout in seconds, default: 30
-w, --wait-time long polling wait time in seconds, default: 0
=head2 LICENSE
(c) Copyright 2024 TBC Development Group, LLC. All rights reserved.
This is free software and may be used or distributed under the same terms as Perl itself.
=head1 FEATURES
=over 5
=item * easy configuration using the command line options or a configuration file
=item * automatically create a queue if it doesn't exist
=item * long or short polling. Set --wait-time for long polling, --queue-interval for short polling
=item * configurable message disposition options for successful handling of messages and exceptions
=item * can be run as a daemon or in a terminal
=back
=head1 HINTS & TIPS
=head2 Quick Start
QueueDaemon.pl --create-queue -q fooManQueue
=over 5
=item 1. If the queue does not exist it will be created if you use the --create-queue option.
=item 2. If no logfile is given, log output will be sent to STDERR
=item 3. See L<Amazon::SQS::Config> regarding the available options in a config file.
=item 4. The default is to daemonize the script. Use --no-daemonize to run in a terminal.
=item 5. If you do not provide a handler on the command line or in
your .ini file the default handler will be used. The default hanlder will dump the
message to the log and delete the message.
=item 6. By default messages will only be deleted from the queue if your
handler returns a true value. If you want to delete messages which cannot be
decoded or when you handler returns a non-true value, set the
--delete-when or set 'delete' option in the [error] section of your .ini file.
( run in 0.896 second using v1.01-cache-2.11-cpan-39bf76dae61 )