Group
Extension

WebService-GrowthBook/lib/WebService/GrowthBook/FeatureRepository.pm

package WebService::GrowthBook::FeatureRepository;
use strict;
use warnings;
no indirect;
use Scalar::Util qw(blessed);
use Object::Pad;
use HTTP::Tiny;
use Log::Any qw($log);
use Digest::MD5 qw(md5_base64);
use Syntax::Keyword::Try;
use JSON::MaybeUTF8 qw(decode_json_utf8);
use WebService::GrowthBook::InMemoryFeatureCache;

our $VERSION = '0.003'; ## VERSION

class WebService::GrowthBook::FeatureRepository {
    field $http :param :writer //= HTTP::Tiny->new();
    field $cache :param //= WebService::GrowthBook::InMemoryFeatureCache->singleton();
    method set_cache($new_cache){
        die "Invalid cache object $new_cache" unless blessed($new_cache) && $new_cache->isa('WebService::GrowthBook::AbstractFeatureCache');
        $cache = $new_cache;
    }

    method clear_cache(){
        $cache->clear();
    }
    method load_features($api_host, $client_key, $ttl = 60) {
        my $key = get_cache_key($api_host, $client_key);
        my $features = $cache->get($key);
        if($features){
            $log->debug("Features loaded from cache");
            return $features;
        }
        $features = $self->_fetch_features($api_host, $client_key);
        if($features){
            $cache->set($key, $features, $ttl);
            $log->debug("Features loaded from GrowthBook API, set in cache");
        }

        return $features;
    }

    method _fetch_features($api_host, $client_key){
        my $decoded = $self->_fetch_and_decode($api_host, $client_key);

        # TODO decrypt here
        if(exists $decoded->{features}){
            return $decoded->{features};
        }
        else {
            $log->warn("GrowthBook API response missing features");
            return
        }
    }

    method _fetch_and_decode($api_host, $client_key){
        try {
            my $r = $self->_get($self->_get_features_url($api_host, $client_key));
            if($r->{status} >= 400){
                $log->warnf("Failed to fetch features, received status code %d", $r->{status});
                return;
            }
            my $decoded = decode_json_utf8($r->{content});
            return $decoded;
        }
        catch ($e){
            $log->warnf("Failed to decode feature JSON from GrowthBook API: %s", $e);
        }
        return;
    }
    method _get($url){
        my $headers = {
            'Content-Type'  => 'application/json',
        };

        return  $http->get($url, {headers => $headers});
    }

    method _get_features_url($api_host, $client_key){
        return "$api_host/api/features/$client_key";
    }
}

sub get_cache_key($api_host, $client_key){
    return md5_base64($api_host . '::' . $client_key);
}
1;


Powered by Groonga
Maintained by Kenichi Ishigaki <ishigaki@cpan.org>. If you find anything, submit it on GitHub.