#! /usr/bin/perl -w # ----------------------------------------------------------------------- # Copyright (c) 2011 Henk P. Penning. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the # distribution. # # THIS SOFTWARE IS PROVIDED BY Henk P. Penning, ``AS # IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Henk P. Penning OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # The views and conclusions contained in the software and documentation are # those of the authors and should not be interpreted as representing official # policies, either expressed or implied, of Henk P. Penning. # ----------------------------------------------------------------------- # "Simplified BSD License" or "FreeBSD License" # http://en.wikipedia.org/wiki/BSD_licenses use strict ; # use Devel::Gladiator qw(walk_arena arena_ref_counts arena_table); use Blib ; use RF ; my @ARGS = @ARGV ; my @CNF_KEYS = Blib::Mods::Conf -> CNF_KEYS ; my $CNF_KEYS = join "\n --", @CNF_KEYS ; my $SYN = '[-v] [-q] [-d] [-t] [-f] [-m] [-daemon tag] [-e e] [-c conf] ' . '[config-options]' ; my $prog = PRG () ; my $Usage = < : start as daemon ; creates directory ; must be alpha-numeric (eg 'run'). -e : init with epoch (1308313869, -10m, -1h etc) -c : use config file config-options : --$CNF_KEYS USAGE sub Usage { die "$_[0]$Usage" ; } sub Error { die "$prog: $_[0]\n" ; } sub Warn { warn "$prog: $_[0]\n" ; } # usage: &GetOptions(ARG,ARG,..) defines $opt_ID as 1 or user spec'ed value # usage: &GetOptions(\%opt,ARG,ARG,..) defines $opt{ID} as 1 or user value # ARG = 'ID' | 'ID=SPC' | 'ID:SPC' for no-arg, required-arg or optional-arg # ID = perl identifier # SPC = i|f|s for integer, fixedpoint real or string argument use Getopt::Long ; Getopt::Long::config('no_ignore_case') ; Getopt::Long::config('no_auto_abbrev') ; my %opt = () ; Usage('') unless GetOptions ( \%opt , ( qw(v q d e=s f m tag=s t c=s daemon=s version syn B=s) , map { "$_=s" ; } @CNF_KEYS ) ) ; Usage("too many arguments (@ARGV)\n") unless @ARGV == 0 ; if ( $opt{daemon} ) { my $opt = $opt{daemon} ; if ( $opt =~ /^-/ ) { Usage "Option daemon requires an argument.\n" ; } elsif ( $opt !~ /^\w+$/ ) { Usage "option 'daemon' ($opt) is not alpha-numeric.\n" ; } } elsif ( $opt{tag} ) { Blib::Mods::Conf -> set_CNF_default ( qw(sleep_main_loop 5m) ) ; } $opt{v} ||= $opt{d} ; Blib -> debug ( 0 ) ; my $R = RF -> make ( -root => $opt{c}, %opt ) ; # or die my $conf = $R -> conf ; $conf -> show if $opt{d} ; if ( $opt{version} ) { printf "%s\n", RF -> version ; exit ; } if ( $opt{syn } ) { printf "%s\n", $SYN ; exit ; } if ( $opt{m} ) { $R -> compare ; exit ; } if ( $opt{t} ) { printf "$prog : no config errors detected in %s\n", $conf -> includes ; if ( $opt{v} ) { printf "$prog : args (%s)\n", join ',', @ARGS ; printf "$prog : using module '%s'\n", LCL_JSON () ; } exit ; } if ( $opt{daemon} ) { my $tag = $opt{daemon} ; $R -> start_daemon ( $tag, @ARGS ) ; exit ; } elsif ( $opt{tag} ) { $R -> be_the_daemon ( $opt{tag} ) ; } LOGf "=== iim start - pid %d - %s mode ===", $$, $R -> mode ; $R -> mk_temps ; $R -> full_sync_repeat ( 1 ) if $opt{f} or not $R -> have_all_Recents ; $R -> link_Recents ; if ( $opt{e} ) { my $epoc = $opt{e} ; LOGf "set EPOCH from opt -e (%s)", $opt{e} ; unless ( $epoc =~ /^\d+(\.\d*)?$/ ) { my ( $res, $err ) = $conf -> _secs4spec ( '-e', $epoc ) ; if ( $err ) { LOGx $err ; $R -> _exit ( 1 ) ; } $epoc = int $res ; } $epoc = time + $epoc if $epoc < 0 ; if ( $epoc < time - 7 * 24 * 60 * 60 ) { LOGx "epoch in '-e' is more than a week ago" ; $R -> _exit ( 1 ) ; } $R -> set_epoch ( $epoc ) ; } else { $R -> init_epoch ; } $R -> status ( 'looping' ) ; $R -> set_next_full or LOGx "no full syncs will be scheduled" ; $R -> log_next_exit ; $R -> scores -> put_scoreboards if $R -> tag or $R -> verbose ; my $todo = [] ; # test by adding a "bogus new event" if ( $opt{B} ) { my $ev = Blib::JSON::rfile::recent::event -> make ( base => $R , path => $opt{B} , type => 'new' , epoch => 10 + $R -> epoc , ival => 'xx' ) ; push @$todo, $ev ; } while ( 1 ) { $R -> check_max_run_time ; if ( ! @$todo and $R -> want_full_now ) { if ( $R -> full_sync ) { $R -> init_epoch ; $R -> set_next_full ; } else { $R -> set_next_full ( 'sleep_init_epoch' ) ; } } else { $R -> scores -> incr_loops ; $R -> get_Recents_repeat ; my $events = $R -> find_new_events ; $R -> epoc ( $events -> [ 0 ] -> epoch ) if @$events ; if ( @$events or @$todo ) { my $work = @$events + @$todo ; $todo = $R -> get_batch ( $events, $todo ) ; my $todos = ( scalar @$todo ? sprintf "\n[ %s\n]", join "\n, " , map { $_ -> path ; } @$todo : '' ) ; LOGf ( "events done %s todo %s%s" , $work - @$todo , scalar @$todo , $todos ) if $R -> verbose or @$todo ; } unless ( @$todo ) { $R -> move_Recents ; $R -> try_reload_conf ( %opt ) if $conf -> hot_config ; } $R -> reopen_log if $R -> want_reopen_now ; print Blib::MEEK_dump if $opt{d} ; # $R -> dmp if $opt{d} ; # my $all = walk_arena(); # foreach my $sv ( @$all ) # { warn "live object: $sv\n"; } # warn arena_table() ; LOGx "*********************************************" if $R -> debug ; $R -> _sleep ( 'sleep_main_loop' ) ; } }