prefab-cloud-ruby 0 → 0.0.1

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.
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