tailslide 0.1.2 → 0.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd4e9eea51d59ec4a285b3531dd36e00bb2f437e1df5e50240014c59641c7499
4
- data.tar.gz: feaae9d7f5af47900a5031426e9015290a552e0b0eb8060f80b16c2aa148df3d
3
+ metadata.gz: 8d2f6a5d7784ee42f886c0b8e6565c283c49bdfd3b013bfa272380883f53f223
4
+ data.tar.gz: ead54dc39be41c0447981804958504b5454ee293e53709876bbfb55a3adbf50a
5
5
  SHA512:
6
- metadata.gz: 81e5ec75a95f6edce34ad2136376b222e02712bc30b49ed0c0f9423a0a9b9ad78d810269a0002f607d8d9d538779c5e0237e1a264e12dc98fcd59555eb35331b
7
- data.tar.gz: c4d4c5276a112b56c2d36596e67a438a47f0f071de792cd46b04021d5e6cfb3fca8d5a712ff26c65eaca9f9565cea7913da8fba5c91db9311b34c6222900ce01
6
+ metadata.gz: 41643f574dbc72661251707830be8abaf2ffa967d2828becbb85343a28b6346902a493ba52eb53c687c665b7ba8bd12b4bcc7dc2cca59d1a6a369286bebbefd7
7
+ data.tar.gz: 44647ce3c20988c60ea938e8d23de87e0639006a470c8711156964517b7ba9c1db05ec976855d5c340e679ac60c2a26ca0ec89999e13fc52eeeb2420e38031e5
data/Gemfile CHANGED
@@ -1,17 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in tailslide.gemspec
6
6
  gemspec
7
7
 
8
- gem "async", "~> 2,0.3"
9
- gem "nats-pure", "~> 2,1.0"
10
- gem "redis", "~>4.7.1"
11
- gem "redistimeseries", "~>0.1.2"
12
- gem "rake", "~> 13.0"
8
+ gem 'async', '~> 2,0.3'
9
+ gem 'nats-pure', '~> 2,1.0'
10
+ gem 'rake', '~> 13.0'
11
+ gem 'redis', '~>4.7.1'
12
+ gem 'redistimeseries', '~>0.1.2'
13
13
 
14
- gem "minitest", "~> 5.0"
15
-
16
- gem "rubocop", "~> 1.21"
14
+ gem 'minitest', '~> 5.0'
17
15
 
16
+ gem 'rubocop', '~> 1.21'
data/README.md CHANGED
@@ -1,43 +1,232 @@
1
- # Tailslide
1
+ # Ruby SDK for Tailslide
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/tailslide`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ ---
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ This package is a server-side SDK for applications written in Ruby for the Tailslide feature flag framework.
6
+
7
+ Visit the https://github.com/tailslide-io repository or see Tailslide’s [case study](https://tailslide-io.github.io) page for more information.
6
8
 
7
9
  ## Installation
8
10
 
9
- Add this line to your application's Gemfile:
11
+ ---
12
+
13
+ Install the Tailslide npm package with `gem install tailslide`
14
+
15
+ ## Basic Usage
16
+
17
+ ---
18
+
19
+ ### Instantiating and Initializing FlagManager
20
+
21
+ The `FlagManager`class is the entry point of this SDK. It is responsible for retrieving all the flag rulesets for a given app with its `app_id` and creating new `Toggler` instances to handle toggling of feature flags within that app. To instantiate a `FlagManager` object, a user must provide a configuration object:
22
+
23
+ ```ruby
24
+ require "async"
25
+ require('tailslide')
26
+
27
+ config = {
28
+ nats_server: "nats://localhost:4222",
29
+ nats_stream: "flags_ruleset",
30
+ app_id: 1,
31
+ user_context: "375d39e6-9c3f-4f58-80bd-e5960b710295",
32
+ sdk_key: "myToken",
33
+ redis_host: "http://localhost",
34
+ redis_port: 6379,
35
+ }
36
+
37
+ Async do |task|
38
+ manager = FlagManager.new(**config)
39
+ manager.initialize_flags
40
+
41
+ end
42
+ ```
43
+
44
+ - `nats_server` is the NATS JetStream server `address:port`
45
+ - `nats_stream` is the NATS JetStream’s stream name that stores all the apps and their flag rulesets
46
+ - `app_id` is the ID number of the app the user wants to retrieve its flag ruleset from
47
+ - `user_context` is the UUID string that identifies the current user
48
+ - `sdk_key` is the SDK key for the Tailslide, it is used as a password for NATS JetStream token authentication
49
+ - `redis_host` is the address to the Redis database
50
+ - `redis_port` is the port number that the Redis database runs on
51
+
52
+ After instantiating a `FlagManager`, invoke the `initialize` method. This method connects the `FlagManager` instance to both NATS JetStream and Redis Timeseries, and asynchronously retrieves the latest and any new flag ruleset data.
53
+
54
+ ---
55
+
56
+ ### Using Feature Flag with Toggler
57
+
58
+ Once the `FlagManager` is initialized, it can create a `Toggler`, with the `new_toggler` method, for each feature flag that the developer wants to wrap the new and old features in. A `Toggler`’s `is_flag_active` method checks whether the flag with its `flag_name` is active or not based on the flag ruleset. A `Toggler`’s `is_flag_active` method returns a boolean value, which can be used to evaluate whether a new feature should be used or not.
59
+
60
+ ```ruby
61
+ flag_config = {
62
+ flag_name: 'App 1 Flag 1',
63
+ }
64
+
65
+ flag_toggler = manager.new_toggler(flag_config)
66
+
67
+ if flag_toggler.is_flag_active
68
+ # call new feature here
69
+ else
70
+ # call old feature here
71
+ end
72
+ ```
73
+
74
+ ---
75
+
76
+ ### Emitting Success or Failture
77
+
78
+ To use a `Toggler` instance to record successful or failed operations, call its `emit_success` or `emit_failure` methods:
10
79
 
11
80
  ```ruby
12
- gem 'tailslide'
81
+ if successCondition
82
+ flag_toggler.emit_success
83
+ else
84
+ flag_toggler.emit_failure
85
+ end
13
86
  ```
14
87
 
15
- And then execute:
88
+ ## Documentation
89
+
90
+ ---
91
+
92
+ ### FlagManager
93
+
94
+ The `FlagManager` class is the entry point of the SDK. A new `FlagManager` object will need to be created for each app.
95
+
96
+ #### FlagManager Constructor
97
+
98
+ **Parameters:**
99
+
100
+ - An object with the following keys
101
+ - `nats_server` is the NATS JetStream server `address:port`
102
+ - `nats_stream` is the NATS JetStream’s stream name that stores all the apps and their flag rulesets
103
+ - `app_id` a number representing the application the microservice belongs to
104
+ - `sdk_key` a string generated via the Tower front-end for NATS JetStream authentication
105
+ - `user_context` a string representing the user’s UUID
106
+ - `redis_host` a string that represents the url of the Redis server
107
+ - `redis_port` a number that represents the port number of the Redis server
108
+
109
+ ---
110
+
111
+ #### Instance Methods
112
+
113
+ ##### `flagmanager.initialize()`
114
+
115
+ Asynchronously initialize `flagmanager` connections to NATS JetStream and Redis database
116
+
117
+ **Parameters:**
118
+
119
+ - `nil`
120
+
121
+ **Return Value:**
122
+
123
+ - `nil`
124
+
125
+ ##### `flagmanaer.set_user_context(new_user_context)`
126
+
127
+ Set the current user's context for the `flagmanager`
128
+
129
+ **Parameters:**
130
+
131
+ - `new_user_context`: A UUID string that represents the current active user
132
+
133
+ **Return Value:**
134
+
135
+ - `nil`
136
+
137
+ ---
138
+
139
+ ##### `flagmanaer.get_user_context()`
140
+
141
+ Returns the current user context
142
+
143
+ **Parameters:**
144
+
145
+ - `nil`
146
+
147
+ **Return Value:**
148
+
149
+ - The UUID string that represents the current active user
150
+
151
+ ---
152
+
153
+ ##### `flagmanaer.new_toggler(options)`
154
+
155
+ Creates a new toggler to check for a feature flag's status from the current app's flag ruleset by the flag's name.
156
+
157
+ **Parameters:**
158
+
159
+ - `options`: An object with key of `flag_name` and a string value representing the name of the feature flag for the new toggler to check whether the new feature is enabled
160
+
161
+ **Return Value:**
162
+
163
+ - A `Toggler` object
164
+
165
+ ---
166
+
167
+ ##### `flagmanaer.disconnect()`
168
+
169
+ Asynchronously disconnects the `FlagManager` instance from NATS JetStream and Redis database
170
+
171
+ **Parameters:**
172
+
173
+ - `nil`
174
+
175
+ **Return Value:**
176
+
177
+ - `nil`
178
+
179
+ ---
180
+
181
+ ### Toggler
182
+
183
+ The Toggler class provides methods that determine whether or not new feature code is run and handles success/failure emissions. Each toggler handles one feature flag, and is created by `flagmanaer.new_toggler()`.
184
+
185
+ ---
186
+
187
+ #### Instance Methods
188
+
189
+ ##### `toggler.is_flag_active()`
190
+
191
+ Checks for flag status, whitelisted users, and rollout percentage in that order to determine whether the new feature is enabled.
192
+
193
+ - If the flag's active status is false, the function returns `false`
194
+ - If current user's UUID is in the whitelist of users, the function returns `true`
195
+ - If current user's UUID hashes to a value within user rollout percentage, the function returns `true`
196
+ - If current user's UUID hashes to a value outside user rollout percentage, the function returns `false`
197
+
198
+ **Parameters:**
199
+
200
+ - `nil`
201
+
202
+ **Return Value**
203
+
204
+ - `true` or `false` depending on whether the feature flag is active
16
205
 
17
- $ bundle install
206
+ ---
18
207
 
19
- Or install it yourself as:
208
+ ##### `toggler.emit_success()`
20
209
 
21
- $ gem install tailslide
210
+ Records a successful operation to the Redis Timeseries database, with key `flagId:success` and value of current timestamp
22
211
 
23
- ## Usage
212
+ **Parameters:**
24
213
 
25
- TODO: Write usage instructions here
214
+ - `nil`
26
215
 
27
- ## Development
216
+ **Return Value**
28
217
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
218
+ - `nil`
30
219
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
220
+ ---
32
221
 
33
- ## Contributing
222
+ ##### `toggler.emit_failure()`
34
223
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tailslide. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/tailslide/blob/main/CODE_OF_CONDUCT.md).
224
+ Records a failure operation to the Redis Timeseries database, with key `flagId:success` and value of current timestamp
36
225
 
37
- ## License
226
+ **Parameters:**
38
227
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
228
+ - `nil`
40
229
 
41
- ## Code of Conduct
230
+ **Return Value**
42
231
 
43
- Everyone interacting in the Tailslide project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/tailslide/blob/main/CODE_OF_CONDUCT.md).
232
+ - `nil`
@@ -2,40 +2,45 @@ require_relative 'nats_client'
2
2
  require_relative 'redis_timeseries_client'
3
3
  require_relative 'toggler'
4
4
 
5
- class FlagManger
6
- attr_reader :nats_client, :redis_ts_client, :user_context
5
+ class FlagManager
7
6
 
8
- def initialize(nats_server:'', stream:'', app_id:'', sdk_key:'', user_context:'', redis_host:'', redis_port:'')
9
- @nats_client = NatsClient.new(server_url: nats_server, stream:stream, subject:app_id, callback:method(:set_flags), token:sdk_key)
7
+ def initialize(nats_server: '', stream: '', app_id: '', sdk_key: '', user_context: '', redis_host: '', redis_port: '')
8
+ @nats_client = NatsClient.new(server_url: nats_server, stream: stream, subject: app_id, callback: method(:set_flags),
9
+ token: sdk_key)
10
10
  @redis_ts_client = RedisTimeSeriesClient.new(redis_host, redis_port)
11
11
  @user_context = user_context
12
12
  @flags = []
13
13
  end
14
-
14
+
15
15
  def initialize_flags
16
- nats_client.initialize_flags
17
- redis_ts_client.init
16
+ @nats_client.initialize_flags
17
+ @redis_ts_client.init
18
18
  end
19
-
19
+
20
20
  def set_flags(flags)
21
21
  @flags = flags
22
22
  end
23
-
23
+
24
24
  def get_flags
25
- return @flags
25
+ @flags
26
26
  end
27
27
 
28
- def disconnect
29
- nats_client.disconnect
30
- redis_ts_client.disconnect
28
+ def set_user_context(new_user_context)
29
+ @user_context = new_user_context
31
30
  end
32
31
 
33
- def new_toggler(config)
34
- p config
32
+ def get_user_context
33
+ @user_context
34
+ end
35
35
 
36
- return Toggler.new(**config, get_flags:method(:get_flags), user_context:user_context,
37
- emit_redis_signal:redis_ts_client.method(:emit_signal)
38
- )
36
+ def disconnect
37
+ @nats_client.disconnect
38
+ @redis_ts_client.disconnect
39
39
  end
40
-
41
- end
40
+
41
+ def new_toggler(config)
42
+ Toggler.new(**config, get_flags: method(:get_flags), user_context: get_user_context,
43
+ emit_redis_signal: @redis_ts_client.method(:emit_signal))
44
+ end
45
+ end
46
+
@@ -1,53 +1,50 @@
1
1
  require 'async'
2
- require "nats/client"
2
+ require 'nats/client'
3
3
  TimeoutError = NATS::IO::Timeout
4
4
  require 'json'
5
5
 
6
-
7
6
  class NatsClient
8
7
  attr_accessor :nats_connection, :jetstream, :subscribed_stream
9
8
  attr_reader :connection_string, :stream, :subject, :callback
10
- def initialize(server_url:'localhost:4222', stream:'', subject:'', callback:nil, token:'')
9
+
10
+ def initialize(server_url: 'localhost:4222', stream: '', subject: '', callback: nil, token: '')
11
11
  @stream = stream
12
- @subject = subject
12
+ @subject = format_subject(subject)
13
13
  @connection_string = "nats://#{token}#{'@' if token}#{server_url}"
14
14
  @callback = callback
15
15
  end
16
-
16
+
17
17
  def initialize_flags
18
- connect()
19
- fetch_latest_message()
20
- fetch_ongoing_event_messages()
18
+ connect
19
+ fetch_latest_message
20
+ fetch_ongoing_event_messages
21
21
  end
22
-
22
+
23
23
  private
24
+
24
25
  def connect
25
26
  self.nats_connection = NATS.connect(connection_string)
26
27
  self.jetstream = nats_connection.jetstream
27
28
  end
28
29
 
29
- def fetch_latest_message
30
- begin
31
- latest_msg = jetstream.get_last_msg(stream, subject)
32
- json_data = JSON.parse latest_msg.data
33
- callback.call(json_data)
34
- rescue NATS::Timeout => e
35
- end
30
+ def fetch_latest_message
31
+ latest_msg = jetstream.get_last_msg(stream, subject)
32
+ json_data = JSON.parse latest_msg.data
33
+ callback.call(json_data)
34
+ rescue NATS::Timeout => e
36
35
  end
37
36
 
38
37
  def fetch_ongoing_event_messages
39
- Async do |task|
38
+ Async do |_task|
40
39
  self.subscribed_stream = jetstream.pull_subscribe(subject, 'me', config: { deliver_policy: 'new' })
41
40
  begin
42
41
  messages = subscribed_stream.fetch(1)
43
42
  messages.each do |message|
44
43
  message.ack
45
44
  json_data = JSON.parse message.data
46
- p json_data
47
45
  callback.call(json_data)
48
46
  end
49
47
  rescue NATS::IO::Timeout => e
50
- p e
51
48
  end until nats_connection.closed?
52
49
  end
53
50
  end
@@ -55,4 +52,9 @@ class NatsClient
55
52
  def disconnect
56
53
  nats_connection.close
57
54
  end
58
- end
55
+
56
+ def format_subject(subject)
57
+ "apps.#{subject}.>"
58
+ end
59
+ end
60
+
@@ -1,21 +1,22 @@
1
-
2
1
  require 'redistimeseries'
3
2
  using Redistimeseries::RedisRefinement
4
3
 
5
4
  class RedisTimeSeriesClient
6
5
  attr_reader :host, :port
7
6
  attr_accessor :redis_client
7
+
8
8
  def initialize(host, port)
9
9
  @host = host || 'localhost'
10
10
  @port = port || 6379
11
11
  end
12
12
 
13
13
  def init
14
- self.redis_client = Redis.new(host:host, port:port)
14
+ self.redis_client = Redis.new(host: host, port: port)
15
15
  end
16
-
16
+
17
17
  def emit_signal(flag_id, app_id, status)
18
- redis_client.ts_add(key: "#{flag_id}:#{status}", timestamp:"*", value:1, labels:["status", status, "appId", app_id, "flagId", flag_id])
18
+ redis_client.ts_add(key: "#{flag_id}:#{status}", timestamp: '*', value: 1,
19
+ labels: ['status', status, 'appId', app_id, 'flagId', flag_id])
19
20
  end
21
+ end
20
22
 
21
- end
@@ -1,13 +1,11 @@
1
1
  require 'digest'
2
2
 
3
3
  class Toggler
4
- attr_reader :flag_name, :get_flags, :feature_cb, :default_cb, :error_condition, :emit_redis_signal, :user_context
4
+ attr_reader :flag_name, :get_flags, :emit_redis_signal, :user_context
5
5
  attr_accessor :app_id, :flag_id
6
- def initialize(flag_name:'', feature_cb:nil, default_cb:nil, error_condition:nil, get_flags:nil, emit_redis_signal:nil, user_context:'')
6
+
7
+ def initialize(flag_name: '', get_flags: nil, emit_redis_signal: nil, user_context: '')
7
8
  @flag_name = flag_name
8
- @feature_cb = feature_cb
9
- @default_cb = default_cb
10
- @error_condition = error_condition
11
9
  @get_flags = get_flags
12
10
  @flag_id = nil
13
11
  @app_id = nil
@@ -15,59 +13,62 @@ class Toggler
15
13
  @emit_redis_signal = emit_redis_signal
16
14
  @user_context = user_context
17
15
  end
18
-
16
+
19
17
  def is_flag_active
20
18
  flag = get_matching_flag
21
- flag["is_active"] && (is_user_white_listed(flag) || validate_user_rollout(flag))
19
+ flag['is_active'] && (is_user_white_listed(flag) || validate_user_rollout(flag))
22
20
  end
23
-
21
+
24
22
  def emit_success
25
23
  return unless flag_id
24
+
26
25
  p 'emiting success'
27
26
  emit_redis_signal.call(flag_id, app_id, 'success')
28
27
  end
29
28
 
30
29
  def emit_failure
31
30
  return unless flag_id
31
+
32
32
  emit_redis_signal.call(flag_id, app_id, 'failure')
33
33
  end
34
-
34
+
35
35
  private
36
+
36
37
  def get_matching_flag
37
- flag = get_flags.call.find { |flag| flag["title"] == flag_name}
38
- raise Exception.new "Cannot find flag with flag name of: #{flag_name}" unless flag
38
+ flag = get_flags.call.find { |flag| flag['title'] == flag_name }
39
+ raise Exception, "Cannot find flag with flag name of: #{flag_name}" unless flag
40
+
39
41
  flag
40
42
  end
41
-
42
- def set_flag_id_and_app_id(flag_name)
43
+
44
+ def set_flag_id_and_app_id(_flag_name)
43
45
  matching_flag = get_matching_flag
44
- self.flag_id = matching_flag["id"]
45
- self.app_id = matching_flag["app_id"]
46
+ self.flag_id = matching_flag['id']
47
+ self.app_id = matching_flag['app_id']
46
48
  end
47
-
49
+
48
50
  def is_user_white_listed(flag)
49
- flag["white_listed_users"].split(',').include?(user_context)
51
+ flag['white_listed_users'].split(',').include?(user_context)
50
52
  end
51
-
53
+
52
54
  def validate_user_rollout(flag)
53
- rollout = flag["rollout_percentage"] / 100.0
54
- if is_circuit_in_recovery(flag)
55
- rollout = rollout * (flag["circuit_recovery_percentage"] / 100.0)
56
- end
55
+ rollout = flag['rollout_percentage'] / 100.0
56
+ rollout *= (flag['circuit_recovery_percentage'] / 100.0) if is_circuit_in_recovery(flag)
57
57
  is_user_in_rollout(rollout)
58
58
  end
59
-
59
+
60
60
  def is_circuit_in_recovery(flag)
61
- flag["is_recoverable"] && flag["circuit_status"] == "recovery"
61
+ flag['is_recoverable'] && flag['circuit_status'] == 'recovery'
62
62
  end
63
-
63
+
64
64
  def is_user_in_rollout(rollout)
65
65
  puts "User context hash #{hash_user_context}"
66
66
  puts "Rollout: #{rollout}"
67
67
  hash_user_context <= rollout
68
68
  end
69
-
69
+
70
70
  def hash_user_context
71
- (Digest::MD5.hexdigest(user_context).to_i(base=16) % 100) / 100.0
71
+ (Digest::MD5.hexdigest(user_context).to_i(base = 16) % 100) / 100.0
72
72
  end
73
- end
73
+ end
74
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tailslide
4
- VERSION = "0.1.2"
4
+ VERSION = '0.1.5'
5
5
  end
data/lib/tailslide.rb CHANGED
@@ -4,7 +4,7 @@ require_relative "tailslide/version"
4
4
  require_relative "tailslide/flag_manager"
5
5
 
6
6
  module Tailslide
7
- class FlagManger < FlagManger
7
+ class FlagManager < FlagManager
8
8
  end
9
9
  # Your code goes here...
10
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tailslide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Liou
@@ -11,22 +11,64 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2022-07-24 00:00:00.000000000 Z
14
+ date: 2022-08-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: "[]"
17
+ name: async
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
- - - ">="
20
+ - - "~>"
21
21
  - !ruby/object:Gem::Version
22
- version: '0'
22
+ version: 2.0.3
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ">="
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: 2.0.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: nats-pure
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: 2.1.0
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: 2.1.0
44
+ - !ruby/object:Gem::Dependency
45
+ name: redis
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: 4.7.1
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: 4.7.1
58
+ - !ruby/object:Gem::Dependency
59
+ name: redistimeseries
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: 0.1.2
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: 0.1.2
30
72
  description: " Write a longer description or delete this line."
31
73
  email:
32
74
  - stevenliou@gmail.com
@@ -37,8 +79,6 @@ executables: []
37
79
  extensions: []
38
80
  extra_rdoc_files: []
39
81
  files:
40
- - ".vscode/launch.json"
41
- - ".vscode/settings.json"
42
82
  - CHANGELOG.md
43
83
  - CODE_OF_CONDUCT.md
44
84
  - Gemfile
@@ -51,10 +91,7 @@ files:
51
91
  - lib/tailslide/redis_timeseries_client.rb
52
92
  - lib/tailslide/toggler.rb
53
93
  - lib/tailslide/version.rb
54
- - redis_test.rb
55
94
  - sig/tailslide.rbs
56
- - tailslide-0.1.0.gem
57
- - test.rb
58
95
  homepage: https://github.com/tailslide-io/tailslide.rb
59
96
  licenses:
60
97
  - MIT
data/.vscode/launch.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "name": "Debug Local File",
9
- "type": "Ruby",
10
- "request": "launch",
11
- "program": "./test.rb"
12
- }
13
- ]
14
- }
@@ -1,10 +0,0 @@
1
- {
2
- "workbench.colorCustomizations": {
3
- "sash.hoverBorder": "#3b3b3b",
4
- "titleBar.activeBackground": "#222222",
5
- "titleBar.activeForeground": "#e7e7e7",
6
- "titleBar.inactiveBackground": "#22222299",
7
- "titleBar.inactiveForeground": "#e7e7e799"
8
- },
9
- "editor.acceptSuggestionOnEnter": "on"
10
- }
data/redis_test.rb DELETED
@@ -1,8 +0,0 @@
1
- require 'redistimeseries'
2
- using Redistimeseries::RedisRefinement
3
-
4
- app_id = 1
5
- flag_id = 1
6
- status = 'success'
7
- redis_client = Redis.new(host:'localhost', port: 6379)
8
- redis_client.ts_add(key: "#{flag_id}:#{status}", timestamp:"*", value:1, labels:["status", status, "appId", app_id, "flagId", flag_id])
data/tailslide-0.1.0.gem DELETED
Binary file
data/test.rb DELETED
@@ -1,129 +0,0 @@
1
- require "async"
2
- # require "./lib/tailslide/nats_client.rb"
3
- require_relative "lib/tailslide/flag_manager.rb"
4
- require_relative 'lib/tailslide/toggler'
5
-
6
- # def logMessage(message)
7
- # p message
8
- # end
9
-
10
- # config = {server_url: "localhost:4222", callback: :p, token: 'myToken', stream:"flags", subject:'1'}
11
- app_id = "1"
12
- flag_name = 'Flag in app 1 number 1'
13
- flag_config = {"flag_name": flag_name}
14
-
15
- config = {nats_server:'localhost:4222', stream:'flags', app_id:app_id, sdk_key:'myToken', user_context:'375d39e6-9c3f-4f58-80bd-e5960b710295',
16
- redis_host:'localhost', redis_port:6379}
17
-
18
-
19
- Async do |task|
20
- manager = FlagManger.new(**config)
21
- manager.initialize_flags
22
- flag_toggler = manager.new_toggler(flag_config)
23
-
24
-
25
- if flag_toggler.is_flag_active
26
- puts "Flag in #{app_id} with name \"#{flag_name}\" is active!"
27
- flag_toggler.emit_success()
28
- else
29
- puts "Flag in #{app_id} with name \"#{flag_name}\" is not active!"
30
- flag_toggler.emit_failure()
31
- end
32
- sleep 5
33
-
34
- if flag_toggler.is_flag_active
35
- puts "Flag in #{app_id} with name \"#{flag_name}\" is active!"
36
- flag_toggler.emit_success()
37
- else
38
- puts "Flag in #{app_id} with name \"#{flag_name}\" is not active!"
39
- flag_toggler.emit_failure()
40
- end
41
- end
42
-
43
-
44
- # require "nats/client"
45
- # require "async"
46
- # TimeoutError = NATS::IO::Timeout
47
- # require 'json'
48
-
49
- # token = "myToken"
50
-
51
- # nats_client = NATS.connect("nats://#{token}@127.0.0.1:4222")
52
- # jet_stream = nats_client.jetstream
53
-
54
- # # get last message
55
- # latest_msg = jet_stream.get_last_msg("flags", "test")
56
- # json_data = JSON.parse latest_msg.data
57
- # p json_data
58
-
59
-
60
- # # pull subscribe for new onging messages (workaround until Nats.rb make new update)
61
- # subscribed_stream = jet_stream.pull_subscribe("test", 'mydurable', config: { deliver_policy: 'new' })
62
- # Async do |task|
63
- # task.async do
64
- # begin
65
- # messages = subscribed_stream.fetch(1)
66
- # messages.each do |message|
67
- # message.ack
68
- # json_data = JSON.parse message.data
69
- # p json_data
70
- # end
71
- # rescue NATS::Timeout => e
72
- # p e
73
- # end until nats_client.closed?
74
- # end
75
- # p "hello past async"
76
- # end
77
-
78
-
79
-
80
- # push subscribe for new ongoing messages
81
- # setting deliver_policy still results in delivering all messages in "test" subject
82
- # push_sub = jetStream.subscribe("test", {manual_ack: true, deliver_policy:"new"} ) do |msg|
83
- # msg.ack
84
- # puts msg.data
85
- # end
86
-
87
- # Get ongoing messages
88
- # Push subscribe
89
- # consumer_req = {
90
- # stream_name: "test",
91
- # config: {
92
- # durable_name: "sample",
93
- # deliver_policy: "new",
94
- # ack_policy: "explicit",
95
- # max_deliver: -1,
96
- # replay_policy: "instant"
97
- # }
98
- # }
99
-
100
- # config = NATS::JetStream::API::ConsumerConfig.new({ deliver_policy: "new" })
101
- # Create inbox for push consumer.
102
- # deliver = natsClient.new_inbox
103
- # config.deliver_subject = deliver
104
-
105
- # push_sub = jetStream.subscribe("test", {manual_ack: true, deliver_policy:"new"} ) do |msg|
106
- # puts msg.data
107
- # end
108
-
109
- # cinfo = push_sub.consumer_info["config"]
110
- # puts cinfo
111
- # msg = push_sub.next_msg(timeout: 10000000000)
112
- # msg.ack
113
- # puts msg.data
114
- # push_sub.consumer_info["config"]["deliver_policy"] = "new"
115
- # puts cinfo
116
-
117
- # loop do
118
- # msgs = push_sub.next_msg()
119
- # puts msgs.data
120
- # rescue TimeoutError => e
121
- # puts e
122
- # sleep 1
123
- # end
124
-
125
- # js.publish("9", "Hello JetStream! 1")
126
- # js.publish("9", "Hello JetStream! 2")
127
- # js.publish("9", "Hello JetStream! 3")
128
- # js.publish("9", "Hello JetStream! 4")
129
- # js.publish("9", "Hello JetStream! Latest")