amplitude-experiment 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b67557de274413377e21002269cd9f493f3a5188707700de19f7dc2f49afc7fd
4
- data.tar.gz: c84dbde1419617bda96c2d9bb59a595b8e6375ac8089a6c8ad5c371bd0133be8
3
+ metadata.gz: ff36301b51f9c519b85c5361aa6e50e45d0e55738ee6d36e10b3599e6b91b98b
4
+ data.tar.gz: 6e03119d4dd2b6f33c4f0ba312043aac2eb688f211cf827a046d90457a40dcdb
5
5
  SHA512:
6
- metadata.gz: fea3bbc7566ccf40c68241a27459264486976dba51b3d83e2fc75507f2e0b64803e9aa15ec9adfcd311c0e49964676556fc582f07d8a7eda1fb6d771001fc9e7
7
- data.tar.gz: dbcbdcad28bf17b029345aabdc67445830256eda6ec0e240856892bec7f34a8cc45c71c6d7ff59d0368a721daa09b29a86885ce91bc3792051952b7bff84c01e
6
+ metadata.gz: cf4ab1ee2bdc9dc1d40c0b95cbb2a6f4559a7473fa64997045bbb7b0bc9ac3a5c05cc5826a3f411198e3807f41e57de9c491cf44bbe2409c02fd368174d425a5
7
+ data.tar.gz: 9fb0b7f55cde6e6e51774b5dc434c8f9ec4707b94a03576636a5bec115c23f4e60d09a93fb855595f41be65b8a9ef0b912c671587df16bbe5587950b267e3a5a
@@ -8,9 +8,7 @@ require 'experiment/factory'
8
8
  require 'experiment/remote/client'
9
9
  require 'experiment/local/client'
10
10
  require 'experiment/local/config'
11
- require 'experiment/local/cache'
12
11
  require 'experiment/local/fetcher'
13
- require 'experiment/local/poller'
14
12
 
15
13
  # Amplitude Experiment Module
16
14
  module AmplitudeExperiment
@@ -12,7 +12,8 @@ module AmplitudeExperiment
12
12
  require 'experiment/local/evaluation/evaluation'
13
13
  @api_key = api_key
14
14
  @config = config || LocalEvaluationConfig.new
15
- @cache = InMemoryFlagConfigCache.new(@config.bootstrap)
15
+ @flags = nil
16
+ @flags_mutex = Mutex.new
16
17
  @logger = Logger.new($stdout)
17
18
  @logger.level = if @config.debug
18
19
  Logger::DEBUG
@@ -20,8 +21,6 @@ module AmplitudeExperiment
20
21
  Logger::INFO
21
22
  end
22
23
  @fetcher = LocalEvaluationFetcher.new(api_key, @config.debug, @config.server_url)
23
- @poller = FlagConfigPoller.new(@fetcher, @cache, @config.debug, @config.flag_config_polling_interval_millis)
24
-
25
24
  raise ArgumentError, 'Experiment API key is empty' if @api_key.nil? || @api_key.empty?
26
25
  end
27
26
 
@@ -32,53 +31,59 @@ module AmplitudeExperiment
32
31
  #
33
32
  # @return [Hash[String, Variant]] The evaluated variants
34
33
  def evaluate(user, flag_keys = [])
35
- flag_configs = []
36
- if flag_keys.empty?
37
- @cache.cache.each do |_, value|
38
- flag_configs.push(value)
39
- end
40
- else
41
- flag_configs = get_flag_configs(flag_keys)
34
+ flags = @flags_mutex.synchronize do
35
+ @flags
42
36
  end
43
- flag_configs_str = flag_configs.to_json
44
- user_str = user.to_json
45
- @logger.debug("[Experiment] Evaluate: User: #{user_str} - Rules: #{flag_configs_str}") if @config.debug
46
- result_json = evaluation(flag_configs_str, user_str)
47
- @logger.debug("[Experiment] evaluate - result: #{variants}") if @config.debug
48
- result = JSON.parse(result_json)
49
- variants = {}
50
- result.each do |key, value|
51
- next if value['isDefaultVariant']
37
+ return {} if flags.nil?
52
38
 
53
- variant_key = value['variant']['key']
54
- variant_payload = value['variant']['payload']
55
- variants.store(key, Variant.new(variant_key, variant_payload))
56
- end
57
- variants
39
+ user_str = user.to_json
40
+ @logger.debug("[Experiment] Evaluate: User: #{user_str} - Rules: #{flags}") if @config.debug
41
+ results_json = evaluation(flags, user_str)
42
+ @logger.debug("[Experiment] evaluate - result: #{results_json}") if @config.debug
43
+ parse_results_json(results_json, flag_keys)
58
44
  end
59
45
 
60
46
  # Fetch initial flag configurations and start polling for updates.
61
47
  # You must call this function to begin polling for flag config updates.
62
48
  def start
63
- @poller.start
49
+ return if @is_running
50
+
51
+ @logger.debug('[Experiment] poller - start') if @debug
52
+ run
64
53
  end
65
54
 
66
55
  # Stop polling for flag configurations. Close resource like connection pool with client
67
56
  def stop
68
- @poller.stop
57
+ @poller_thread&.exit
58
+ @is_running = false
59
+ @poller_thread = nil
69
60
  end
70
61
 
71
62
  private
72
63
 
73
- def get_flag_configs(flag_keys = [])
74
- return @cache.cache if flag_keys.empty?
64
+ def parse_results_json(results_json, flag_keys)
65
+ result = JSON.parse(results_json)
66
+ variants = {}
67
+ result.each do |key, value|
68
+ next if value['isDefaultVariant'] || (flag_keys.empty? && flag_keys.include?(key))
69
+
70
+ variant_key = value['variant']['key']
71
+ variant_payload = value['variant']['payload']
72
+ variants.store(key, Variant.new(variant_key, variant_payload))
73
+ end
74
+ variants
75
+ end
75
76
 
76
- flag_configs = []
77
- flag_keys.each do |key|
78
- flag_config = @cache.get(key)
79
- flag_configs.push(flag_config) if flag_config
77
+ def run
78
+ @is_running = true
79
+ flags = @fetcher.fetch_v1
80
+ @flags_mutex.synchronize do
81
+ @flags = flags
82
+ end
83
+ @poller_thread = Thread.new do
84
+ sleep(@config.flag_config_polling_interval_millis / 1000.to_f)
85
+ run
80
86
  end
81
- flag_configs
82
87
  end
83
88
  end
84
89
  end
@@ -12,11 +12,7 @@ module AmplitudeExperiment
12
12
  # @return [String] the value of server url
13
13
  attr_accessor :server_url
14
14
 
15
- # The server endpoint from which to request variants.
16
- # @return [Hash] the value of bootstrap
17
- attr_accessor :bootstrap
18
-
19
- # The server endpoint from which to request variants.
15
+ # The polling interval for flag configs.
20
16
  # @return [long] the value of flag config polling interval in million seconds
21
17
  attr_accessor :flag_config_polling_interval_millis
22
18
 
@@ -25,14 +25,31 @@ module EvaluationInterop
25
25
  :DisposeString, callback([:string], :void),
26
26
  :IsInstance, callback([:pointer, :string], :pointer),
27
27
  :createNullableByte, callback([:string], :pointer),
28
+ :getNonNullValueOfByte, callback([:pointer], :pointer),
28
29
  :createNullableShort, callback([:pointer], :pointer),
30
+ :getNonNullValueOfShort, callback([:pointer], :pointer),
29
31
  :createNullableInt, callback([:pointer], :pointer),
32
+ :getNonNullValueOfInt, callback([:pointer], :pointer),
30
33
  :createNullableLong, callback([:pointer], :pointer),
34
+ :getNonNullValueOfLong, callback([:pointer], :pointer),
31
35
  :createNullableFloat, callback([:pointer], :pointer),
36
+ :getNonNullValueOfFloat, callback([:pointer], :pointer),
32
37
  :createNullableDouble, callback([:pointer], :pointer),
38
+ :getNonNullValueOfDouble, callback([:pointer], :pointer),
33
39
  :createNullableChar, callback([:pointer], :pointer),
40
+ :getNonNullValueOfChar, callback([:pointer], :pointer),
34
41
  :createNullableBoolean, callback([:pointer], :pointer),
42
+ :getNonNullValueOfBoolean, callback([:pointer], :pointer),
35
43
  :createNullableUnit, callback([], :pointer),
44
+ :createNullableUByte, callback([:pointer], :pointer),
45
+ :getNonNullValueOfUByte, callback([:pointer], :pointer),
46
+ :createNullableUShort, callback([:pointer], :pointer),
47
+ :getNonNullValueOfUShort, callback([:pointer], :pointer),
48
+ :createNullableUInt, callback([:pointer], :pointer),
49
+ :getNonNullValueOfUInt, callback([:pointer], :pointer),
50
+ :createNullableULong, callback([:pointer], :pointer),
51
+ :getNonNullValueOfULong, callback([:pointer], :pointer),
52
+
36
53
  :kotlin, Kotlin
37
54
  end
38
55
 
@@ -51,6 +51,18 @@ typedef struct {
51
51
  typedef struct {
52
52
  libevaluation_interop_KNativePtr pinned;
53
53
  } libevaluation_interop_kref_kotlin_Unit;
54
+ typedef struct {
55
+ libevaluation_interop_KNativePtr pinned;
56
+ } libevaluation_interop_kref_kotlin_UByte;
57
+ typedef struct {
58
+ libevaluation_interop_KNativePtr pinned;
59
+ } libevaluation_interop_kref_kotlin_UShort;
60
+ typedef struct {
61
+ libevaluation_interop_KNativePtr pinned;
62
+ } libevaluation_interop_kref_kotlin_UInt;
63
+ typedef struct {
64
+ libevaluation_interop_KNativePtr pinned;
65
+ } libevaluation_interop_kref_kotlin_ULong;
54
66
 
55
67
 
56
68
  typedef struct {
@@ -59,14 +71,30 @@ typedef struct {
59
71
  void (*DisposeString)(const char* string);
60
72
  libevaluation_interop_KBoolean (*IsInstance)(libevaluation_interop_KNativePtr ref, const libevaluation_interop_KType* type);
61
73
  libevaluation_interop_kref_kotlin_Byte (*createNullableByte)(libevaluation_interop_KByte);
74
+ libevaluation_interop_KByte (*getNonNullValueOfByte)(libevaluation_interop_kref_kotlin_Byte);
62
75
  libevaluation_interop_kref_kotlin_Short (*createNullableShort)(libevaluation_interop_KShort);
76
+ libevaluation_interop_KShort (*getNonNullValueOfShort)(libevaluation_interop_kref_kotlin_Short);
63
77
  libevaluation_interop_kref_kotlin_Int (*createNullableInt)(libevaluation_interop_KInt);
78
+ libevaluation_interop_KInt (*getNonNullValueOfInt)(libevaluation_interop_kref_kotlin_Int);
64
79
  libevaluation_interop_kref_kotlin_Long (*createNullableLong)(libevaluation_interop_KLong);
80
+ libevaluation_interop_KLong (*getNonNullValueOfLong)(libevaluation_interop_kref_kotlin_Long);
65
81
  libevaluation_interop_kref_kotlin_Float (*createNullableFloat)(libevaluation_interop_KFloat);
82
+ libevaluation_interop_KFloat (*getNonNullValueOfFloat)(libevaluation_interop_kref_kotlin_Float);
66
83
  libevaluation_interop_kref_kotlin_Double (*createNullableDouble)(libevaluation_interop_KDouble);
84
+ libevaluation_interop_KDouble (*getNonNullValueOfDouble)(libevaluation_interop_kref_kotlin_Double);
67
85
  libevaluation_interop_kref_kotlin_Char (*createNullableChar)(libevaluation_interop_KChar);
86
+ libevaluation_interop_KChar (*getNonNullValueOfChar)(libevaluation_interop_kref_kotlin_Char);
68
87
  libevaluation_interop_kref_kotlin_Boolean (*createNullableBoolean)(libevaluation_interop_KBoolean);
88
+ libevaluation_interop_KBoolean (*getNonNullValueOfBoolean)(libevaluation_interop_kref_kotlin_Boolean);
69
89
  libevaluation_interop_kref_kotlin_Unit (*createNullableUnit)(void);
90
+ libevaluation_interop_kref_kotlin_UByte (*createNullableUByte)(libevaluation_interop_KUByte);
91
+ libevaluation_interop_KUByte (*getNonNullValueOfUByte)(libevaluation_interop_kref_kotlin_UByte);
92
+ libevaluation_interop_kref_kotlin_UShort (*createNullableUShort)(libevaluation_interop_KUShort);
93
+ libevaluation_interop_KUShort (*getNonNullValueOfUShort)(libevaluation_interop_kref_kotlin_UShort);
94
+ libevaluation_interop_kref_kotlin_UInt (*createNullableUInt)(libevaluation_interop_KUInt);
95
+ libevaluation_interop_KUInt (*getNonNullValueOfUInt)(libevaluation_interop_kref_kotlin_UInt);
96
+ libevaluation_interop_kref_kotlin_ULong (*createNullableULong)(libevaluation_interop_KULong);
97
+ libevaluation_interop_KULong (*getNonNullValueOfULong)(libevaluation_interop_kref_kotlin_ULong);
70
98
 
71
99
  /* User functions. */
72
100
  struct {
@@ -51,6 +51,18 @@ typedef struct {
51
51
  typedef struct {
52
52
  libevaluation_interop_KNativePtr pinned;
53
53
  } libevaluation_interop_kref_kotlin_Unit;
54
+ typedef struct {
55
+ libevaluation_interop_KNativePtr pinned;
56
+ } libevaluation_interop_kref_kotlin_UByte;
57
+ typedef struct {
58
+ libevaluation_interop_KNativePtr pinned;
59
+ } libevaluation_interop_kref_kotlin_UShort;
60
+ typedef struct {
61
+ libevaluation_interop_KNativePtr pinned;
62
+ } libevaluation_interop_kref_kotlin_UInt;
63
+ typedef struct {
64
+ libevaluation_interop_KNativePtr pinned;
65
+ } libevaluation_interop_kref_kotlin_ULong;
54
66
 
55
67
 
56
68
  typedef struct {
@@ -59,14 +71,30 @@ typedef struct {
59
71
  void (*DisposeString)(const char* string);
60
72
  libevaluation_interop_KBoolean (*IsInstance)(libevaluation_interop_KNativePtr ref, const libevaluation_interop_KType* type);
61
73
  libevaluation_interop_kref_kotlin_Byte (*createNullableByte)(libevaluation_interop_KByte);
74
+ libevaluation_interop_KByte (*getNonNullValueOfByte)(libevaluation_interop_kref_kotlin_Byte);
62
75
  libevaluation_interop_kref_kotlin_Short (*createNullableShort)(libevaluation_interop_KShort);
76
+ libevaluation_interop_KShort (*getNonNullValueOfShort)(libevaluation_interop_kref_kotlin_Short);
63
77
  libevaluation_interop_kref_kotlin_Int (*createNullableInt)(libevaluation_interop_KInt);
78
+ libevaluation_interop_KInt (*getNonNullValueOfInt)(libevaluation_interop_kref_kotlin_Int);
64
79
  libevaluation_interop_kref_kotlin_Long (*createNullableLong)(libevaluation_interop_KLong);
80
+ libevaluation_interop_KLong (*getNonNullValueOfLong)(libevaluation_interop_kref_kotlin_Long);
65
81
  libevaluation_interop_kref_kotlin_Float (*createNullableFloat)(libevaluation_interop_KFloat);
82
+ libevaluation_interop_KFloat (*getNonNullValueOfFloat)(libevaluation_interop_kref_kotlin_Float);
66
83
  libevaluation_interop_kref_kotlin_Double (*createNullableDouble)(libevaluation_interop_KDouble);
84
+ libevaluation_interop_KDouble (*getNonNullValueOfDouble)(libevaluation_interop_kref_kotlin_Double);
67
85
  libevaluation_interop_kref_kotlin_Char (*createNullableChar)(libevaluation_interop_KChar);
86
+ libevaluation_interop_KChar (*getNonNullValueOfChar)(libevaluation_interop_kref_kotlin_Char);
68
87
  libevaluation_interop_kref_kotlin_Boolean (*createNullableBoolean)(libevaluation_interop_KBoolean);
88
+ libevaluation_interop_KBoolean (*getNonNullValueOfBoolean)(libevaluation_interop_kref_kotlin_Boolean);
69
89
  libevaluation_interop_kref_kotlin_Unit (*createNullableUnit)(void);
90
+ libevaluation_interop_kref_kotlin_UByte (*createNullableUByte)(libevaluation_interop_KUByte);
91
+ libevaluation_interop_KUByte (*getNonNullValueOfUByte)(libevaluation_interop_kref_kotlin_UByte);
92
+ libevaluation_interop_kref_kotlin_UShort (*createNullableUShort)(libevaluation_interop_KUShort);
93
+ libevaluation_interop_KUShort (*getNonNullValueOfUShort)(libevaluation_interop_kref_kotlin_UShort);
94
+ libevaluation_interop_kref_kotlin_UInt (*createNullableUInt)(libevaluation_interop_KUInt);
95
+ libevaluation_interop_KUInt (*getNonNullValueOfUInt)(libevaluation_interop_kref_kotlin_UInt);
96
+ libevaluation_interop_kref_kotlin_ULong (*createNullableULong)(libevaluation_interop_KULong);
97
+ libevaluation_interop_KULong (*getNonNullValueOfULong)(libevaluation_interop_kref_kotlin_ULong);
70
98
 
71
99
  /* User functions. */
72
100
  struct {
@@ -51,6 +51,18 @@ typedef struct {
51
51
  typedef struct {
52
52
  libevaluation_interop_KNativePtr pinned;
53
53
  } libevaluation_interop_kref_kotlin_Unit;
54
+ typedef struct {
55
+ libevaluation_interop_KNativePtr pinned;
56
+ } libevaluation_interop_kref_kotlin_UByte;
57
+ typedef struct {
58
+ libevaluation_interop_KNativePtr pinned;
59
+ } libevaluation_interop_kref_kotlin_UShort;
60
+ typedef struct {
61
+ libevaluation_interop_KNativePtr pinned;
62
+ } libevaluation_interop_kref_kotlin_UInt;
63
+ typedef struct {
64
+ libevaluation_interop_KNativePtr pinned;
65
+ } libevaluation_interop_kref_kotlin_ULong;
54
66
 
55
67
 
56
68
  typedef struct {
@@ -59,14 +71,30 @@ typedef struct {
59
71
  void (*DisposeString)(const char* string);
60
72
  libevaluation_interop_KBoolean (*IsInstance)(libevaluation_interop_KNativePtr ref, const libevaluation_interop_KType* type);
61
73
  libevaluation_interop_kref_kotlin_Byte (*createNullableByte)(libevaluation_interop_KByte);
74
+ libevaluation_interop_KByte (*getNonNullValueOfByte)(libevaluation_interop_kref_kotlin_Byte);
62
75
  libevaluation_interop_kref_kotlin_Short (*createNullableShort)(libevaluation_interop_KShort);
76
+ libevaluation_interop_KShort (*getNonNullValueOfShort)(libevaluation_interop_kref_kotlin_Short);
63
77
  libevaluation_interop_kref_kotlin_Int (*createNullableInt)(libevaluation_interop_KInt);
78
+ libevaluation_interop_KInt (*getNonNullValueOfInt)(libevaluation_interop_kref_kotlin_Int);
64
79
  libevaluation_interop_kref_kotlin_Long (*createNullableLong)(libevaluation_interop_KLong);
80
+ libevaluation_interop_KLong (*getNonNullValueOfLong)(libevaluation_interop_kref_kotlin_Long);
65
81
  libevaluation_interop_kref_kotlin_Float (*createNullableFloat)(libevaluation_interop_KFloat);
82
+ libevaluation_interop_KFloat (*getNonNullValueOfFloat)(libevaluation_interop_kref_kotlin_Float);
66
83
  libevaluation_interop_kref_kotlin_Double (*createNullableDouble)(libevaluation_interop_KDouble);
84
+ libevaluation_interop_KDouble (*getNonNullValueOfDouble)(libevaluation_interop_kref_kotlin_Double);
67
85
  libevaluation_interop_kref_kotlin_Char (*createNullableChar)(libevaluation_interop_KChar);
86
+ libevaluation_interop_KChar (*getNonNullValueOfChar)(libevaluation_interop_kref_kotlin_Char);
68
87
  libevaluation_interop_kref_kotlin_Boolean (*createNullableBoolean)(libevaluation_interop_KBoolean);
88
+ libevaluation_interop_KBoolean (*getNonNullValueOfBoolean)(libevaluation_interop_kref_kotlin_Boolean);
69
89
  libevaluation_interop_kref_kotlin_Unit (*createNullableUnit)(void);
90
+ libevaluation_interop_kref_kotlin_UByte (*createNullableUByte)(libevaluation_interop_KUByte);
91
+ libevaluation_interop_KUByte (*getNonNullValueOfUByte)(libevaluation_interop_kref_kotlin_UByte);
92
+ libevaluation_interop_kref_kotlin_UShort (*createNullableUShort)(libevaluation_interop_KUShort);
93
+ libevaluation_interop_KUShort (*getNonNullValueOfUShort)(libevaluation_interop_kref_kotlin_UShort);
94
+ libevaluation_interop_kref_kotlin_UInt (*createNullableUInt)(libevaluation_interop_KUInt);
95
+ libevaluation_interop_KUInt (*getNonNullValueOfUInt)(libevaluation_interop_kref_kotlin_UInt);
96
+ libevaluation_interop_kref_kotlin_ULong (*createNullableULong)(libevaluation_interop_KULong);
97
+ libevaluation_interop_KULong (*getNonNullValueOfULong)(libevaluation_interop_kref_kotlin_ULong);
70
98
 
71
99
  /* User functions. */
72
100
  struct {
@@ -51,6 +51,18 @@ typedef struct {
51
51
  typedef struct {
52
52
  libevaluation_interop_KNativePtr pinned;
53
53
  } libevaluation_interop_kref_kotlin_Unit;
54
+ typedef struct {
55
+ libevaluation_interop_KNativePtr pinned;
56
+ } libevaluation_interop_kref_kotlin_UByte;
57
+ typedef struct {
58
+ libevaluation_interop_KNativePtr pinned;
59
+ } libevaluation_interop_kref_kotlin_UShort;
60
+ typedef struct {
61
+ libevaluation_interop_KNativePtr pinned;
62
+ } libevaluation_interop_kref_kotlin_UInt;
63
+ typedef struct {
64
+ libevaluation_interop_KNativePtr pinned;
65
+ } libevaluation_interop_kref_kotlin_ULong;
54
66
 
55
67
 
56
68
  typedef struct {
@@ -59,14 +71,30 @@ typedef struct {
59
71
  void (*DisposeString)(const char* string);
60
72
  libevaluation_interop_KBoolean (*IsInstance)(libevaluation_interop_KNativePtr ref, const libevaluation_interop_KType* type);
61
73
  libevaluation_interop_kref_kotlin_Byte (*createNullableByte)(libevaluation_interop_KByte);
74
+ libevaluation_interop_KByte (*getNonNullValueOfByte)(libevaluation_interop_kref_kotlin_Byte);
62
75
  libevaluation_interop_kref_kotlin_Short (*createNullableShort)(libevaluation_interop_KShort);
76
+ libevaluation_interop_KShort (*getNonNullValueOfShort)(libevaluation_interop_kref_kotlin_Short);
63
77
  libevaluation_interop_kref_kotlin_Int (*createNullableInt)(libevaluation_interop_KInt);
78
+ libevaluation_interop_KInt (*getNonNullValueOfInt)(libevaluation_interop_kref_kotlin_Int);
64
79
  libevaluation_interop_kref_kotlin_Long (*createNullableLong)(libevaluation_interop_KLong);
80
+ libevaluation_interop_KLong (*getNonNullValueOfLong)(libevaluation_interop_kref_kotlin_Long);
65
81
  libevaluation_interop_kref_kotlin_Float (*createNullableFloat)(libevaluation_interop_KFloat);
82
+ libevaluation_interop_KFloat (*getNonNullValueOfFloat)(libevaluation_interop_kref_kotlin_Float);
66
83
  libevaluation_interop_kref_kotlin_Double (*createNullableDouble)(libevaluation_interop_KDouble);
84
+ libevaluation_interop_KDouble (*getNonNullValueOfDouble)(libevaluation_interop_kref_kotlin_Double);
67
85
  libevaluation_interop_kref_kotlin_Char (*createNullableChar)(libevaluation_interop_KChar);
86
+ libevaluation_interop_KChar (*getNonNullValueOfChar)(libevaluation_interop_kref_kotlin_Char);
68
87
  libevaluation_interop_kref_kotlin_Boolean (*createNullableBoolean)(libevaluation_interop_KBoolean);
88
+ libevaluation_interop_KBoolean (*getNonNullValueOfBoolean)(libevaluation_interop_kref_kotlin_Boolean);
69
89
  libevaluation_interop_kref_kotlin_Unit (*createNullableUnit)(void);
90
+ libevaluation_interop_kref_kotlin_UByte (*createNullableUByte)(libevaluation_interop_KUByte);
91
+ libevaluation_interop_KUByte (*getNonNullValueOfUByte)(libevaluation_interop_kref_kotlin_UByte);
92
+ libevaluation_interop_kref_kotlin_UShort (*createNullableUShort)(libevaluation_interop_KUShort);
93
+ libevaluation_interop_KUShort (*getNonNullValueOfUShort)(libevaluation_interop_kref_kotlin_UShort);
94
+ libevaluation_interop_kref_kotlin_UInt (*createNullableUInt)(libevaluation_interop_KUInt);
95
+ libevaluation_interop_KUInt (*getNonNullValueOfUInt)(libevaluation_interop_kref_kotlin_UInt);
96
+ libevaluation_interop_kref_kotlin_ULong (*createNullableULong)(libevaluation_interop_KULong);
97
+ libevaluation_interop_KULong (*getNonNullValueOfULong)(libevaluation_interop_kref_kotlin_ULong);
70
98
 
71
99
  /* User functions. */
72
100
  struct {
@@ -7,9 +7,28 @@ module AmplitudeExperiment
7
7
 
8
8
  def initialize(api_key, debug, server_url = 'https://api.lab.amplitude.com')
9
9
  @api_key = api_key
10
- @uri = "#{server_url}/sdk/rules?eval_mode=local"
10
+ @server_url = server_url
11
11
  @debug = debug
12
- @http = PersistentHttpClient.get(@uri, { read_timeout: FLAG_CONFIG_TIMEOUT })
12
+ @http = PersistentHttpClient.get(server_url, { read_timeout: FLAG_CONFIG_TIMEOUT })
13
+ end
14
+
15
+ # Fetch local evaluation mode flag configs from the Experiment API server.
16
+ # These flag configs can be used to perform local evaluation.
17
+ #
18
+ # @return [String] The flag configs
19
+ def fetch_v1
20
+ # fetch flag_configs
21
+ headers = {
22
+ 'Authorization' => "Api-Key #{@api_key}",
23
+ 'Content-Type' => 'application/json;charset=utf-8',
24
+ 'X-Amp-Exp-Library' => "experiment-ruby-server/#{VERSION}"
25
+ }
26
+ request = Net::HTTP::Get.new("#{@server_url}/sdk/v1/flags", headers)
27
+ response = @http.request(request)
28
+ raise "flagConfigs - received error response: #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPOK)
29
+
30
+ @logger.debug("[Experiment] Fetch flag configs: #{response.body}") if @debug
31
+ response.body
13
32
  end
14
33
 
15
34
  # Fetch local evaluation mode flag configs from the Experiment API server.
@@ -23,7 +42,7 @@ module AmplitudeExperiment
23
42
  'Content-Type' => 'application/json;charset=utf-8',
24
43
  'X-Amp-Exp-Library' => "experiment-ruby-server/#{VERSION}"
25
44
  }
26
- request = Net::HTTP::Get.new(@uri, headers)
45
+ request = Net::HTTP::Get.new("#{@server_url}/sdk/rules?eval_mode=local", headers)
27
46
  response = @http.request(request)
28
47
  raise "flagConfigs - received error response: #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPOK)
29
48
 
@@ -1,3 +1,3 @@
1
1
  module AmplitudeExperiment
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amplitude-experiment
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amplitude
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-27 00:00:00.000000000 Z
11
+ date: 2023-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -150,7 +150,6 @@ files:
150
150
  - lib/amplitude-experiment.rb
151
151
  - lib/experiment/cookie.rb
152
152
  - lib/experiment/factory.rb
153
- - lib/experiment/local/cache.rb
154
153
  - lib/experiment/local/client.rb
155
154
  - lib/experiment/local/config.rb
156
155
  - lib/experiment/local/evaluation/evaluation.rb
@@ -163,7 +162,6 @@ files:
163
162
  - lib/experiment/local/evaluation/lib/macosX64/libevaluation_interop.dylib
164
163
  - lib/experiment/local/evaluation/lib/macosX64/libevaluation_interop_api.h
165
164
  - lib/experiment/local/fetcher.rb
166
- - lib/experiment/local/poller.rb
167
165
  - lib/experiment/persistent_http_client.rb
168
166
  - lib/experiment/remote/client.rb
169
167
  - lib/experiment/remote/config.rb
@@ -1,53 +0,0 @@
1
- require 'uri'
2
- require 'logger'
3
-
4
- module AmplitudeExperiment
5
- # InMemoryFlagConfigCache
6
- # The place to store the flag configs fetched from the server
7
- class InMemoryFlagConfigCache
8
- attr_accessor :cache
9
-
10
- def initialize(flag_configs = {})
11
- @semaphore = Mutex.new
12
- @cache = flag_configs
13
- end
14
-
15
- def get(flag_key)
16
- @semaphore.synchronize do
17
- @cache.fetch(flag_key, nil)
18
- end
19
- end
20
-
21
- def caches
22
- @semaphore.synchronize do
23
- @cache
24
- end
25
- end
26
-
27
- def put(flag_key, flag_config)
28
- @semaphore.synchronize do
29
- @cache.store(flag_key, flag_config.clone)
30
- end
31
- end
32
-
33
- def put_all(flag_configs)
34
- @semaphore.synchronize do
35
- flag_configs.each do |key, value|
36
- @cache.store(key, value.clone) if value
37
- end
38
- end
39
- end
40
-
41
- def delete(flag_key)
42
- @semaphore.synchronize do
43
- @cache.delete(flag_key)
44
- end
45
- end
46
-
47
- def clear
48
- @semaphore.synchronize do
49
- @cache = {}
50
- end
51
- end
52
- end
53
- end
@@ -1,48 +0,0 @@
1
- module AmplitudeExperiment
2
- # FlagConfigPoller
3
- # update the flag_config cache value
4
- class FlagConfigPoller
5
- FLAG_CONFIG_POLLING_INTERVAL_MILLIS = 30_000
6
-
7
- def initialize(fetcher, cache, debug, poll_interval_millis = FLAG_CONFIG_POLLING_INTERVAL_MILLIS)
8
- @fetcher = fetcher
9
- @cache = cache
10
- @poll_interval_millis = poll_interval_millis
11
- @logger = Logger.new($stdout)
12
- @debug = debug
13
- @poller_thread = nil
14
- @is_running = false
15
- end
16
-
17
- # Fetch initial flag configurations and start polling for updates.
18
- # You must call this function to begin polling for flag config updates.
19
- # Calling this function while the poller is already running does nothing.
20
- def start
21
- return if @is_running
22
-
23
- @logger.debug('[Experiment] poller - start') if @debug
24
- run
25
- end
26
-
27
- # Stop polling for flag configurations.
28
- # Calling this function while the poller is not running will do nothing.
29
- def stop
30
- @poller_thread&.exit
31
- @is_running = false
32
- @poller_thread = nil
33
- end
34
-
35
- private
36
-
37
- def run
38
- @is_running = true
39
- flag_configs = @fetcher.fetch
40
- @cache.clear
41
- @cache.put_all(flag_configs)
42
- @poller_thread = Thread.new do
43
- sleep(@poll_interval_millis / 1000.to_f)
44
- run
45
- end
46
- end
47
- end
48
- end