prefab-cloud-ruby 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.envrc.sample +3 -0
 - data/.github/workflows/ruby.yml +4 -0
 - data/.gitmodules +3 -0
 - data/Gemfile +12 -12
 - data/Gemfile.lock +16 -14
 - data/README.md +1 -1
 - data/Rakefile +13 -14
 - data/VERSION +1 -1
 - data/lib/prefab/auth_interceptor.rb +2 -1
 - data/lib/prefab/cancellable_interceptor.rb +8 -7
 - data/lib/prefab/client.rb +33 -24
 - data/lib/prefab/config_client.rb +55 -66
 - data/lib/prefab/config_loader.rb +7 -114
 - data/lib/prefab/config_resolver.rb +27 -57
 - data/lib/prefab/config_value_unwrapper.rb +23 -0
 - data/lib/prefab/criteria_evaluator.rb +96 -0
 - data/lib/prefab/errors/invalid_api_key_error.rb +1 -1
 - data/lib/prefab/feature_flag_client.rb +13 -145
 - data/lib/prefab/internal_logger.rb +6 -5
 - data/lib/prefab/local_config_parser.rb +110 -0
 - data/lib/prefab/logger_client.rb +26 -31
 - data/lib/prefab/murmer3.rb +3 -4
 - data/lib/prefab/noop_cache.rb +5 -7
 - data/lib/prefab/noop_stats.rb +2 -3
 - data/lib/prefab/options.rb +11 -9
 - data/lib/prefab/ratelimit_client.rb +11 -13
 - data/lib/prefab/sse_logger.rb +3 -2
 - data/lib/prefab/weighted_value_resolver.rb +42 -0
 - data/lib/prefab/yaml_config_parser.rb +32 -0
 - data/lib/prefab-cloud-ruby.rb +7 -2
 - data/lib/prefab_pb.rb +49 -43
 - data/lib/prefab_services_pb.rb +0 -1
 - data/prefab-cloud-ruby.gemspec +28 -19
 - data/test/.prefab.unit_tests.config.yaml +3 -2
 - data/test/integration_test.rb +98 -0
 - data/test/integration_test_helpers.rb +37 -0
 - data/test/test_client.rb +32 -31
 - data/test/test_config_client.rb +21 -20
 - data/test/test_config_loader.rb +48 -37
 - data/test/test_config_resolver.rb +312 -135
 - data/test/test_config_value_unwrapper.rb +83 -0
 - data/test/test_criteria_evaluator.rb +533 -0
 - data/test/test_feature_flag_client.rb +35 -347
 - data/test/test_helper.rb +18 -14
 - data/test/test_integration.rb +33 -0
 - data/test/test_local_config_parser.rb +78 -0
 - data/test/test_logger.rb +47 -46
 - data/test/test_weighted_value_resolver.rb +65 -0
 - metadata +24 -27
 - data/lib/prefab/config_helper.rb +0 -31
 - data/run_test_harness_server.sh +0 -8
 - data/test/harness_server.rb +0 -64
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: a34b06515d401b7e73fd8b6adf77294187d94ea3a1d1909d159ebfd63b4046ad
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6ba449742b1a75517b35a47151452dbdf94c0a8aef0e58a639ae5b2481262d43
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 0a32e0ac965c54d634c579de66927d2982cca26d7098daaf3cdfd2dda88bf04bd33265c1e9f85e303d75fc9360f6df202cee256e59a91012b94f0adcf29252aa
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 2c37b2cfeef43f44d2dcbe8835ff8ea130393ad98dd9dd61328371972bf1818ab12d932f6bec319a52ec2423f9204762c6305ab3643023a3aa5ea4bfd18974bf
         
     | 
    
        data/.envrc.sample
    ADDED
    
    
    
        data/.github/workflows/ruby.yml
    CHANGED
    
    | 
         @@ -26,6 +26,8 @@ jobs: 
     | 
|
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                steps:
         
     | 
| 
       28 
28 
     | 
    
         
             
                - uses: actions/checkout@v3
         
     | 
| 
      
 29 
     | 
    
         
            +
                  with:
         
     | 
| 
      
 30 
     | 
    
         
            +
                    submodules: recursive
         
     | 
| 
       29 
31 
     | 
    
         
             
                - name: Set up Ruby
         
     | 
| 
       30 
32 
     | 
    
         
             
                # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
         
     | 
| 
       31 
33 
     | 
    
         
             
                # change this to (see https://github.com/ruby/setup-ruby#versioning):
         
     | 
| 
         @@ -37,3 +39,5 @@ jobs: 
     | 
|
| 
       37 
39 
     | 
    
         
             
                    bundler-cache: true # runs 'bundle install' and caches installed gems automatically
         
     | 
| 
       38 
40 
     | 
    
         
             
                - name: Run tests
         
     | 
| 
       39 
41 
     | 
    
         
             
                  run: bundle exec rake
         
     | 
| 
      
 42 
     | 
    
         
            +
                  env:
         
     | 
| 
      
 43 
     | 
    
         
            +
                    PREFAB_INTEGRATION_TEST_API_KEY: ${{ secrets.PREFAB_INTEGRATION_TEST_API_KEY }}
         
     | 
    
        data/.gitmodules
    ADDED
    
    
    
        data/Gemfile
    CHANGED
    
    | 
         @@ -1,23 +1,23 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            source  
     | 
| 
      
 1 
     | 
    
         
            +
            source 'https://rubygems.org'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            gem 'concurrent-ruby', '~> 1.0', '>= 1.0.5'
         
     | 
| 
       4 
4 
     | 
    
         
             
            gem 'faraday'
         
     | 
| 
      
 5 
     | 
    
         
            +
            gem 'googleapis-common-protos-types', platforms: :ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            gem 'google-protobuf', platforms: :ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            gem 'grpc', platforms: :ruby
         
     | 
| 
       5 
8 
     | 
    
         
             
            gem 'ld-eventsource'
         
     | 
| 
       6 
     | 
    
         
            -
            gem 'grpc', :platforms => :ruby
         
     | 
| 
       7 
     | 
    
         
            -
            gem 'google-protobuf', :platforms => :ruby
         
     | 
| 
       8 
     | 
    
         
            -
            gem 'googleapis-common-protos-types', :platforms => :ruby
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            group :development do
         
     | 
| 
       11 
11 
     | 
    
         
             
              gem 'benchmark-ips'
         
     | 
| 
       12 
     | 
    
         
            -
              gem ' 
     | 
| 
       13 
     | 
    
         
            -
              gem  
     | 
| 
       14 
     | 
    
         
            -
              gem  
     | 
| 
       15 
     | 
    
         
            -
              gem  
     | 
| 
       16 
     | 
    
         
            -
              gem  
     | 
| 
       17 
     | 
    
         
            -
              gem 'thin'
         
     | 
| 
      
 12 
     | 
    
         
            +
              gem 'bundler'
         
     | 
| 
      
 13 
     | 
    
         
            +
              gem 'grpc-tools', platforms: :ruby
         
     | 
| 
      
 14 
     | 
    
         
            +
              gem 'juwelier', '~> 2.4.9'
         
     | 
| 
      
 15 
     | 
    
         
            +
              gem 'rdoc'
         
     | 
| 
      
 16 
     | 
    
         
            +
              gem 'simplecov', '>= 0'
         
     | 
| 
       18 
17 
     | 
    
         
             
            end
         
     | 
| 
       19 
18 
     | 
    
         | 
| 
       20 
19 
     | 
    
         
             
            group :test do
         
     | 
| 
       21 
     | 
    
         
            -
              gem  
     | 
| 
       22 
     | 
    
         
            -
              gem  
     | 
| 
      
 20 
     | 
    
         
            +
              gem 'minitest'
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem 'minitest-focus'
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem 'minitest-reporters'
         
     | 
| 
       23 
23 
     | 
    
         
             
            end
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    | 
         @@ -3,16 +3,15 @@ GEM 
     | 
|
| 
       3 
3 
     | 
    
         
             
              specs:
         
     | 
| 
       4 
4 
     | 
    
         
             
                addressable (2.8.0)
         
     | 
| 
       5 
5 
     | 
    
         
             
                  public_suffix (>= 2.0.2, < 5.0)
         
     | 
| 
      
 6 
     | 
    
         
            +
                ansi (1.5.0)
         
     | 
| 
       6 
7 
     | 
    
         
             
                benchmark-ips (2.10.0)
         
     | 
| 
       7 
8 
     | 
    
         
             
                builder (3.2.4)
         
     | 
| 
       8 
9 
     | 
    
         
             
                concurrent-ruby (1.1.10)
         
     | 
| 
       9 
     | 
    
         
            -
                daemons (1.4.1)
         
     | 
| 
       10 
10 
     | 
    
         
             
                descendants_tracker (0.0.4)
         
     | 
| 
       11 
11 
     | 
    
         
             
                  thread_safe (~> 0.3, >= 0.3.1)
         
     | 
| 
       12 
12 
     | 
    
         
             
                docile (1.3.5)
         
     | 
| 
       13 
13 
     | 
    
         
             
                domain_name (0.5.20190701)
         
     | 
| 
       14 
14 
     | 
    
         
             
                  unf (>= 0.0.5, < 1.0.0)
         
     | 
| 
       15 
     | 
    
         
            -
                eventmachine (1.2.7)
         
     | 
| 
       16 
15 
     | 
    
         
             
                faraday (1.3.0)
         
     | 
| 
       17 
16 
     | 
    
         
             
                  faraday-net_http (~> 1.0)
         
     | 
| 
       18 
17 
     | 
    
         
             
                  multipart-post (>= 1.2, < 3)
         
     | 
| 
         @@ -22,7 +21,8 @@ GEM 
     | 
|
| 
       22 
21 
     | 
    
         
             
                ffi-compiler (1.0.1)
         
     | 
| 
       23 
22 
     | 
    
         
             
                  ffi (>= 1.0.0)
         
     | 
| 
       24 
23 
     | 
    
         
             
                  rake
         
     | 
| 
       25 
     | 
    
         
            -
                git (1. 
     | 
| 
      
 24 
     | 
    
         
            +
                git (1.13.0)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  addressable (~> 2.8)
         
     | 
| 
       26 
26 
     | 
    
         
             
                  rchardet (~> 1.8)
         
     | 
| 
       27 
27 
     | 
    
         
             
                github_api (0.19.0)
         
     | 
| 
       28 
28 
     | 
    
         
             
                  addressable (~> 2.4)
         
     | 
| 
         @@ -72,35 +72,37 @@ GEM 
     | 
|
| 
       72 
72 
     | 
    
         
             
                minitest (5.16.2)
         
     | 
| 
       73 
73 
     | 
    
         
             
                minitest-focus (1.3.1)
         
     | 
| 
       74 
74 
     | 
    
         
             
                  minitest (>= 4, < 6)
         
     | 
| 
      
 75 
     | 
    
         
            +
                minitest-reporters (1.5.0)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  ansi
         
     | 
| 
      
 77 
     | 
    
         
            +
                  builder
         
     | 
| 
      
 78 
     | 
    
         
            +
                  minitest (>= 5.0)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  ruby-progressbar
         
     | 
| 
       75 
80 
     | 
    
         
             
                multi_json (1.15.0)
         
     | 
| 
       76 
81 
     | 
    
         
             
                multi_xml (0.6.0)
         
     | 
| 
       77 
82 
     | 
    
         
             
                multipart-post (2.1.1)
         
     | 
| 
       78 
     | 
    
         
            -
                nokogiri (1.13. 
     | 
| 
      
 83 
     | 
    
         
            +
                nokogiri (1.13.10)
         
     | 
| 
       79 
84 
     | 
    
         
             
                  mini_portile2 (~> 2.8.0)
         
     | 
| 
       80 
85 
     | 
    
         
             
                  racc (~> 1.4)
         
     | 
| 
       81 
     | 
    
         
            -
                oauth2 (1.4. 
     | 
| 
       82 
     | 
    
         
            -
                  faraday (>= 0. 
     | 
| 
      
 86 
     | 
    
         
            +
                oauth2 (1.4.11)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  faraday (>= 0.17.3, < 3.0)
         
     | 
| 
       83 
88 
     | 
    
         
             
                  jwt (>= 1.0, < 3.0)
         
     | 
| 
       84 
89 
     | 
    
         
             
                  multi_json (~> 1.3)
         
     | 
| 
       85 
90 
     | 
    
         
             
                  multi_xml (~> 0.5)
         
     | 
| 
       86 
     | 
    
         
            -
                  rack (>= 1.2, <  
     | 
| 
      
 91 
     | 
    
         
            +
                  rack (>= 1.2, < 4)
         
     | 
| 
       87 
92 
     | 
    
         
             
                psych (3.3.1)
         
     | 
| 
       88 
93 
     | 
    
         
             
                public_suffix (4.0.6)
         
     | 
| 
       89 
     | 
    
         
            -
                racc (1.6. 
     | 
| 
       90 
     | 
    
         
            -
                rack ( 
     | 
| 
      
 94 
     | 
    
         
            +
                racc (1.6.1)
         
     | 
| 
      
 95 
     | 
    
         
            +
                rack (3.0.4.1)
         
     | 
| 
       91 
96 
     | 
    
         
             
                rake (13.0.6)
         
     | 
| 
       92 
97 
     | 
    
         
             
                rchardet (1.8.0)
         
     | 
| 
       93 
98 
     | 
    
         
             
                rdoc (6.3.3)
         
     | 
| 
      
 99 
     | 
    
         
            +
                ruby-progressbar (1.11.0)
         
     | 
| 
       94 
100 
     | 
    
         
             
                ruby2_keywords (0.0.4)
         
     | 
| 
       95 
101 
     | 
    
         
             
                semver2 (3.4.2)
         
     | 
| 
       96 
102 
     | 
    
         
             
                simplecov (0.18.5)
         
     | 
| 
       97 
103 
     | 
    
         
             
                  docile (~> 1.1)
         
     | 
| 
       98 
104 
     | 
    
         
             
                  simplecov-html (~> 0.11)
         
     | 
| 
       99 
105 
     | 
    
         
             
                simplecov-html (0.12.3)
         
     | 
| 
       100 
     | 
    
         
            -
                thin (1.8.1)
         
     | 
| 
       101 
     | 
    
         
            -
                  daemons (~> 1.0, >= 1.0.9)
         
     | 
| 
       102 
     | 
    
         
            -
                  eventmachine (~> 1.0, >= 1.0.4)
         
     | 
| 
       103 
     | 
    
         
            -
                  rack (>= 1, < 3)
         
     | 
| 
       104 
106 
     | 
    
         
             
                thread_safe (0.3.6)
         
     | 
| 
       105 
107 
     | 
    
         
             
                unf (0.1.4)
         
     | 
| 
       106 
108 
     | 
    
         
             
                  unf_ext
         
     | 
| 
         @@ -122,9 +124,9 @@ DEPENDENCIES 
     | 
|
| 
       122 
124 
     | 
    
         
             
              ld-eventsource
         
     | 
| 
       123 
125 
     | 
    
         
             
              minitest
         
     | 
| 
       124 
126 
     | 
    
         
             
              minitest-focus
         
     | 
| 
      
 127 
     | 
    
         
            +
              minitest-reporters
         
     | 
| 
       125 
128 
     | 
    
         
             
              rdoc
         
     | 
| 
       126 
129 
     | 
    
         
             
              simplecov
         
     | 
| 
       127 
     | 
    
         
            -
              thin
         
     | 
| 
       128 
130 
     | 
    
         | 
| 
       129 
131 
     | 
    
         
             
            BUNDLED WITH
         
     | 
| 
       130 
132 
     | 
    
         
             
               2.3.5
         
     | 
    
        data/README.md
    CHANGED
    
    
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,4 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # encoding: utf-8
         
     | 
| 
       2 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       3 
2 
     | 
    
         | 
| 
       4 
3 
     | 
    
         
             
            require 'rubygems'
         
     | 
| 
         @@ -6,21 +5,21 @@ require 'bundler' 
     | 
|
| 
       6 
5 
     | 
    
         
             
            begin
         
     | 
| 
       7 
6 
     | 
    
         
             
              Bundler.setup(:default, :development)
         
     | 
| 
       8 
7 
     | 
    
         
             
            rescue Bundler::BundlerError => e
         
     | 
| 
       9 
     | 
    
         
            -
               
     | 
| 
       10 
     | 
    
         
            -
               
     | 
| 
      
 8 
     | 
    
         
            +
              warn e.message
         
     | 
| 
      
 9 
     | 
    
         
            +
              warn 'Run `bundle install` to install missing gems'
         
     | 
| 
       11 
10 
     | 
    
         
             
              exit e.status_code
         
     | 
| 
       12 
11 
     | 
    
         
             
            end
         
     | 
| 
       13 
12 
     | 
    
         
             
            require 'rake'
         
     | 
| 
       14 
13 
     | 
    
         
             
            require 'juwelier'
         
     | 
| 
       15 
14 
     | 
    
         
             
            Juwelier::Tasks.new do |gem|
         
     | 
| 
       16 
15 
     | 
    
         
             
              # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
         
     | 
| 
       17 
     | 
    
         
            -
              gem.name =  
     | 
| 
       18 
     | 
    
         
            -
              gem.homepage =  
     | 
| 
       19 
     | 
    
         
            -
              gem.license =  
     | 
| 
       20 
     | 
    
         
            -
              gem.summary = % 
     | 
| 
       21 
     | 
    
         
            -
              gem.description = % 
     | 
| 
       22 
     | 
    
         
            -
              gem.email =  
     | 
| 
       23 
     | 
    
         
            -
              gem.authors = [ 
     | 
| 
      
 16 
     | 
    
         
            +
              gem.name = 'prefab-cloud-ruby'
         
     | 
| 
      
 17 
     | 
    
         
            +
              gem.homepage = 'http://github.com/prefab-cloud/prefab-cloud-ruby'
         
     | 
| 
      
 18 
     | 
    
         
            +
              gem.license = 'MIT'
         
     | 
| 
      
 19 
     | 
    
         
            +
              gem.summary = %(Prefab Ruby Infrastructure)
         
     | 
| 
      
 20 
     | 
    
         
            +
              gem.description = %(RateLimits & Config as a service)
         
     | 
| 
      
 21 
     | 
    
         
            +
              gem.email = 'jdwyer@prefab.cloud'
         
     | 
| 
      
 22 
     | 
    
         
            +
              gem.authors = ['Jeff Dwyer']
         
     | 
| 
       24 
23 
     | 
    
         | 
| 
       25 
24 
     | 
    
         
             
              # dependencies defined in Gemfile
         
     | 
| 
       26 
25 
     | 
    
         
             
            end
         
     | 
| 
         @@ -32,17 +31,17 @@ Rake::TestTask.new(:test) do |test| 
     | 
|
| 
       32 
31 
     | 
    
         
             
              test.verbose = true
         
     | 
| 
       33 
32 
     | 
    
         
             
            end
         
     | 
| 
       34 
33 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            desc  
     | 
| 
      
 34 
     | 
    
         
            +
            desc 'Code coverage detail'
         
     | 
| 
       36 
35 
     | 
    
         
             
            task :simplecov do
         
     | 
| 
       37 
     | 
    
         
            -
              ENV['COVERAGE'] =  
     | 
| 
      
 36 
     | 
    
         
            +
              ENV['COVERAGE'] = 'true'
         
     | 
| 
       38 
37 
     | 
    
         
             
              Rake::Task['test'].execute
         
     | 
| 
       39 
38 
     | 
    
         
             
            end
         
     | 
| 
       40 
39 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
            task : 
     | 
| 
      
 40 
     | 
    
         
            +
            task default: :test
         
     | 
| 
       42 
41 
     | 
    
         | 
| 
       43 
42 
     | 
    
         
             
            require 'rdoc/task'
         
     | 
| 
       44 
43 
     | 
    
         
             
            Rake::RDocTask.new do |rdoc|
         
     | 
| 
       45 
     | 
    
         
            -
              version = File.exist?('VERSION') ? File.read('VERSION') :  
     | 
| 
      
 44 
     | 
    
         
            +
              version = File.exist?('VERSION') ? File.read('VERSION') : ''
         
     | 
| 
       46 
45 
     | 
    
         | 
| 
       47 
46 
     | 
    
         
             
              rdoc.rdoc_dir = 'rdoc'
         
     | 
| 
       48 
47 
     | 
    
         
             
              rdoc.title = "prefab-cloud-ruby #{version}"
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            0. 
     | 
| 
      
 1 
     | 
    
         
            +
            0.21.0
         
     | 
| 
         @@ -1,7 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            module Prefab
         
     | 
| 
       3 
4 
     | 
    
         
             
              class AuthInterceptor < GRPC::ClientInterceptor
         
     | 
| 
       4 
     | 
    
         
            -
                VERSION = File.exist?('VERSION') ? File.read('VERSION').chomp :  
     | 
| 
      
 5 
     | 
    
         
            +
                VERSION = File.exist?('VERSION') ? File.read('VERSION').chomp : ''
         
     | 
| 
       5 
6 
     | 
    
         
             
                CLIENT = "prefab-cloud-ruby.#{VERSION}".freeze
         
     | 
| 
       6 
7 
     | 
    
         | 
| 
       7 
8 
     | 
    
         
             
                def initialize(api_key)
         
     | 
| 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            module Prefab
         
     | 
| 
       3 
4 
     | 
    
         
             
              class CancellableInterceptor < GRPC::ClientInterceptor
         
     | 
| 
       4 
5 
     | 
    
         
             
                WAIT_SEC = 3
         
     | 
| 
         @@ -8,20 +9,20 @@ module Prefab 
     | 
|
| 
       8 
9 
     | 
    
         
             
                end
         
     | 
| 
       9 
10 
     | 
    
         | 
| 
       10 
11 
     | 
    
         
             
                def cancel
         
     | 
| 
       11 
     | 
    
         
            -
                  @call.instance_variable_get( 
     | 
| 
      
 12 
     | 
    
         
            +
                  @call.instance_variable_get('@wrapped').instance_variable_get('@call').cancel
         
     | 
| 
       12 
13 
     | 
    
         
             
                  i = 0
         
     | 
| 
       13 
     | 
    
         
            -
                  while  
     | 
| 
       14 
     | 
    
         
            -
                    if @call.instance_variable_get( 
     | 
| 
       15 
     | 
    
         
            -
                      @base_client.log_internal Logger::DEBUG,  
     | 
| 
      
 14 
     | 
    
         
            +
                  while i < WAIT_SEC
         
     | 
| 
      
 15 
     | 
    
         
            +
                    if @call.instance_variable_get('@wrapped').cancelled?
         
     | 
| 
      
 16 
     | 
    
         
            +
                      @base_client.log_internal Logger::DEBUG, 'Cancelled streaming.'
         
     | 
| 
       16 
17 
     | 
    
         
             
                      return
         
     | 
| 
       17 
18 
     | 
    
         
             
                    else
         
     | 
| 
       18 
     | 
    
         
            -
                      @base_client.log_internal Logger::DEBUG,  
     | 
| 
       19 
     | 
    
         
            -
                      @call.instance_variable_get( 
     | 
| 
      
 19 
     | 
    
         
            +
                      @base_client.log_internal Logger::DEBUG, 'Unable to cancel streaming. Trying again'
         
     | 
| 
      
 20 
     | 
    
         
            +
                      @call.instance_variable_get('@wrapped').instance_variable_get('@call').cancel
         
     | 
| 
       20 
21 
     | 
    
         
             
                      i += 1
         
     | 
| 
       21 
22 
     | 
    
         
             
                      sleep(1)
         
     | 
| 
       22 
23 
     | 
    
         
             
                    end
         
     | 
| 
       23 
24 
     | 
    
         
             
                  end
         
     | 
| 
       24 
     | 
    
         
            -
                  @base_client.log_internal Logger::INFO,  
     | 
| 
      
 25 
     | 
    
         
            +
                  @base_client.log_internal Logger::INFO, 'Unable to cancel streaming.'
         
     | 
| 
       25 
26 
     | 
    
         
             
                end
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
                def request_response(request:, call:, method:, metadata:, &block)
         
     | 
    
        data/lib/prefab/client.rb
    CHANGED
    
    | 
         @@ -1,11 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            module Prefab
         
     | 
| 
       3 
4 
     | 
    
         
             
              class Client
         
     | 
| 
       4 
5 
     | 
    
         
             
                MAX_SLEEP_SEC = 10
         
     | 
| 
       5 
6 
     | 
    
         
             
                BASE_SLEEP_SEC = 0.5
         
     | 
| 
       6 
7 
     | 
    
         
             
                NO_DEFAULT_PROVIDED = :no_default_provided
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                attr_reader :shared_cache 
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :shared_cache
         
     | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :stats
         
     | 
| 
      
 11 
     | 
    
         
            +
                attr_reader :namespace
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_reader :interceptor
         
     | 
| 
      
 13 
     | 
    
         
            +
                attr_reader :api_key
         
     | 
| 
      
 14 
     | 
    
         
            +
                attr_reader :prefab_api_url
         
     | 
| 
      
 15 
     | 
    
         
            +
                attr_reader :options
         
     | 
| 
       9 
16 
     | 
    
         | 
| 
       10 
17 
     | 
    
         
             
                def initialize(options = Prefab::Options.new)
         
     | 
| 
       11 
18 
     | 
    
         
             
                  @options = options
         
     | 
| 
         @@ -15,14 +22,16 @@ module Prefab 
     | 
|
| 
       15 
22 
     | 
    
         
             
                  @stubs = {}
         
     | 
| 
       16 
23 
     | 
    
         | 
| 
       17 
24 
     | 
    
         
             
                  if @options.local_only?
         
     | 
| 
       18 
     | 
    
         
            -
                    log_internal Logger::INFO,  
     | 
| 
      
 25 
     | 
    
         
            +
                    log_internal Logger::INFO, 'Prefab Running in Local Mode'
         
     | 
| 
       19 
26 
     | 
    
         
             
                  else
         
     | 
| 
       20 
27 
     | 
    
         
             
                    @api_key = @options.api_key
         
     | 
| 
       21 
     | 
    
         
            -
                    raise Prefab::Errors::InvalidApiKeyError 
     | 
| 
      
 28 
     | 
    
         
            +
                    raise Prefab::Errors::InvalidApiKeyError, @api_key if @api_key.nil? || @api_key.empty? || api_key.count('-') < 1
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
       22 
30 
     | 
    
         
             
                    @interceptor = Prefab::AuthInterceptor.new(@api_key)
         
     | 
| 
       23 
31 
     | 
    
         
             
                    @prefab_api_url = @options.prefab_api_url
         
     | 
| 
       24 
32 
     | 
    
         
             
                    @prefab_grpc_url = @options.prefab_grpc_url
         
     | 
| 
       25 
     | 
    
         
            -
                    log_internal Logger::INFO, 
     | 
| 
      
 33 
     | 
    
         
            +
                    log_internal Logger::INFO,
         
     | 
| 
      
 34 
     | 
    
         
            +
                                 "Prefab Connecting to: #{@prefab_api_url} and #{@prefab_grpc_url} Secure: #{http_secure?}"
         
     | 
| 
       26 
35 
     | 
    
         
             
                    at_exit do
         
     | 
| 
       27 
36 
     | 
    
         
             
                      channel.destroy
         
     | 
| 
       28 
37 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -63,16 +72,14 @@ module Prefab 
     | 
|
| 
       63 
72 
     | 
    
         | 
| 
       64 
73 
     | 
    
         
             
                  begin
         
     | 
| 
       65 
74 
     | 
    
         
             
                    attempts += 1
         
     | 
| 
       66 
     | 
    
         
            -
                     
     | 
| 
       67 
     | 
    
         
            -
                  rescue =>  
     | 
| 
      
 75 
     | 
    
         
            +
                    stub_for(service, opts[:timeout]).send(method, *params)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  rescue StandardError => e
         
     | 
| 
      
 77 
     | 
    
         
            +
                    log_internal Logger::WARN, e
         
     | 
| 
       68 
78 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
                     
     | 
| 
      
 79 
     | 
    
         
            +
                    raise e if Time.now - start_time > opts[:timeout]
         
     | 
| 
       70 
80 
     | 
    
         | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                    end
         
     | 
| 
       74 
     | 
    
         
            -
                    sleep_seconds = [BASE_SLEEP_SEC * (2 ** (attempts - 1)), MAX_SLEEP_SEC].min
         
     | 
| 
       75 
     | 
    
         
            -
                    sleep_seconds = sleep_seconds * (0.5 * (1 + rand()))
         
     | 
| 
      
 81 
     | 
    
         
            +
                    sleep_seconds = [BASE_SLEEP_SEC * (2**(attempts - 1)), MAX_SLEEP_SEC].min
         
     | 
| 
      
 82 
     | 
    
         
            +
                    sleep_seconds *= (0.5 * (1 + rand))
         
     | 
| 
       76 
83 
     | 
    
         
             
                    sleep_seconds = [BASE_SLEEP_SEC, sleep_seconds].max
         
     | 
| 
       77 
84 
     | 
    
         
             
                    log_internal Logger::INFO, "Sleep #{sleep_seconds} and Reset #{service} #{method}"
         
     | 
| 
       78 
85 
     | 
    
         
             
                    sleep sleep_seconds
         
     | 
| 
         @@ -86,24 +93,28 @@ module Prefab 
     | 
|
| 
       86 
93 
     | 
    
         
             
                  @_channel = nil
         
     | 
| 
       87 
94 
     | 
    
         
             
                end
         
     | 
| 
       88 
95 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                def enabled?(feature_name, lookup_key=nil, attributes={})
         
     | 
| 
      
 96 
     | 
    
         
            +
                def enabled?(feature_name, lookup_key = nil, attributes = {})
         
     | 
| 
       90 
97 
     | 
    
         
             
                  feature_flag_client.feature_is_on_for?(feature_name, lookup_key, attributes: attributes)
         
     | 
| 
       91 
98 
     | 
    
         
             
                end
         
     | 
| 
       92 
99 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
                def get(key, default_or_lookup_key=NO_DEFAULT_PROVIDED,  
     | 
| 
       94 
     | 
    
         
            -
                   
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                  if result.is_a?(Prefab::FeatureFlag)
         
     | 
| 
       97 
     | 
    
         
            -
                    feature_flag_client.get(key, default_or_lookup_key, attributes, default: ff_default)
         
     | 
| 
      
 100 
     | 
    
         
            +
                def get(key, default_or_lookup_key = NO_DEFAULT_PROVIDED, properties = {}, ff_default = nil)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  if is_ff?(key)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    feature_flag_client.get(key, default_or_lookup_key, properties, default: ff_default)
         
     | 
| 
       98 
103 
     | 
    
         
             
                  else
         
     | 
| 
       99 
     | 
    
         
            -
                     
     | 
| 
      
 104 
     | 
    
         
            +
                    config_client.get(key, default_or_lookup_key, properties)
         
     | 
| 
       100 
105 
     | 
    
         
             
                  end
         
     | 
| 
       101 
106 
     | 
    
         
             
                end
         
     | 
| 
       102 
107 
     | 
    
         | 
| 
       103 
108 
     | 
    
         
             
                private
         
     | 
| 
       104 
109 
     | 
    
         | 
| 
      
 110 
     | 
    
         
            +
                def is_ff?(key)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  raw = config_client.send(:raw, key)
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  raw && raw.allowable_values.any?
         
     | 
| 
      
 114 
     | 
    
         
            +
                end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
       105 
116 
     | 
    
         
             
                def http_secure?
         
     | 
| 
       106 
     | 
    
         
            -
                  ENV[ 
     | 
| 
      
 117 
     | 
    
         
            +
                  ENV['PREFAB_CLOUD_HTTP'] != 'true'
         
     | 
| 
       107 
118 
     | 
    
         
             
                end
         
     | 
| 
       108 
119 
     | 
    
         | 
| 
       109 
120 
     | 
    
         
             
                def stub_for(service, timeout)
         
     | 
| 
         @@ -119,7 +130,7 @@ module Prefab 
     | 
|
| 
       119 
130 
     | 
    
         
             
                end
         
     | 
| 
       120 
131 
     | 
    
         | 
| 
       121 
132 
     | 
    
         
             
                def ssl_certs
         
     | 
| 
       122 
     | 
    
         
            -
                  ssl_certs =  
     | 
| 
      
 133 
     | 
    
         
            +
                  ssl_certs = ''
         
     | 
| 
       123 
134 
     | 
    
         
             
                  Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*.pem"].each do |cert|
         
     | 
| 
       124 
135 
     | 
    
         
             
                    ssl_certs += File.open(cert).read
         
     | 
| 
       125 
136 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -127,11 +138,9 @@ module Prefab 
     | 
|
| 
       127 
138 
     | 
    
         
             
                    ssl_certs += File.open(OpenSSL::X509::DEFAULT_CERT_FILE).read
         
     | 
| 
       128 
139 
     | 
    
         
             
                  end
         
     | 
| 
       129 
140 
     | 
    
         
             
                  ssl_certs
         
     | 
| 
       130 
     | 
    
         
            -
                rescue => e
         
     | 
| 
      
 141 
     | 
    
         
            +
                rescue StandardError => e
         
     | 
| 
       131 
142 
     | 
    
         
             
                  log.warn("Issue loading SSL certs #{e.message}")
         
     | 
| 
       132 
143 
     | 
    
         
             
                  ssl_certs
         
     | 
| 
       133 
144 
     | 
    
         
             
                end
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
145 
     | 
    
         
             
              end
         
     | 
| 
       136 
146 
     | 
    
         
             
            end
         
     | 
| 
       137 
     | 
    
         
            -
             
     | 
    
        data/lib/prefab/config_client.rb
    CHANGED
    
    | 
         @@ -1,17 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            module Prefab
         
     | 
| 
       3 
4 
     | 
    
         
             
              class ConfigClient
         
     | 
| 
       4 
     | 
    
         
            -
                include Prefab::ConfigHelper
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
5 
     | 
    
         
             
                RECONNECT_WAIT = 5
         
     | 
| 
       7 
6 
     | 
    
         
             
                DEFAULT_CHECKPOINT_FREQ_SEC = 60
         
     | 
| 
       8 
7 
     | 
    
         
             
                SSE_READ_TIMEOUT = 300
         
     | 
| 
       9 
     | 
    
         
            -
                AUTH_USER =  
     | 
| 
      
 8 
     | 
    
         
            +
                AUTH_USER = 'authuser'
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
       11 
10 
     | 
    
         
             
                def initialize(base_client, timeout)
         
     | 
| 
       12 
11 
     | 
    
         
             
                  @base_client = base_client
         
     | 
| 
       13 
12 
     | 
    
         
             
                  @options = base_client.options
         
     | 
| 
       14 
     | 
    
         
            -
                  @base_client.log_internal Logger::DEBUG,  
     | 
| 
      
 13 
     | 
    
         
            +
                  @base_client.log_internal Logger::DEBUG, 'Initialize ConfigClient'
         
     | 
| 
       15 
14 
     | 
    
         
             
                  @timeout = timeout
         
     | 
| 
       16 
15 
     | 
    
         | 
| 
       17 
16 
     | 
    
         
             
                  @stream_lock = Concurrent::ReadWriteLock.new
         
     | 
| 
         @@ -22,9 +21,9 @@ module Prefab 
     | 
|
| 
       22 
21 
     | 
    
         
             
                  @config_resolver = Prefab::ConfigResolver.new(@base_client, @config_loader)
         
     | 
| 
       23 
22 
     | 
    
         | 
| 
       24 
23 
     | 
    
         
             
                  @initialization_lock = Concurrent::ReadWriteLock.new
         
     | 
| 
       25 
     | 
    
         
            -
                  @base_client.log_internal Logger::DEBUG,  
     | 
| 
      
 24 
     | 
    
         
            +
                  @base_client.log_internal Logger::DEBUG, 'Initialize ConfigClient: AcquireWriteLock'
         
     | 
| 
       26 
25 
     | 
    
         
             
                  @initialization_lock.acquire_write_lock
         
     | 
| 
       27 
     | 
    
         
            -
                  @base_client.log_internal Logger::DEBUG,  
     | 
| 
      
 26 
     | 
    
         
            +
                  @base_client.log_internal Logger::DEBUG, 'Initialize ConfigClient: AcquiredWriteLock'
         
     | 
| 
       28 
27 
     | 
    
         
             
                  @initialized_future = Concurrent::Future.execute { @initialization_lock.acquire_read_lock }
         
     | 
| 
       29 
28 
     | 
    
         | 
| 
       30 
29 
     | 
    
         
             
                  @cancellable_interceptor = Prefab::CancellableInterceptor.new(@base_client)
         
     | 
| 
         @@ -45,14 +44,15 @@ module Prefab 
     | 
|
| 
       45 
44 
     | 
    
         
             
                end
         
     | 
| 
       46 
45 
     | 
    
         | 
| 
       47 
46 
     | 
    
         
             
                def upsert(key, config_value, namespace = nil, previous_key = nil)
         
     | 
| 
       48 
     | 
    
         
            -
                  raise "Key must not contain ':' set namespaces separately" if key.include?  
     | 
| 
       49 
     | 
    
         
            -
                  raise "Namespace must not contain ':'" if namespace&.include?( 
     | 
| 
      
 47 
     | 
    
         
            +
                  raise "Key must not contain ':' set namespaces separately" if key.include? ':'
         
     | 
| 
      
 48 
     | 
    
         
            +
                  raise "Namespace must not contain ':'" if namespace&.include?(':')
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       50 
50 
     | 
    
         
             
                  config_delta = Prefab::ConfigClient.value_to_delta(key, config_value, namespace)
         
     | 
| 
       51 
51 
     | 
    
         
             
                  upsert_req = Prefab::UpsertRequest.new(config_delta: config_delta)
         
     | 
| 
       52 
52 
     | 
    
         
             
                  upsert_req.previous_key = previous_key if previous_key&.present?
         
     | 
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
                  @base_client.request Prefab::ConfigService, :upsert, req_options: { timeout: @timeout }, params: upsert_req
         
     | 
| 
       55 
     | 
    
         
            -
                  @base_client.stats.increment( 
     | 
| 
      
 55 
     | 
    
         
            +
                  @base_client.stats.increment('prefab.config.upsert')
         
     | 
| 
       56 
56 
     | 
    
         
             
                  @config_loader.set(config_delta, :upsert)
         
     | 
| 
       57 
57 
     | 
    
         
             
                  @config_loader.rm(previous_key) if previous_key&.present?
         
     | 
| 
       58 
58 
     | 
    
         
             
                  @config_resolver.update
         
     | 
| 
         @@ -68,46 +68,43 @@ module Prefab 
     | 
|
| 
       68 
68 
     | 
    
         
             
                end
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
       70 
70 
     | 
    
         
             
                def self.value_to_delta(key, config_value, namespace = nil)
         
     | 
| 
       71 
     | 
    
         
            -
                  Prefab::Config.new(key: [namespace, key].compact.join( 
     | 
| 
      
 71 
     | 
    
         
            +
                  Prefab::Config.new(key: [namespace, key].compact.join(':'),
         
     | 
| 
       72 
72 
     | 
    
         
             
                                     rows: [Prefab::ConfigRow.new(value: config_value)])
         
     | 
| 
       73 
73 
     | 
    
         
             
                end
         
     | 
| 
       74 
74 
     | 
    
         | 
| 
       75 
     | 
    
         
            -
                def get(key, default=Prefab::Client::NO_DEFAULT_PROVIDED)
         
     | 
| 
       76 
     | 
    
         
            -
                   
     | 
| 
       77 
     | 
    
         
            -
                   
     | 
| 
       78 
     | 
    
         
            -
                end
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
                def get_config_obj(key)
         
     | 
| 
       81 
     | 
    
         
            -
                  config = _get(key)
         
     | 
| 
       82 
     | 
    
         
            -
                  config ? config[:config] : nil
         
     | 
| 
      
 75 
     | 
    
         
            +
                def get(key, default = Prefab::Client::NO_DEFAULT_PROVIDED, properties = {}, lookup_key = nil)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  value = _get(key, lookup_key, properties)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  value ? Prefab::ConfigValueUnwrapper.unwrap(value, key, properties) : handle_default(key, default)
         
     | 
| 
       83 
78 
     | 
    
         
             
                end
         
     | 
| 
       84 
79 
     | 
    
         | 
| 
       85 
80 
     | 
    
         
             
                private
         
     | 
| 
       86 
81 
     | 
    
         | 
| 
      
 82 
     | 
    
         
            +
                def raw(key)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  @config_resolver.raw(key)
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
       87 
86 
     | 
    
         
             
                def handle_default(key, default)
         
     | 
| 
       88 
     | 
    
         
            -
                  if default != Prefab::Client::NO_DEFAULT_PROVIDED
         
     | 
| 
       89 
     | 
    
         
            -
                    return default
         
     | 
| 
       90 
     | 
    
         
            -
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                  return default if default != Prefab::Client::NO_DEFAULT_PROVIDED
         
     | 
| 
       91 
88 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                  if @options.on_no_default == Prefab::Options::ON_NO_DEFAULT::RAISE
         
     | 
| 
       93 
     | 
    
         
            -
                    raise Prefab::Errors::MissingDefaultError.new(key)
         
     | 
| 
       94 
     | 
    
         
            -
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  raise Prefab::Errors::MissingDefaultError, key if @options.on_no_default == Prefab::Options::ON_NO_DEFAULT::RAISE
         
     | 
| 
       95 
90 
     | 
    
         | 
| 
       96 
91 
     | 
    
         
             
                  nil
         
     | 
| 
       97 
92 
     | 
    
         
             
                end
         
     | 
| 
       98 
93 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                def _get(key)
         
     | 
| 
      
 94 
     | 
    
         
            +
                def _get(key, lookup_key, properties)
         
     | 
| 
       100 
95 
     | 
    
         
             
                  # wait timeout sec for the initalization to be complete
         
     | 
| 
       101 
96 
     | 
    
         
             
                  @initialized_future.value(@options.initialization_timeout_sec)
         
     | 
| 
       102 
97 
     | 
    
         
             
                  if @initialized_future.incomplete?
         
     | 
| 
       103 
     | 
    
         
            -
                     
     | 
| 
       104 
     | 
    
         
            -
                      @base_client.log_internal Logger::WARN, "Couldn't Initialize In #{@options.initialization_timeout_sec}. Key #{key}. Returning what we have"
         
     | 
| 
       105 
     | 
    
         
            -
                      @initialization_lock.release_write_lock
         
     | 
| 
       106 
     | 
    
         
            -
                    else
         
     | 
| 
      
 98 
     | 
    
         
            +
                    unless @options.on_init_failure == Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN
         
     | 
| 
       107 
99 
     | 
    
         
             
                      raise Prefab::Errors::InitializationTimeoutError.new(@options.initialization_timeout_sec, key)
         
     | 
| 
       108 
100 
     | 
    
         
             
                    end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    @base_client.log_internal Logger::WARN,
         
     | 
| 
      
 103 
     | 
    
         
            +
                                              "Couldn't Initialize In #{@options.initialization_timeout_sec}. Key #{key}. Returning what we have"
         
     | 
| 
      
 104 
     | 
    
         
            +
                    @initialization_lock.release_write_lock
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
       109 
106 
     | 
    
         
             
                  end
         
     | 
| 
       110 
     | 
    
         
            -
                  @config_resolver. 
     | 
| 
      
 107 
     | 
    
         
            +
                  @config_resolver.get(key, lookup_key, properties)
         
     | 
| 
       111 
108 
     | 
    
         
             
                end
         
     | 
| 
       112 
109 
     | 
    
         | 
| 
       113 
110 
     | 
    
         
             
                def stub
         
     | 
| 
         @@ -120,19 +117,15 @@ module Prefab 
     | 
|
| 
       120 
117 
     | 
    
         
             
                def load_checkpoint
         
     | 
| 
       121 
118 
     | 
    
         
             
                  success = load_checkpoint_api_cdn
         
     | 
| 
       122 
119 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                  if success
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
                   
     | 
| 
       126 
     | 
    
         
            -
                    @base_client.log_internal Logger::INFO, "LoadCheckpoint: Fallback to GRPC API"
         
     | 
| 
       127 
     | 
    
         
            -
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  return if success
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  @base_client.log_internal Logger::INFO, 'LoadCheckpoint: Fallback to GRPC API'
         
     | 
| 
       128 
123 
     | 
    
         | 
| 
       129 
124 
     | 
    
         
             
                  success = load_checkpoint_from_grpc_api
         
     | 
| 
       130 
125 
     | 
    
         | 
| 
       131 
     | 
    
         
            -
                  if success
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                   
     | 
| 
       134 
     | 
    
         
            -
                    @base_client.log_internal Logger::WARN, "No success loading checkpoints"
         
     | 
| 
       135 
     | 
    
         
            -
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
                  return if success
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  @base_client.log_internal Logger::WARN, 'No success loading checkpoints'
         
     | 
| 
       136 
129 
     | 
    
         
             
                end
         
     | 
| 
       137 
130 
     | 
    
         | 
| 
       138 
131 
     | 
    
         
             
                def load_checkpoint_from_grpc_api
         
     | 
| 
         @@ -142,8 +135,8 @@ module Prefab 
     | 
|
| 
       142 
135 
     | 
    
         
             
                  load_configs(resp, :remote_api_grpc)
         
     | 
| 
       143 
136 
     | 
    
         
             
                  true
         
     | 
| 
       144 
137 
     | 
    
         
             
                rescue GRPC::Unauthenticated
         
     | 
| 
       145 
     | 
    
         
            -
                  @base_client.log_internal Logger::WARN,  
     | 
| 
       146 
     | 
    
         
            -
                rescue => e
         
     | 
| 
      
 138 
     | 
    
         
            +
                  @base_client.log_internal Logger::WARN, 'Unauthenticated'
         
     | 
| 
      
 139 
     | 
    
         
            +
                rescue StandardError => e
         
     | 
| 
       147 
140 
     | 
    
         
             
                  @base_client.log_internal Logger::WARN, "Unexpected grpc_api problem loading checkpoint #{e}"
         
     | 
| 
       148 
141 
     | 
    
         
             
                  false
         
     | 
| 
       149 
142 
     | 
    
         
             
                end
         
     | 
| 
         @@ -172,7 +165,7 @@ module Prefab 
     | 
|
| 
       172 
165 
     | 
    
         
             
                    @base_client.log_internal Logger::INFO, "Checkpoint #{source} failed to load. Response #{resp.status}"
         
     | 
| 
       173 
166 
     | 
    
         
             
                    false
         
     | 
| 
       174 
167 
     | 
    
         
             
                  end
         
     | 
| 
       175 
     | 
    
         
            -
                rescue => e
         
     | 
| 
      
 168 
     | 
    
         
            +
                rescue StandardError => e
         
     | 
| 
       176 
169 
     | 
    
         
             
                  @base_client.log_internal Logger::WARN, "Unexpected #{source} problem loading checkpoint #{e} #{conn}"
         
     | 
| 
       177 
170 
     | 
    
         
             
                  false
         
     | 
| 
       178 
171 
     | 
    
         
             
                end
         
     | 
| 
         @@ -187,42 +180,39 @@ module Prefab 
     | 
|
| 
       187 
180 
     | 
    
         
             
                    @config_loader.set(config, source)
         
     | 
| 
       188 
181 
     | 
    
         
             
                  end
         
     | 
| 
       189 
182 
     | 
    
         
             
                  if @config_loader.highwater_mark > starting_highwater_mark
         
     | 
| 
       190 
     | 
    
         
            -
                    @base_client.log_internal Logger::INFO, 
     | 
| 
      
 183 
     | 
    
         
            +
                    @base_client.log_internal Logger::INFO,
         
     | 
| 
      
 184 
     | 
    
         
            +
                                              "Found new checkpoint with highwater id #{@config_loader.highwater_mark} from #{source} in project #{project_id} environment: #{project_env_id} and namespace: '#{@namespace}'"
         
     | 
| 
       191 
185 
     | 
    
         
             
                  else
         
     | 
| 
       192 
     | 
    
         
            -
                    @base_client.log_internal Logger::DEBUG, 
     | 
| 
      
 186 
     | 
    
         
            +
                    @base_client.log_internal Logger::DEBUG,
         
     | 
| 
      
 187 
     | 
    
         
            +
                                              "Checkpoint with highwater id #{@config_loader.highwater_mark} from #{source}. No changes.", 'load_configs'
         
     | 
| 
       193 
188 
     | 
    
         
             
                  end
         
     | 
| 
       194 
     | 
    
         
            -
                  @base_client.stats.increment( 
     | 
| 
      
 189 
     | 
    
         
            +
                  @base_client.stats.increment('prefab.config.checkpoint.load')
         
     | 
| 
       195 
190 
     | 
    
         
             
                  @config_resolver.update
         
     | 
| 
       196 
191 
     | 
    
         
             
                  finish_init!(source)
         
     | 
| 
       197 
192 
     | 
    
         
             
                end
         
     | 
| 
       198 
193 
     | 
    
         | 
| 
       199 
194 
     | 
    
         
             
                # A thread that checks for a checkpoint
         
     | 
| 
       200 
195 
     | 
    
         
             
                def start_checkpointing_thread
         
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
196 
     | 
    
         
             
                  Thread.new do
         
     | 
| 
       203 
197 
     | 
    
         
             
                    loop do
         
     | 
| 
       204 
     | 
    
         
            -
                       
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
             
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
                        end
         
     | 
| 
       212 
     | 
    
         
            -
                      rescue StandardError => exn
         
     | 
| 
       213 
     | 
    
         
            -
                        @base_client.log_internal Logger::INFO, "Issue Checkpointing #{exn.message}"
         
     | 
| 
       214 
     | 
    
         
            -
                      end
         
     | 
| 
      
 198 
     | 
    
         
            +
                      load_checkpoint
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                      started_at = Time.now
         
     | 
| 
      
 201 
     | 
    
         
            +
                      delta = @checkpoint_freq_secs - (Time.now - started_at)
         
     | 
| 
      
 202 
     | 
    
         
            +
                      sleep(delta) if delta > 0
         
     | 
| 
      
 203 
     | 
    
         
            +
                    rescue StandardError => e
         
     | 
| 
      
 204 
     | 
    
         
            +
                      @base_client.log_internal Logger::INFO, "Issue Checkpointing #{e.message}"
         
     | 
| 
       215 
205 
     | 
    
         
             
                    end
         
     | 
| 
       216 
206 
     | 
    
         
             
                  end
         
     | 
| 
       217 
207 
     | 
    
         
             
                end
         
     | 
| 
       218 
208 
     | 
    
         | 
| 
       219 
209 
     | 
    
         
             
                def finish_init!(source)
         
     | 
| 
       220 
     | 
    
         
            -
                   
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
                   
     | 
| 
      
 210 
     | 
    
         
            +
                  return unless @initialization_lock.write_locked?
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                  @base_client.log_internal Logger::INFO, "Unlocked Config via #{source}"
         
     | 
| 
      
 213 
     | 
    
         
            +
                  @initialization_lock.release_write_lock
         
     | 
| 
      
 214 
     | 
    
         
            +
                  @base_client.log.set_config_client(self)
         
     | 
| 
      
 215 
     | 
    
         
            +
                  @base_client.log_internal Logger::INFO, to_s
         
     | 
| 
       226 
216 
     | 
    
         
             
                end
         
     | 
| 
       227 
217 
     | 
    
         | 
| 
       228 
218 
     | 
    
         
             
                def start_sse_streaming_connection_thread(start_at_id)
         
     | 
| 
         @@ -230,7 +220,7 @@ module Prefab 
     | 
|
| 
       230 
220 
     | 
    
         
             
                  auth_string = Base64.strict_encode64(auth)
         
     | 
| 
       231 
221 
     | 
    
         
             
                  headers = {
         
     | 
| 
       232 
222 
     | 
    
         
             
                    "x-prefab-start-at-id": start_at_id,
         
     | 
| 
       233 
     | 
    
         
            -
                    "Authorization": "Basic #{auth_string}" 
     | 
| 
      
 223 
     | 
    
         
            +
                    "Authorization": "Basic #{auth_string}"
         
     | 
| 
       234 
224 
     | 
    
         
             
                  }
         
     | 
| 
       235 
225 
     | 
    
         
             
                  url = "#{@base_client.prefab_api_url}/api/v1/sse/config"
         
     | 
| 
       236 
226 
     | 
    
         
             
                  @base_client.log_internal Logger::INFO, "SSE Streaming Connect to #{url} start_at #{start_at_id}"
         
     | 
| 
         @@ -246,4 +236,3 @@ module Prefab 
     | 
|
| 
       246 
236 
     | 
    
         
             
                end
         
     | 
| 
       247 
237 
     | 
    
         
             
              end
         
     | 
| 
       248 
238 
     | 
    
         
             
            end
         
     | 
| 
       249 
     | 
    
         
            -
             
     |