[Bps-public-commit] app-aws-cloudwatch-monitor branch 0.03/update-meta-data-caching-writes created. 61b92ae956223ae5eb6aef66c22dcf17ff3f02a6

BPS Git Server git at git.bestpractical.com
Fri May 20 16:37:47 UTC 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "app-aws-cloudwatch-monitor".

The branch, 0.03/update-meta-data-caching-writes has been created
        at  61b92ae956223ae5eb6aef66c22dcf17ff3f02a6 (commit)

- Log -----------------------------------------------------------------
commit 61b92ae956223ae5eb6aef66c22dcf17ff3f02a6
Author: Blaine Motsinger <blaine at bestpractical.com>
Date:   Fri May 20 11:33:19 2022 -0500

    Add test dep for Test::Warnings

diff --git a/Makefile.PL b/Makefile.PL
index abd072b..0517062 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -29,6 +29,7 @@ WriteMakefile(
         'File::Spec' => 0,
         'Test::Exception' => '0.42',  # recommended by Test2
         'Test::More' => '0.98',  # for subtest()
+        'Test::Warnings',
     },
     PREREQ_PM => {
         'base' => 0,
commit a67d35778bf0d5ed2016dbdacf2f19cf770e739f
Author: Blaine Motsinger <blaine at bestpractical.com>
Date:   Fri May 20 11:22:44 2022 -0500

    Add tests for get_meta_data
    
    These tests verify the logic and return for get_meta_data
    happens when expected:
    
    - don't write cache if meta_data wasn't retrieved from mount
    - get meta_data from mount when cache returns empty
    - write the cache if meta_data was retrieved from mount
    - warn if cache and mount both return no value
    
    The cache read/write and GET requests to AWS are all mocked.
    Integration testing to read/write the cache should happen in tests
    for read_meta_data and write_meta_data.

diff --git a/t/cloudwatchclient-get_meta_data.t b/t/cloudwatchclient-get_meta_data.t
new file mode 100644
index 0000000..64b196b
--- /dev/null
+++ b/t/cloudwatchclient-get_meta_data.t
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+
+use FindBin ();
+use lib "$FindBin::RealBin/../lib", "$FindBin::RealBin/lib";
+use App::AWS::CloudWatch::Monitor::Test;
+use Test::Warnings qw{:no_end_test};
+
+my $class = 'App::AWS::CloudWatch::Monitor::CloudWatchClient';
+use_ok($class);
+
+use constant {
+    DO_NOT_CACHE => 0,
+    USE_CACHE    => 1,
+};
+
+my %meta_data_cache = (
+    '/instance-id' => 'i12345testcache',
+);
+
+my %meta_data_mount = (
+    '/instance-id' => 'i12345testmount',
+);
+
+my $return_empty_cache = 0;
+App::AWS::CloudWatch::Monitor::Test::override(
+    package => 'App::AWS::CloudWatch::Monitor::CloudWatchClient',
+    name    => 'read_meta_data',
+    subref  => sub {
+        my $resource    = shift;
+        my $default_ttl = shift;
+        my $meta_data;
+        unless ($return_empty_cache) {
+            $meta_data = $meta_data_cache{$resource};
+        }
+        return $meta_data;
+    },
+);
+
+my $meta_data_was_written = 0;
+App::AWS::CloudWatch::Monitor::Test::override(
+    package => 'App::AWS::CloudWatch::Monitor::CloudWatchClient',
+    name    => 'write_meta_data',
+    subref  => sub {
+        my $resource   = shift;
+        my $data_value = shift;
+        $meta_data_was_written = 1;
+        return;
+    },
+);
+
+my $return_empty_mount = 0;
+App::AWS::CloudWatch::Monitor::Test::override(
+    package => 'App::AWS::CloudWatch::Monitor::CloudWatchClient',
+    name    => 'get',  # get is imported from LWP::Simple
+    subref  => sub {
+        my $uri = shift;
+        my $resource;
+        if ( $uri =~ /.latest\/meta-data(\/.+)/ ) {
+            $resource = $1;
+        }
+        my $meta_data;
+        unless ($return_empty_mount) {
+            $meta_data = $meta_data_mount{$resource};
+        }
+        return $meta_data;
+    },
+);
+
+note('get meta_data from cache');
+my $instance_id = App::AWS::CloudWatch::Monitor::CloudWatchClient::get_meta_data( '/instance-id', USE_CACHE );
+is( $instance_id, $meta_data_cache{'/instance-id'}, 'instance-id from cache returned expected' );
+is( $meta_data_was_written, 0, 'meta_data was not written' );
+
+note('get meta_data from mount');
+$return_empty_cache = 1;
+note("don't write the cache");
+$instance_id = App::AWS::CloudWatch::Monitor::CloudWatchClient::get_meta_data( '/instance-id', DO_NOT_CACHE );
+is( $instance_id, $meta_data_mount{'/instance-id'}, 'instance-id from mount returned expected' );
+is( $meta_data_was_written, 0, 'meta_data was not written' );
+
+note("write the cache");
+$instance_id = App::AWS::CloudWatch::Monitor::CloudWatchClient::get_meta_data( '/instance-id', USE_CACHE );
+is( $instance_id, $meta_data_mount{'/instance-id'}, 'instance-id from mount returned expected' );
+is( $meta_data_was_written, 1, 'meta_data was written' );
+$meta_data_was_written = 0;
+
+note("return empty from cache and mount");
+$return_empty_mount = 1;
+$instance_id = App::AWS::CloudWatch::Monitor::CloudWatchClient::get_meta_data( '/instance-id', USE_CACHE );
+is( $instance_id, undef, 'instance-id from mount returned empty' );
+is( $meta_data_was_written, 0, 'meta_data was not written' );
+my $warning = Test::Warnings::warning { App::AWS::CloudWatch::Monitor::CloudWatchClient::get_meta_data( '/instance-id', USE_CACHE ) };
+like(
+    $warning,
+    qr/^meta-data resource \/instance-id returned empty/,
+    'warning is generated if cache and mount return no meta-data',
+);
+
+done_testing();
commit a77c977309e66ce3138d24213371eeb43dee2607
Author: Blaine Motsinger <blaine at bestpractical.com>
Date:   Fri May 20 09:46:35 2022 -0500

    Add warning if meta-data resource returns empty

diff --git a/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm b/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
index bdbcaa4..fdfebe7 100644
--- a/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
+++ b/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
@@ -137,6 +137,9 @@ sub get_meta_data {
                 write_meta_data( $resource, $data_value );
             }
         }
+        else {
+            warn "meta-data resource $resource returned empty\n";
+        }
     }
 
     return $meta_data;
commit bf14385889a4699ca0ea58731bd419e548e0aabd
Author: Blaine Motsinger <blaine at bestpractical.com>
Date:   Thu May 19 13:30:35 2022 -0500

    Fix meta-data caching writes
    
    The meta-data cache files are written after every call, regardless
    of the TTL variables.  This presents a couple issues.
    
    First, the age of the cache files never get older than the time of
    the last call, effectively making the TTL time meaningless.  This
    leads to far too many unnecessary writes to the disk since the
    cache files never age.
    
    Second, since the TTL time is not honored, if the special meta-data
    mount is incorrectly returning empty string (an issue at AWS or the
    mount on the instance), the benefit of relying on a cached value is
    lost.
    
    This commit fixes the meta-data cache writes to now only write the
    cache file if a value was retrieved from the special mount, which
    only happens if the TTL is reached or the cache file doesn't exist
    or doesn't contain a value.

diff --git a/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm b/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
index 21c8845..bdbcaa4 100644
--- a/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
+++ b/lib/App/AWS/CloudWatch/Monitor/CloudWatchClient.pm
@@ -124,18 +124,22 @@ sub get_meta_data {
     my $use_cache = shift;
     my $meta_data = read_meta_data( $resource, $meta_data_short_ttl );
 
-    my $base_uri   = 'http://169.254.169.254/latest/meta-data';
-    my $data_value = !$meta_data ? get $base_uri. $resource : $meta_data;
+    # if we didn't get meta data from the cache (it might not exist, or the cache TTL expired),
+    # get the meta data from the meta-data mount.
+    unless ($meta_data) {
+        my $base_uri   = 'http://169.254.169.254/latest/meta-data';
+        my $data_value = get $base_uri . $resource;
 
-    if ( !$data_value ) {
-        return "";
-    }
+        if ($data_value) {
+            $meta_data = $data_value;
 
-    if ($use_cache) {
-        write_meta_data( $resource, $data_value );
+            if ($use_cache) {
+                write_meta_data( $resource, $data_value );
+            }
+        }
     }
 
-    return $data_value;
+    return $meta_data;
 }
 
 =item read_meta_data
-----------------------------------------------------------------------


hooks/post-receive
-- 
app-aws-cloudwatch-monitor


More information about the Bps-public-commit mailing list