Cache YAOUSen in memcache during fine generation user/miker/lp-1705728-alternative-cache-in-memcache
authorMike Rylander <mrylander@gmail.com>
Mon, 24 Jul 2017 18:54:41 +0000 (14:54 -0400)
committerMike Rylander <mrylander@gmail.com>
Mon, 24 Jul 2017 18:58:47 +0000 (14:58 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/CircCommon.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm
Open-ILS/src/support-scripts/fine_generator.pl

index 1675712..b6023da 100644 (file)
@@ -5,6 +5,7 @@ use DateTime::Format::ISO8601;
 use OpenILS::Application::AppUtils;
 use OpenSRF::Utils qw/:datetime/;
 use OpenILS::Event;
+use OpenSRF::Utils::Cache;
 use OpenSRF::Utils::Logger qw(:logger);
 use OpenILS::Utils::CStoreEditor q/:funcs/;
 use OpenILS::Const qw/:const/;
@@ -18,6 +19,23 @@ my $parser = DateTime::Format::ISO8601->new;
 # Do not publish methods here.  This code is shared across apps.
 # -----------------------------------------------------------------
 
+# return org setting value, using the value found in $cache if available.
+my $settings_cache;
+sub get_cached_ou_setting {
+    my ($class, $org_id, $setting, $token) = @_;
+    $token //= '';
+    my $key = join('.', 'YAOUS_CACHE', $token, $org_id, $setting);
+
+    $settings_cache ||= OpenSRF::Utils::Cache->new('global');
+    my $value = $settings_cache->get_cache($key);
+    if (!defined($value)) {
+        $value = $U->ou_ancestor_setting_value($org_id, $setting);
+        $settings_cache->put_cache($key => $value);
+    }
+
+    return $value;
+}
+
 
 # -----------------------------------------------------------------
 # Voids (or zeros) overdue fines on the given circ.  if a backdate is 
@@ -219,13 +237,13 @@ sub create_bill {
 }
 
 sub extend_grace_period {
-    my($class, $circ_lib, $due_date, $grace_period, $e, $h) = @_;
+    my($class, $circ_lib, $due_date, $grace_period, $e, $h, $cache_token) = @_;
     if ($grace_period >= 86400) { # Only extend grace periods greater than or equal to a full day
         my $parser = DateTime::Format::ISO8601->new;
         my $due_dt = $parser->parse_datetime( cleanse_ISO8601( $due_date ) );
         my $due = $due_dt->epoch;
 
-        my $grace_extend = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend');
+        my $grace_extend = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend', $cache_token);
         $e = new_editor() if (!$e);
         $h = $e->retrieve_actor_org_unit_hours_of_operation($circ_lib) if (!$h);
         if ($grace_extend and $h) { 
@@ -251,10 +269,10 @@ sub extend_grace_period {
             } else {
                 # Extra nice grace periods
                 # AKA, merge closed dates trailing the grace period into the grace period
-                my $grace_extend_into_closed = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend.into_closed');
+                my $grace_extend_into_closed = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend.into_closed', $cache_token);
                 $due += 86400 if $grace_extend_into_closed;
 
-                my $grace_extend_all = $U->ou_ancestor_setting_value($circ_lib, 'circ.grace.extend.all');
+                my $grace_extend_all = $class->get_cached_ou_setting($circ_lib, 'circ.grace.extend.all', $cache_token);
 
                 if ( $grace_extend_all ) {
                     # Start checking the day after the item was due
@@ -428,6 +446,7 @@ sub seconds_to_interval_hash {
 sub generate_fines {
     my ($class, $args) = @_;
     my $circs = $args->{circs};
+    my $cache_token = $args->{cache_token};
     return unless $circs and @$circs;
     my $e = $args->{editor};
     # if a client connection is passed in, this will be chatty like
@@ -546,7 +565,7 @@ sub generate_fines {
                 $logger->info( "Potential first billing for circ ".$c->id );
                 $last_fine = $due;
 
-                $grace_period = extend_grace_period($class, $c->$circ_lib_method,$c->$due_date_method,$grace_period,undef,$hoo{$c->$circ_lib_method});
+                $grace_period = extend_grace_period($class, $c->$circ_lib_method,$c->$due_date_method,$grace_period,undef,$hoo{$c->$circ_lib_method},$cache_token);
             }
 
             return if ($last_fine > $now);
@@ -568,11 +587,11 @@ sub generate_fines {
             my $recurring_fine = int($c->$recurring_fine_method * 100);
             my $max_fine = int($c->max_fine * 100);
 
-            my $skip_closed_check = $U->ou_ancestor_setting_value(
+            my $skip_closed_check = $class->get_cached_ou_setting(
                 $c->$circ_lib_method, 'circ.fines.charge_when_closed');
             $skip_closed_check = $U->is_true($skip_closed_check);
 
-            my $truncate_to_max_fine = $U->ou_ancestor_setting_value(
+            my $truncate_to_max_fine = $class->get_cached_ou_setting(
                 $c->$circ_lib_method, 'circ.fines.truncate_to_max_fine');
             $truncate_to_max_fine = $U->is_true($truncate_to_max_fine);
 
index c6118f2..15def81 100644 (file)
@@ -998,6 +998,7 @@ sub generate_fines {
     my $self = shift;
     my $client = shift;
     my $circ_id = shift;
+    my $cache_token = shift;
 
     my $circs;
     my $editor = new_editor;
@@ -1017,7 +1018,7 @@ sub generate_fines {
         $circs = [overdue_circs(undef, 1, 1, 1)];
     }
 
-    return OpenILS::Application::Circ::CircCommon->generate_fines({circs => $circs, conn => $client})
+    return OpenILS::Application::Circ::CircCommon->generate_fines({circs => $circs, cache_token => $cache_token, conn => $client})
 }
 __PACKAGE__->register_method(
     api_name        => 'open-ils.storage.action.circulation.overdue.generate_fines',
index 5d0ac8e..72af3d3 100755 (executable)
@@ -6,19 +6,70 @@
 
 use strict; 
 use warnings;
-use OpenSRF::Utils::JSON;
+use Getopt::Long;
 use OpenSRF::System;
 use OpenSRF::Utils::SettingsClient;
 use OpenSRF::MultiSession;
 
-my $config = shift || die "bootstrap config required\n";
-my $lockfile = shift || "/tmp/generate_fines-LOCK";
-my $grace = shift;
+my $help;
+my $osrf_config = '/openils/conf/opensrf_core.xml';
+my $lockfile = '/tmp/generate_fines-LOCK';
+my $parallel = 1; # default to opensrf.xml value
 
-if (defined($grace)) {
-    die "Grace period is now defined in the database. It should not be passed to the fine generator.";
+GetOptions(
+    'help'                  => \$help,
+    'osrf-config=s'         => \$osrf_config,
+    'lockfile=s'            => \$lockfile,
+    'parallel=i'            => \$parallel,
+) || die "\nSee --help for more\n";
+
+
+# Support legacy (pre-get-opt) argument passing with warnings.
+my $legacy_config = shift;
+if ($legacy_config) {
+    warn "Loading opensrf config: $legacy_config.\n".
+        "Use --osrf-config instead to silence this warning\n";
+    $osrf_config = $legacy_config;
 }
+
+my $legacy_lockfile = shift;
+if ($legacy_lockfile) {
+    warn "Loading lockfile: $legacy_lockfile.\n".
+        "Use --lockfile instead to silence this warning\n";
+    $lockfile = $legacy_lockfile;
+}
+
+sub help {
+    print <<HELP;
+
+Batch fine generator
+
+$0 --osrf-config $osrf_config --lockfile $lockfile --parallel 3 
+
+Options
+
+    --osrf-config [/openils/conf/opensrf_core.xml] 
+        OpenSRF config file.
+
+    --lockfile [/tmp/generate_fines-LOCK]
+        Full path to lock file
+
+    --parallel
+        Number of parallel fine generator processes to run.
+        When set, this overrides the value from opensrf.xml
+
+    --verbose
+        Print process counts
+HELP
+
+    exit(0);
+}
+
+help() if $help;
+
+# If a lockfile exists and the PID in the file is in fact running, exit.
+# If the lockfile references a dead PID, just replace it.
+
 if (-e $lockfile) {
         open(F,$lockfile);
         my $pid = <F>;
@@ -34,19 +85,19 @@ if (-e $lockfile) {
         close F;
 }
 
-open(F, ">$lockfile");
+open(F, ">$lockfile") or die "Cannot open $lockfile: $!\n";
 print F $$;
 close F;
 
-OpenSRF::System->bootstrap_client( config_file => $config );
+OpenSRF::System->bootstrap_client( config_file => $osrf_config );
 my $settings = OpenSRF::Utils::SettingsClient->new;
-my $parallel = $settings->config_value( fine_generator => 'parallel' ) || 1; 
+$parallel = $settings->config_value( fine_generator => 'parallel' ) || 1; 
 
 if ($parallel == 1) {
 
     my $r = OpenSRF::AppSession
             ->create( 'open-ils.storage' )
-            ->request( 'open-ils.storage.action.circulation.overdue.generate_fines' );
+            ->request( 'open-ils.storage.action.circulation.overdue.generate_fines', undef, $$ );
 
     while (!$r->complete) { $r->recv };
 
@@ -62,7 +113,7 @@ if ($parallel == 1) {
     my $r = $storage->request('open-ils.storage.action.circulation.overdue.id_list');
     while (my $resp = $r->recv(timeout => 600)) {
         my $circ_id = $resp->content;
-        $multi_generator->request( 'open-ils.storage.action.circulation.overdue.generate_fines', $circ_id );
+        $multi_generator->request( 'open-ils.storage.action.circulation.overdue.generate_fines', $circ_id, $$ );
     }
     $storage->disconnect();
     $multi_generator->session_wait(1);