prefab-cloud-ruby 0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.ruby-version +1 -0
  3. data/Gemfile +9 -22
  4. data/Gemfile.lock +88 -160
  5. data/LICENSE.txt +1 -1
  6. data/Rakefile +14 -14
  7. data/VERSION +1 -1
  8. data/lib/prefab/auth_interceptor.rb +25 -0
  9. data/lib/prefab/client.rb +34 -139
  10. data/lib/prefab/config_client.rb +23 -275
  11. data/lib/prefab/config_loader.rb +27 -60
  12. data/lib/prefab/config_resolver.rb +40 -53
  13. data/lib/prefab/noop_cache.rb +13 -0
  14. data/lib/prefab/noop_stats.rb +8 -0
  15. data/lib/prefab/prefab_pb.rb +39 -0
  16. data/lib/prefab/prefab_services_pb.rb +37 -0
  17. data/lib/prefab/ratelimit_client.rb +58 -0
  18. data/lib/prefab/ratelimit_pb.rb +125 -0
  19. data/lib/prefab/store.rb +29 -0
  20. data/lib/prefab_client.rb +35 -0
  21. metadata +36 -198
  22. data/.envrc.sample +0 -3
  23. data/.github/workflows/ruby.yml +0 -46
  24. data/.gitmodules +0 -3
  25. data/.rubocop.yml +0 -13
  26. data/.tool-versions +0 -1
  27. data/CHANGELOG.md +0 -169
  28. data/CODEOWNERS +0 -1
  29. data/README.md +0 -94
  30. data/bin/console +0 -21
  31. data/compile_protos.sh +0 -18
  32. data/lib/prefab/config_client_presenter.rb +0 -18
  33. data/lib/prefab/config_value_unwrapper.rb +0 -115
  34. data/lib/prefab/config_value_wrapper.rb +0 -18
  35. data/lib/prefab/context.rb +0 -179
  36. data/lib/prefab/context_shape.rb +0 -20
  37. data/lib/prefab/context_shape_aggregator.rb +0 -65
  38. data/lib/prefab/criteria_evaluator.rb +0 -136
  39. data/lib/prefab/encryption.rb +0 -65
  40. data/lib/prefab/error.rb +0 -6
  41. data/lib/prefab/errors/env_var_parse_error.rb +0 -11
  42. data/lib/prefab/errors/initialization_timeout_error.rb +0 -13
  43. data/lib/prefab/errors/invalid_api_key_error.rb +0 -19
  44. data/lib/prefab/errors/missing_default_error.rb +0 -13
  45. data/lib/prefab/errors/missing_env_var_error.rb +0 -11
  46. data/lib/prefab/errors/uninitialized_error.rb +0 -13
  47. data/lib/prefab/evaluation.rb +0 -52
  48. data/lib/prefab/evaluation_summary_aggregator.rb +0 -87
  49. data/lib/prefab/example_contexts_aggregator.rb +0 -78
  50. data/lib/prefab/exponential_backoff.rb +0 -21
  51. data/lib/prefab/feature_flag_client.rb +0 -42
  52. data/lib/prefab/http_connection.rb +0 -41
  53. data/lib/prefab/internal_logger.rb +0 -16
  54. data/lib/prefab/local_config_parser.rb +0 -151
  55. data/lib/prefab/log_path_aggregator.rb +0 -69
  56. data/lib/prefab/logger_client.rb +0 -264
  57. data/lib/prefab/murmer3.rb +0 -50
  58. data/lib/prefab/options.rb +0 -208
  59. data/lib/prefab/periodic_sync.rb +0 -69
  60. data/lib/prefab/prefab.rb +0 -56
  61. data/lib/prefab/rate_limit_cache.rb +0 -41
  62. data/lib/prefab/resolved_config_presenter.rb +0 -86
  63. data/lib/prefab/time_helpers.rb +0 -7
  64. data/lib/prefab/weighted_value_resolver.rb +0 -42
  65. data/lib/prefab/yaml_config_parser.rb +0 -34
  66. data/lib/prefab-cloud-ruby.rb +0 -57
  67. data/lib/prefab_pb.rb +0 -93
  68. data/prefab-cloud-ruby.gemspec +0 -155
  69. data/test/.prefab.default.config.yaml +0 -2
  70. data/test/.prefab.unit_tests.config.yaml +0 -28
  71. data/test/integration_test.rb +0 -150
  72. data/test/integration_test_helpers.rb +0 -151
  73. data/test/support/common_helpers.rb +0 -180
  74. data/test/support/mock_base_client.rb +0 -42
  75. data/test/support/mock_config_client.rb +0 -19
  76. data/test/support/mock_config_loader.rb +0 -1
  77. data/test/test_client.rb +0 -444
  78. data/test/test_config_client.rb +0 -109
  79. data/test/test_config_loader.rb +0 -117
  80. data/test/test_config_resolver.rb +0 -430
  81. data/test/test_config_value_unwrapper.rb +0 -224
  82. data/test/test_config_value_wrapper.rb +0 -42
  83. data/test/test_context.rb +0 -203
  84. data/test/test_context_shape.rb +0 -50
  85. data/test/test_context_shape_aggregator.rb +0 -147
  86. data/test/test_criteria_evaluator.rb +0 -726
  87. data/test/test_encryption.rb +0 -16
  88. data/test/test_evaluation_summary_aggregator.rb +0 -162
  89. data/test/test_example_contexts_aggregator.rb +0 -238
  90. data/test/test_exponential_backoff.rb +0 -18
  91. data/test/test_feature_flag_client.rb +0 -48
  92. data/test/test_helper.rb +0 -17
  93. data/test/test_integration.rb +0 -58
  94. data/test/test_local_config_parser.rb +0 -147
  95. data/test/test_log_path_aggregator.rb +0 -62
  96. data/test/test_logger.rb +0 -621
  97. data/test/test_logger_initialization.rb +0 -12
  98. data/test/test_options.rb +0 -75
  99. data/test/test_prefab.rb +0 -12
  100. data/test/test_rate_limit_cache.rb +0 -44
  101. data/test/test_weighted_value_resolver.rb +0 -71
@@ -1,292 +1,40 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Prefab
4
2
  class ConfigClient
5
- RECONNECT_WAIT = 5
6
- DEFAULT_CHECKPOINT_FREQ_SEC = 60
7
- SSE_READ_TIMEOUT = 300
8
- STALE_CACHE_WARN_HOURS = 5
9
- AUTH_USER = 'authuser'
10
- LOGGING_KEY_PREFIX = "#{Prefab::LoggerClient::BASE_KEY}#{Prefab::LoggerClient::SEP}".freeze
11
- LOG = Prefab::InternalLogger.new(ConfigClient)
12
-
13
- def initialize(base_client, timeout)
14
- @base_client = base_client
15
- @options = base_client.options
16
- LOG.debug 'Initialize ConfigClient'
17
- @timeout = timeout
18
-
19
- @stream_lock = Concurrent::ReadWriteLock.new
20
-
21
- @checkpoint_freq_secs = DEFAULT_CHECKPOINT_FREQ_SEC
22
-
23
- @config_loader = Prefab::ConfigLoader.new(@base_client)
24
- @config_resolver = Prefab::ConfigResolver.new(@base_client, @config_loader)
25
-
26
- @initialization_lock = Concurrent::ReadWriteLock.new
27
- LOG.debug 'Initialize ConfigClient: AcquireWriteLock'
28
- @initialization_lock.acquire_write_lock
29
- LOG.debug 'Initialize ConfigClient: AcquiredWriteLock'
30
- @initialized_future = Concurrent::Future.execute { @initialization_lock.acquire_read_lock }
31
-
32
- if @options.local_only?
33
- finish_init!(:local_only, nil)
34
- elsif @options.datafile?
35
- load_json_file(@options.datafile)
36
- else
37
- load_checkpoint
38
- start_checkpointing_thread
39
- start_streaming
40
- end
41
- end
42
-
43
- def start_streaming
44
- @stream_lock.with_write_lock do
45
- start_sse_streaming_connection_thread(@config_loader.highwater_mark) if @streaming_thread.nil?
46
- end
47
- end
48
-
49
- def to_s
50
- @config_resolver.to_s
51
- end
52
-
53
- def resolver
54
- @config_resolver
3
+ def initialize(config_service, client)
4
+ @client = client
5
+ @config_service = config_service
6
+ @config_resolver = EzConfig::ConfigResolver.new(client)
7
+ boot_resolver(@config_service)
55
8
  end
56
9
 
57
- def self.value_to_delta(key, config_value, namespace = nil)
58
- PrefabProto::Config.new(key: [namespace, key].compact.join(':'),
59
- rows: [PrefabProto::ConfigRow.new(value: config_value)])
10
+ def get(prop)
11
+ @config_resolver.get(prop)
60
12
  end
61
13
 
62
- def get(key, default = NO_DEFAULT_PROVIDED, properties = NO_DEFAULT_PROVIDED)
63
- context = @config_resolver.make_context(properties)
64
-
65
- if !context.blank? && @base_client.example_contexts_aggregator
66
- @base_client.example_contexts_aggregator.record(context)
67
- end
68
-
69
- evaluation = _get(key, context)
70
-
71
- @base_client.context_shape_aggregator&.push(context)
72
-
73
- if evaluation
74
- evaluation.report_and_return(@base_client.evaluation_summary_aggregator)
75
- else
76
- handle_default(key, default)
77
- end
14
+ def set(config_value)
15
+ @config_service.upsert(config_value)
78
16
  end
79
17
 
80
18
  private
81
19
 
82
- def raw(key)
83
- @config_resolver.raw(key)
84
- end
85
-
86
- def handle_default(key, default)
87
- return default if default != NO_DEFAULT_PROVIDED
88
-
89
- raise Prefab::Errors::MissingDefaultError, key if @options.on_no_default == Prefab::Options::ON_NO_DEFAULT::RAISE
90
-
91
- nil
92
- end
93
-
94
- def _get(key, properties)
95
- # wait timeout sec for the initialization to be complete
96
- @initialized_future.value(@options.initialization_timeout_sec)
97
- if @initialized_future.incomplete?
98
- unless @options.on_init_failure == Prefab::Options::ON_INITIALIZATION_FAILURE::RETURN
99
- raise Prefab::Errors::InitializationTimeoutError.new(@options.initialization_timeout_sec, key)
100
- end
101
-
102
- LOG.warn("Couldn't Initialize In #{@options.initialization_timeout_sec}. Key #{key}. Returning what we have")
103
- @initialization_lock.release_write_lock
104
- end
105
-
106
- @config_resolver.get key, properties
107
- end
108
-
109
- def load_checkpoint
110
- success = load_checkpoint_api_cdn
111
-
112
- return if success
113
-
114
- success = load_checkpoint_api
115
-
116
- return if success
117
-
118
- success = load_cache
119
-
120
- return if success
121
-
122
- LOG.warn 'No success loading checkpoints'
123
- end
124
-
125
- def load_checkpoint_api_cdn
126
- conn = Prefab::HttpConnection.new("#{@options.url_for_api_cdn}/api/v1/configs/0", @base_client.api_key)
127
- load_url(conn, :remote_cdn_api)
128
- end
129
-
130
- def load_checkpoint_api
131
- conn = Prefab::HttpConnection.new("#{@options.prefab_api_url}/api/v1/configs/0", @base_client.api_key)
132
- load_url(conn, :remote_api)
133
- end
134
-
135
- def load_url(conn, source)
136
- resp = conn.get('')
137
- if resp.status == 200
138
- configs = PrefabProto::Configs.decode(resp.body)
139
- load_configs(configs, source)
140
- cache_configs(configs)
141
- true
142
- else
143
- LOG.info "Checkpoint #{source} failed to load. Response #{resp.status}"
144
- false
145
- end
146
- rescue Faraday::ConnectionFailed => e
147
- if @initialization_lock.write_locked?
148
- LOG.warn "Connection Fail loading #{source} checkpoint."
149
- else
150
- LOG.debug "Connection Fail loading #{source} checkpoint."
151
- end
152
- false
153
- rescue StandardError => e
154
- LOG.warn "Unexpected #{source} problem loading checkpoint #{e} #{conn}"
155
- LOG.debug e.backtrace
156
- false
157
- end
158
-
159
- def load_configs(configs, source)
160
- project_id = configs.config_service_pointer.project_id
161
- project_env_id = configs.config_service_pointer.project_env_id
162
- @config_resolver.project_env_id = project_env_id
163
- starting_highwater_mark = @config_loader.highwater_mark
164
-
165
- default_contexts = configs.default_context&.contexts&.map do |context|
166
- [
167
- context.type,
168
- context.values.keys.map do |k|
169
- [k, Prefab::ConfigValueUnwrapper.new(context.values[k], @config_resolver).unwrap]
170
- end.to_h
171
- ]
172
- end.to_h
173
-
174
- @config_resolver.default_context = default_contexts || {}
175
-
176
- configs.configs.each do |config|
177
- @config_loader.set(config, source)
178
- end
179
- if @config_loader.highwater_mark > starting_highwater_mark
180
- LOG.debug("Found new checkpoint with highwater id #{@config_loader.highwater_mark} from #{source} in project #{project_id} environment: #{project_env_id} and namespace: '#{@namespace}'")
181
- else
182
- LOG.debug("Checkpoint with highwater id #{@config_loader.highwater_mark} from #{source}. No changes.")
183
- end
184
- @config_resolver.update
185
- finish_init!(source, project_id)
186
- end
187
-
188
- def cache_path
189
- return @cache_path unless @cache_path.nil?
190
- @cache_path ||= calc_cache_path
191
- FileUtils.mkdir_p(File.dirname(@cache_path))
192
- @cache_path
193
- end
194
-
195
- def calc_cache_path
196
- file_name = "prefab.cache.#{@base_client.options.api_key_id}.json"
197
- dir = ENV.fetch('XDG_CACHE_HOME', File.join(Dir.home, '.cache'))
198
- File.join(dir, file_name)
199
- end
200
-
201
- def cache_configs(configs)
202
- return unless @options.use_local_cache && !@options.is_fork
203
- File.open(cache_path, "w") do |f|
204
- f.flock(File::LOCK_EX)
205
- f.write(PrefabProto::Configs.encode_json(configs))
206
- end
207
- LOG.debug "Cached configs to #{cache_path}"
208
- rescue => e
209
- LOG.debug "Failed to cache configs to #{cache_path} #{e}"
210
- end
211
-
212
- def load_cache
213
- return false unless @options.use_local_cache
214
- File.open(cache_path) do |f|
215
- f.flock(File::LOCK_SH)
216
- configs = PrefabProto::Configs.decode_json(f.read)
217
- load_configs(configs, :cache)
218
-
219
- hours_old = ((Time.now - File.mtime(f)) / 60 / 60).round(2)
220
- if hours_old > STALE_CACHE_WARN_HOURS
221
- LOG.info "Stale Cache Load: #{hours_old} hours old"
222
- end
223
- true
224
- end
225
- rescue => e
226
- LOG.debug "Failed to read cached configs at #{cache_path}. #{e}"
227
- false
228
- end
229
-
230
- def load_json_file(file)
231
- File.open(file) do |f|
232
- f.flock(File::LOCK_SH)
233
- configs = PrefabProto::Configs.decode_json(f.read)
234
- load_configs(configs, :datafile)
235
- end
236
- end
20
+ def boot_resolver(config_service)
21
+ config_req = Prefab::ConfigServicePointer.new(account_id: 1,
22
+ start_at_id: 0)
237
23
 
238
- # A thread that checks for a checkpoint
239
- def start_checkpointing_thread
240
24
  Thread.new do
241
- loop do
242
- started_at = Time.now
243
- delta = @checkpoint_freq_secs - (Time.now - started_at)
244
- sleep(delta) if delta > 0
245
-
246
- load_checkpoint
247
- rescue StandardError => e
248
- LOG.debug "Issue Checkpointing #{e.message}"
249
- end
250
- end
251
- end
252
-
253
- def finish_init!(source, project_id)
254
- return unless @initialization_lock.write_locked?
255
-
256
- LOG.debug "Unlocked Config via #{source}"
257
- @initialization_lock.release_write_lock
258
-
259
- Prefab::LoggerClient.instance.config_client = self
260
- presenter = Prefab::ConfigClientPresenter.new(
261
- size: @config_resolver.local_store.size,
262
- source: source,
263
- project_id: project_id,
264
- project_env_id: @config_resolver.project_env_id,
265
- api_key_id: @base_client.options.api_key_id
266
- )
267
- LOG.info presenter.to_s
268
- LOG.debug to_s
269
- end
270
-
271
- def start_sse_streaming_connection_thread(start_at_id)
272
- auth = "#{AUTH_USER}:#{@base_client.api_key}"
273
- auth_string = Base64.strict_encode64(auth)
274
- headers = {
275
- 'x-prefab-start-at-id' => start_at_id,
276
- 'Authorization' => "Basic #{auth_string}",
277
- 'X-PrefabCloud-Client-Version' => "prefab-cloud-ruby-#{Prefab::VERSION}"
278
- }
279
- url = "#{@base_client.prefab_api_url}/api/v1/sse/config"
280
- LOG.debug "SSE Streaming Connect to #{url} start_at #{start_at_id}"
281
- @streaming_thread = SSE::Client.new(url,
282
- headers: headers,
283
- read_timeout: SSE_READ_TIMEOUT,
284
- logger: Prefab::SseLogger.new) do |client|
285
- client.on_event do |event|
286
- configs = PrefabProto::Configs.decode(Base64.decode64(event.data))
287
- load_configs(configs, :sse)
25
+ begin
26
+ resp = config_service.get_config(config_req)
27
+ resp.each do |r|
28
+ r.deltas.each do |delta|
29
+ @config_resolver.set(delta)
30
+ end
31
+ @config_resolver.update
32
+ end
33
+ rescue => e
34
+ @client.logger.warn(e)
288
35
  end
289
36
  end
290
37
  end
291
38
  end
292
39
  end
40
+
@@ -1,84 +1,51 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
1
+ require 'yaml'
2
+ module EzConfig
4
3
  class ConfigLoader
5
- LOG = Prefab::InternalLogger.new(ConfigLoader)
6
-
7
- attr_reader :highwater_mark
8
-
9
- def initialize(base_client)
10
- @base_client = base_client
11
- @prefab_options = base_client.options
12
- @highwater_mark = 0
13
- @classpath_config = load_classpath_config
14
- @local_overrides = load_local_overrides
4
+ def initialize(logger)
5
+ @logger = logger
6
+ load_ez_config
7
+ load_project_config
8
+ load_local_overrides
15
9
  @api_config = Concurrent::Map.new
10
+ @immutable_config = @ez_config.merge(@project_config)
16
11
  end
17
12
 
18
13
  def calc_config
19
- rtn = @classpath_config.clone
14
+ rtn = @immutable_config.clone
20
15
  @api_config.each_key do |k|
21
16
  rtn[k] = @api_config[k]
22
17
  end
23
- rtn.merge(@local_overrides)
18
+ rtn = rtn.merge(@local_overrides)
19
+ rtn
24
20
  end
25
21
 
26
- def set(config, source)
27
- # don't overwrite newer values
28
- return if @api_config[config.key] && @api_config[config.key][:config].id >= config.id
29
-
30
- if config.rows.empty?
31
- @api_config.delete(config.key)
32
- else
33
- if @api_config[config.key]
34
- LOG.debug(
35
- "Replace #{config.key} with value from #{source} #{@api_config[config.key][:config].id} -> #{config.id}")
36
- end
37
- @api_config[config.key] = { source: source, config: config }
38
- end
39
- @highwater_mark = [config.id, @highwater_mark].max
22
+ def set(delta)
23
+ @api_config[delta.key] = delta.value
40
24
  end
41
25
 
42
- def rm(key)
43
- @api_config.delete key
44
- end
26
+ private
45
27
 
46
- def get_api_deltas
47
- configs = PrefabProto::Configs.new
48
- @api_config.each_value do |config_value|
49
- configs.configs << config_value[:config]
50
- end
51
- configs
28
+ def load_ez_config
29
+ @ez_config = load(".ezconfig.yaml")
52
30
  end
53
31
 
54
- private
55
-
56
- def load_classpath_config
57
- return {} if @prefab_options.datafile?
58
- classpath_dir = @prefab_options.prefab_config_classpath_dir
59
- rtn = load_glob(File.join(classpath_dir, '.prefab.default.config.yaml'))
60
- @prefab_options.prefab_envs.each do |env|
61
- rtn = rtn.merge load_glob(File.join(classpath_dir, ".prefab.#{env}.config.yaml"))
62
- end
63
- rtn
32
+ def load_project_config
33
+ @project_config = load(".projectconfig.yaml")
64
34
  end
65
35
 
66
36
  def load_local_overrides
67
- return {} if @prefab_options.datafile?
68
- override_dir = @prefab_options.prefab_config_override_dir
69
- rtn = load_glob(File.join(override_dir, '.prefab.default.config.yaml'))
70
- @prefab_options.prefab_envs.each do |env|
71
- rtn = rtn.merge load_glob(File.join(override_dir, ".prefab.#{env}.config.yaml"))
72
- end
73
- rtn
37
+ @local_overrides = load(".ezconfig.overrides.yaml")
74
38
  end
75
39
 
76
- def load_glob(glob)
77
- rtn = {}
78
- Dir.glob(glob).each do |file|
79
- Prefab::YAMLConfigParser.new(file, @base_client).merge(rtn)
40
+ def load(filename)
41
+ if File.exist? filename
42
+
43
+ YAML.load_file(filename)
44
+ else
45
+ @logger.info "No file #{filename}"
46
+ {}
80
47
  end
81
- rtn
82
48
  end
49
+
83
50
  end
84
51
  end
@@ -1,76 +1,63 @@
1
- # frozen_string_literal: true
2
-
3
- module Prefab
1
+ module EzConfig
4
2
  class ConfigResolver
5
- attr_accessor :project_env_id # this will be set by the config_client when it gets an API response
6
- attr_reader :local_store
7
-
8
- attr_accessor :default_context
9
3
 
10
- def initialize(base_client, config_loader)
4
+ def initialize(client)
11
5
  @lock = Concurrent::ReadWriteLock.new
12
6
  @local_store = {}
13
- @config_loader = config_loader
14
- @project_env_id = 0 # we don't know this yet, it is set from the API results
15
- @base_client = base_client
16
- @on_update = nil
17
- @default_context = {}
7
+ @namespace = client.namespace
8
+ @config_loader = EzConfig::ConfigLoader.new(client.logger)
18
9
  make_local
19
10
  end
20
11
 
21
- def to_s
22
- presenter.to_s
23
- end
24
-
25
- def presenter
26
- Prefab::ResolvedConfigPresenter.new(self, @lock, @local_store)
27
- end
28
-
29
- def raw(key)
30
- @local_store.dig(key, :config)
31
- end
32
-
33
- def get(key, properties = NO_DEFAULT_PROVIDED)
34
- @lock.with_read_lock do
35
- raw_config = raw(key)
36
-
37
- return nil unless raw_config
38
-
39
- evaluate(raw_config, properties)
12
+ def get(property)
13
+ value = @lock.with_read_lock do
14
+ @local_store[property][:value]
15
+ end
16
+ case value.type
17
+ when :string then
18
+ puts "SSString"
19
+ value.string
20
+ when :int then
21
+ puts "INT"
22
+ value.int
40
23
  end
41
24
  end
42
25
 
43
- def evaluate(config, properties = NO_DEFAULT_PROVIDED)
44
- Prefab::CriteriaEvaluator.new(config,
45
- project_env_id: @project_env_id,
46
- resolver: self,
47
- namespace: @base_client.options.namespace,
48
- base_client: @base_client).evaluate(make_context(properties))
26
+ def set(delta)
27
+ @config_loader.set(delta)
49
28
  end
50
29
 
51
30
  def update
52
31
  make_local
53
-
54
- @on_update ? @on_update.call : nil
55
- end
56
-
57
- def on_update(&block)
58
- @on_update = block
59
- end
60
-
61
- def make_context(properties)
62
- if properties == NO_DEFAULT_PROVIDED || properties.nil?
63
- Context.current
64
- else
65
- Context.merge_with_current(properties)
66
- end.merge_default(default_context || {})
67
32
  end
68
33
 
69
34
  private
70
35
 
71
36
  def make_local
37
+ store = {}
38
+ @config_loader.calc_config.each do |prop, value|
39
+ property = prop
40
+ namespace = ""
41
+ split = prop.split(":")
42
+
43
+ if split.size > 1
44
+ property = split[1..-1].join
45
+ namespace = split[0]
46
+ end
47
+
48
+ if (namespace == "") || namespace.start_with?(@namespace)
49
+ existing = store[property]
50
+ if existing.nil?
51
+ store[property] = { namespace: namespace, value: value }
52
+ elsif existing[:namespace].split(".").size < namespace.split(".").size
53
+ store[property] = { namespace: namespace, value: value }
54
+ end
55
+ end
56
+
57
+ puts "prop #{property} namespace #{namespace} value #{value}"
58
+ end
72
59
  @lock.with_write_lock do
73
- @local_store = @config_loader.calc_config
60
+ @local_store = store
74
61
  end
75
62
  end
76
63
  end
@@ -0,0 +1,13 @@
1
+ module Prefab
2
+ class NoopCache
3
+ def fetch(name, opts, &method)
4
+ yield
5
+ end
6
+
7
+ def write(name, value, opts=nil)
8
+ end
9
+
10
+ def read(name)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ module Prefab
2
+
3
+ class NoopStats
4
+ # receives increment("prefab.ratelimit.limitcheck", {:tags=>["policy_group:page_view", "pass:true"]})
5
+ def increment(name, opts)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,39 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: prefab.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'google/protobuf/wrappers_pb'
7
+ require 'ratelimit_pb'
8
+ Google::Protobuf::DescriptorPool.generated_pool.build do
9
+ add_message "prefab.ConfigServicePointer" do
10
+ optional :account_id, :int64, 1
11
+ optional :start_at_id, :int64, 2
12
+ end
13
+ add_message "prefab.ConfigDelta" do
14
+ optional :account_id, :int64, 1
15
+ optional :id, :int64, 2
16
+ optional :key, :string, 3
17
+ optional :value, :message, 4, "prefab.ConfigValue"
18
+ end
19
+ add_message "prefab.ConfigValue" do
20
+ oneof :type do
21
+ optional :int, :int64, 1
22
+ optional :string, :string, 2
23
+ optional :bytes, :bytes, 3
24
+ optional :double, :double, 4
25
+ optional :bool, :bool, 5
26
+ optional :feature_flag, :message, 6, "it.ratelim.data.FeatureFlag"
27
+ end
28
+ end
29
+ add_message "prefab.ConfigDeltas" do
30
+ repeated :deltas, :message, 1, "prefab.ConfigDelta"
31
+ end
32
+ end
33
+
34
+ module Prefab
35
+ ConfigServicePointer = Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigServicePointer").msgclass
36
+ ConfigDelta = Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigDelta").msgclass
37
+ ConfigValue = Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigValue").msgclass
38
+ ConfigDeltas = Google::Protobuf::DescriptorPool.generated_pool.lookup("prefab.ConfigDeltas").msgclass
39
+ end
@@ -0,0 +1,37 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: prefab.proto for package 'prefab'
3
+
4
+ require 'grpc'
5
+ require 'prefab_pb'
6
+
7
+ module Prefab
8
+ module RateLimitService
9
+ class Service
10
+
11
+ include GRPC::GenericService
12
+
13
+ self.marshal_class_method = :encode
14
+ self.unmarshal_class_method = :decode
15
+ self.service_name = 'prefab.RateLimitService'
16
+
17
+ rpc :LimitCheck, It::Ratelim::Data::LimitRequest, It::Ratelim::Data::LimitResponse
18
+ end
19
+
20
+ Stub = Service.rpc_stub_class
21
+ end
22
+ module ConfigService
23
+ class Service
24
+
25
+ include GRPC::GenericService
26
+
27
+ self.marshal_class_method = :encode
28
+ self.unmarshal_class_method = :decode
29
+ self.service_name = 'prefab.ConfigService'
30
+
31
+ rpc :GetConfig, ConfigServicePointer, stream(ConfigDeltas)
32
+ rpc :Upsert, ConfigDelta, ConfigServicePointer
33
+ end
34
+
35
+ Stub = Service.rpc_stub_class
36
+ end
37
+ end