statsig 1.6.2 → 1.6.3
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/lib/config_result.rb +3 -1
- data/lib/evaluator.rb +30 -5
- data/lib/statsig_driver.rb +9 -2
- data/lib/statsig_event.rb +2 -0
- data/lib/statsig_logger.rb +5 -3
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 9192f1c9886d3a3b18c0a2e70599e998b4784b23245e9064018ec31c98881b25
         | 
| 4 | 
            +
              data.tar.gz: eb329d5f742ce2f77391f3f33ba4229852c2c68827643159b51fd870c1fb21d9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: e8a090dc289fe6994b08578b2d2884f9196f37f4104120c546dd11b3036bc939b84a343a643f15f8e12ca01a494f920206ee01a2302de5bcb71a94efb3048b76
         | 
| 7 | 
            +
              data.tar.gz: 995f91cb599608d0691e8f598d7bc2aa50f0f1b652ad1fac83f3afdb9e950132e21a34aaee44c57797849fb99005cc9dea9d4664f3f4f0ba13afb75dd120c251
         | 
    
        data/lib/config_result.rb
    CHANGED
    
    | @@ -3,11 +3,13 @@ class ConfigResult | |
| 3 3 | 
             
              attr_accessor :gate_value
         | 
| 4 4 | 
             
              attr_accessor :json_value
         | 
| 5 5 | 
             
              attr_accessor :rule_id
         | 
| 6 | 
            +
              attr_accessor :secondary_exposures
         | 
| 6 7 |  | 
| 7 | 
            -
              def initialize(name, gate_value = false, json_value = {}, rule_id = '')
         | 
| 8 | 
            +
              def initialize(name, gate_value = false, json_value = {}, rule_id = '', secondary_exposures = [])
         | 
| 8 9 | 
             
                @name = name
         | 
| 9 10 | 
             
                @gate_value = gate_value
         | 
| 10 11 | 
             
                @json_value = json_value
         | 
| 11 12 | 
             
                @rule_id = rule_id
         | 
| 13 | 
            +
                @secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
         | 
| 12 14 | 
             
              end
         | 
| 13 15 | 
             
            end
         | 
    
        data/lib/evaluator.rb
    CHANGED
    
    | @@ -32,18 +32,21 @@ class Evaluator | |
| 32 32 |  | 
| 33 33 | 
             
              def eval_spec(user, config)
         | 
| 34 34 | 
             
                if config['enabled']
         | 
| 35 | 
            +
                  exposures = []
         | 
| 35 36 | 
             
                  i = 0
         | 
| 36 37 | 
             
                  until i >= config['rules'].length do
         | 
| 37 38 | 
             
                    rule = config['rules'][i]
         | 
| 38 39 | 
             
                    result = self.eval_rule(user, rule)
         | 
| 39 40 | 
             
                    return $fetch_from_server if result == $fetch_from_server
         | 
| 40 | 
            -
                    if result
         | 
| 41 | 
            +
                    exposures = exposures + result["exposures"] if result["exposures"].is_a? Array
         | 
| 42 | 
            +
                    if result['value']
         | 
| 41 43 | 
             
                      pass = self.eval_pass_percent(user, rule, config['salt'])
         | 
| 42 44 | 
             
                      return ConfigResult.new(
         | 
| 43 45 | 
             
                        config['name'],
         | 
| 44 46 | 
             
                        pass,
         | 
| 45 47 | 
             
                        pass ? rule['returnValue'] : config['defaultValue'],
         | 
| 46 48 | 
             
                        rule['id'],
         | 
| 49 | 
            +
                        exposures
         | 
| 47 50 | 
             
                      )
         | 
| 48 51 | 
             
                    end
         | 
| 49 52 |  | 
| @@ -51,17 +54,28 @@ class Evaluator | |
| 51 54 | 
             
                  end
         | 
| 52 55 | 
             
                end
         | 
| 53 56 |  | 
| 54 | 
            -
                ConfigResult.new(config['name'], false, config['defaultValue'], 'default')
         | 
| 57 | 
            +
                ConfigResult.new(config['name'], false, config['defaultValue'], 'default', [])
         | 
| 55 58 | 
             
              end
         | 
| 56 59 |  | 
| 57 60 | 
             
              def eval_rule(user, rule)
         | 
| 61 | 
            +
                exposures = []
         | 
| 62 | 
            +
                pass = true
         | 
| 58 63 | 
             
                i = 0
         | 
| 59 64 | 
             
                until i >= rule['conditions'].length do
         | 
| 60 65 | 
             
                  result = self.eval_condition(user, rule['conditions'][i])
         | 
| 61 | 
            -
                   | 
| 66 | 
            +
                  if result == $fetch_from_server
         | 
| 67 | 
            +
                    return $fetch_from_server
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  if result.is_a?(Hash)
         | 
| 71 | 
            +
                    exposures = exposures + result["exposures"] if result["exposures"].is_a? Array
         | 
| 72 | 
            +
                    pass = false if result["value"] == false
         | 
| 73 | 
            +
                  elsif result == false
         | 
| 74 | 
            +
                    pass = false
         | 
| 75 | 
            +
                  end
         | 
| 62 76 | 
             
                  i += 1
         | 
| 63 77 | 
             
                end
         | 
| 64 | 
            -
                 | 
| 78 | 
            +
                { "value" => pass, "exposures" => exposures }
         | 
| 65 79 | 
             
              end
         | 
| 66 80 |  | 
| 67 81 | 
             
              def eval_condition(user, condition)
         | 
| @@ -82,7 +96,18 @@ class Evaluator | |
| 82 96 | 
             
                when 'fail_gate', 'pass_gate'
         | 
| 83 97 | 
             
                  other_gate_result = self.check_gate(user, target)
         | 
| 84 98 | 
             
                  return $fetch_from_server if other_gate_result == $fetch_from_server
         | 
| 85 | 
            -
             | 
| 99 | 
            +
             | 
| 100 | 
            +
                  gate_value = other_gate_result&.gate_value == true
         | 
| 101 | 
            +
                  new_exposure = {
         | 
| 102 | 
            +
                    "gate" => target,
         | 
| 103 | 
            +
                    "gateValue" => gate_value ? "true" : "false",
         | 
| 104 | 
            +
                    "ruleID" => other_gate_result&.rule_id
         | 
| 105 | 
            +
                  }
         | 
| 106 | 
            +
                  exposures = other_gate_result&.secondary_exposures&.append(new_exposure)
         | 
| 107 | 
            +
                  return {
         | 
| 108 | 
            +
                    "value" => type == 'pass_gate' ? gate_value : !gate_value,
         | 
| 109 | 
            +
                    "exposures" => exposures
         | 
| 110 | 
            +
                  }
         | 
| 86 111 | 
             
                when 'ip_based'
         | 
| 87 112 | 
             
                  value = get_value_from_user(user, field) || get_value_from_ip(user, field)
         | 
| 88 113 | 
             
                  return $fetch_from_server if value == $fetch_from_server
         | 
    
        data/lib/statsig_driver.rb
    CHANGED
    
    | @@ -58,7 +58,7 @@ class StatsigDriver | |
| 58 58 | 
             
                  res = check_gate_fallback(user, gate_name)
         | 
| 59 59 | 
             
                  # exposure logged by the server
         | 
| 60 60 | 
             
                else
         | 
| 61 | 
            -
                  @logger.log_gate_exposure(user, res.name, res.gate_value, res.rule_id)
         | 
| 61 | 
            +
                  @logger.log_gate_exposure(user, res.name, res.gate_value, res.rule_id, res.secondary_exposures)
         | 
| 62 62 | 
             
                end
         | 
| 63 63 |  | 
| 64 64 | 
             
                res.gate_value
         | 
| @@ -84,12 +84,19 @@ class StatsigDriver | |
| 84 84 | 
             
                  res = get_config_fallback(user, dynamic_config_name)
         | 
| 85 85 | 
             
                  # exposure logged by the server
         | 
| 86 86 | 
             
                else
         | 
| 87 | 
            -
                  @logger.log_config_exposure(user, res.name, res.rule_id)
         | 
| 87 | 
            +
                  @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures)
         | 
| 88 88 | 
             
                end
         | 
| 89 89 |  | 
| 90 90 | 
             
                DynamicConfig.new(res.name, res.json_value, res.rule_id)
         | 
| 91 91 | 
             
              end
         | 
| 92 92 |  | 
| 93 | 
            +
              def get_experiment(user, experiment_name)
         | 
| 94 | 
            +
                if !experiment_name.is_a?(String) || experiment_name.empty?
         | 
| 95 | 
            +
                  raise "Invalid experiment_name provided"
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
                get_config(user, experiment_name)
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 93 100 | 
             
              def log_event(user, event_name, value = nil, metadata = nil)
         | 
| 94 101 | 
             
                if !user.nil? && !user.instance_of?(StatsigUser)
         | 
| 95 102 | 
             
                  raise 'Must provide a valid StatsigUser or nil'
         | 
    
        data/lib/statsig_event.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ class StatsigEvent | |
| 2 2 | 
             
              attr_accessor :value
         | 
| 3 3 | 
             
              attr_accessor :metadata
         | 
| 4 4 | 
             
              attr_accessor :statsig_metadata
         | 
| 5 | 
            +
              attr_accessor :secondary_exposures
         | 
| 5 6 | 
             
              attr_reader :user
         | 
| 6 7 |  | 
| 7 8 | 
             
              def initialize(event_name)
         | 
| @@ -23,6 +24,7 @@ class StatsigEvent | |
| 23 24 | 
             
                  'user' => @user,
         | 
| 24 25 | 
             
                  'time' => @time,
         | 
| 25 26 | 
             
                  'statsigMetadata' => @statsig_metadata,
         | 
| 27 | 
            +
                  'secondaryExposures' => @secondary_exposures
         | 
| 26 28 | 
             
                }
         | 
| 27 29 | 
             
              end
         | 
| 28 30 | 
             
            end
         | 
    
        data/lib/statsig_logger.rb
    CHANGED
    
    | @@ -21,7 +21,7 @@ class StatsigLogger | |
| 21 21 | 
             
                end
         | 
| 22 22 | 
             
              end
         | 
| 23 23 |  | 
| 24 | 
            -
              def log_gate_exposure(user, gate_name, value, rule_id)
         | 
| 24 | 
            +
              def log_gate_exposure(user, gate_name, value, rule_id, secondary_exposures)
         | 
| 25 25 | 
             
                event = StatsigEvent.new($gate_exposure_event)
         | 
| 26 26 | 
             
                event.user = user
         | 
| 27 27 | 
             
                event.metadata = {
         | 
| @@ -30,10 +30,11 @@ class StatsigLogger | |
| 30 30 | 
             
                  'ruleID' => rule_id
         | 
| 31 31 | 
             
                }
         | 
| 32 32 | 
             
                event.statsig_metadata = @statsig_metadata
         | 
| 33 | 
            +
                event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
         | 
| 33 34 | 
             
                log_event(event)
         | 
| 34 35 | 
             
              end
         | 
| 35 36 |  | 
| 36 | 
            -
              def log_config_exposure(user, config_name, rule_id)
         | 
| 37 | 
            +
              def log_config_exposure(user, config_name, rule_id, secondary_exposures)
         | 
| 37 38 | 
             
                event = StatsigEvent.new($config_exposure_event)
         | 
| 38 39 | 
             
                event.user = user
         | 
| 39 40 | 
             
                event.metadata = {
         | 
| @@ -41,6 +42,7 @@ class StatsigLogger | |
| 41 42 | 
             
                  'ruleID' => rule_id
         | 
| 42 43 | 
             
                }
         | 
| 43 44 | 
             
                event.statsig_metadata = @statsig_metadata
         | 
| 45 | 
            +
                event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
         | 
| 44 46 | 
             
                log_event(event)
         | 
| 45 47 | 
             
              end
         | 
| 46 48 |  | 
| @@ -51,7 +53,7 @@ class StatsigLogger | |
| 51 53 | 
             
                if @events.length == 0
         | 
| 52 54 | 
             
                  return
         | 
| 53 55 | 
             
                end
         | 
| 54 | 
            -
                flush_events = @events.map { |e| e.serialize | 
| 56 | 
            +
                flush_events = @events.map { |e| e.serialize }
         | 
| 55 57 | 
             
                @events = []
         | 
| 56 58 |  | 
| 57 59 | 
             
                @network.post_logs(flush_events, @statsig_metadata)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: statsig
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.6. | 
| 4 | 
            +
              version: 1.6.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Statsig, Inc
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021-09- | 
| 11 | 
            +
            date: 2021-09-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |