tailslide 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.vscode/settings.json +2 -1
- data/Gemfile +8 -9
- data/README.md +192 -20
- data/lib/tailslide/flag_manager.rb +25 -20
- data/lib/tailslide/nats_client.rb +22 -20
- data/lib/tailslide/redis_timeseries_client.rb +6 -5
- data/lib/tailslide/toggler.rb +29 -28
- data/lib/tailslide/version.rb +1 -1
- data/lib/tailslide.rb +1 -1
- data/tailslide-0.1.3.gem +0 -0
- data/test.rb +15 -12
- metadata +3 -4
- data/redis_test.rb +0 -8
- data/tailslide-0.1.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d317d72da4b918e8c57feaf8072884cbc8ecdcb10ab3e49eefc9a392cb7a71ce
|
4
|
+
data.tar.gz: 4edf3d36bf65775916ed49d79ff8c28bd128c91c630bde5b21091353df495d2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 796bfd026bb228dd49a089a8ed87b8785bc21e7e667e2b6c4f3237a0b3e4de41f3ace73be4efb3b9161baf2c187abb66a74a7f21f8f76c906fef554b1d230659
|
7
|
+
data.tar.gz: 41884a753fed4a3e7c77773ef76059f3cdb1ccd9e63b56cd5efa5ab040590d1726cd1862153ef0eed06eb342d19e5b61868f50a6c2fc17a2c5ef6b6776fc1345
|
data/.vscode/settings.json
CHANGED
@@ -4,7 +4,8 @@
|
|
4
4
|
"titleBar.activeBackground": "#222222",
|
5
5
|
"titleBar.activeForeground": "#e7e7e7",
|
6
6
|
"titleBar.inactiveBackground": "#22222299",
|
7
|
-
"titleBar.inactiveForeground": "#e7e7e799"
|
7
|
+
"titleBar.inactiveForeground": "#e7e7e799",
|
8
|
+
"commandCenter.border": "#e7e7e799"
|
8
9
|
},
|
9
10
|
"editor.acceptSuggestionOnEnter": "on"
|
10
11
|
}
|
data/Gemfile
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
source
|
3
|
+
source 'https://rubygems.org'
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in tailslide.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem
|
9
|
-
gem
|
10
|
-
gem
|
11
|
-
gem
|
12
|
-
gem
|
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
|
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,215 @@
|
|
1
|
-
# Tailslide
|
1
|
+
# Ruby SDK for Tailslide
|
2
2
|
|
3
|
-
|
3
|
+
---
|
4
4
|
|
5
|
-
|
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
|
-
|
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 is intended to be used to control branching logic flow within an application at runtime, to invoke new features.
|
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 the `Toggler` instances to record successful or failed operations, call its `emit_success` or `emit_failure` methods:
|
10
79
|
|
11
80
|
```ruby
|
12
|
-
|
81
|
+
if successCondition
|
82
|
+
flag_toggler.emit_success
|
83
|
+
else
|
84
|
+
flag_toggler.emit_failure
|
85
|
+
end
|
13
86
|
```
|
14
87
|
|
15
|
-
|
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
|
+
- `server` a string that represents the URL and port of the NATS server.
|
102
|
+
- `app_id` a number representing the application the microservice belongs to
|
103
|
+
- `sdk_key` a string generated via the Tower front-end for NATS JetStream authentication
|
104
|
+
- `user_context` a string representing the user’s UUID
|
105
|
+
- `redis_host` a string that represents the url of the Redis server
|
106
|
+
- `redis_port` a number that represents the port number of the Redis server
|
107
|
+
|
108
|
+
---
|
109
|
+
|
110
|
+
#### Instance Methods
|
111
|
+
|
112
|
+
##### `FlagManager.prototype.set_user_context(new_user_context)`
|
113
|
+
|
114
|
+
**Parameters:**
|
115
|
+
|
116
|
+
- A UUID string that represents the current active user
|
117
|
+
|
118
|
+
**Return Value:**
|
119
|
+
|
120
|
+
- `null`
|
121
|
+
|
122
|
+
---
|
123
|
+
|
124
|
+
##### `FlagManager.prototype.get_user_context()`
|
125
|
+
|
126
|
+
**Parameters:**
|
127
|
+
|
128
|
+
- `null`
|
129
|
+
|
130
|
+
**Return Value:**
|
131
|
+
|
132
|
+
- The UUID string that represents the current active user
|
133
|
+
|
134
|
+
---
|
135
|
+
|
136
|
+
##### `FlagManager.prototype.new_toggler(options)`
|
137
|
+
|
138
|
+
Creates a new toggler to check for a feature flag's status from the current app's flag ruleset by the flag's name.
|
139
|
+
|
140
|
+
**Parameters:**
|
141
|
+
|
142
|
+
- 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
|
143
|
+
|
144
|
+
**Return Value:**
|
145
|
+
|
146
|
+
- A `Toggler` object
|
147
|
+
|
148
|
+
---
|
149
|
+
|
150
|
+
##### `FlagManager.prototype.disconnect()`
|
151
|
+
|
152
|
+
Asynchronously disconnects the `FlagManager` instance from NATS JetStream and Redis database
|
153
|
+
|
154
|
+
**Parameters:**
|
155
|
+
|
156
|
+
- `null`
|
157
|
+
|
158
|
+
**Return Value:**
|
159
|
+
|
160
|
+
- `null`
|
161
|
+
|
162
|
+
---
|
163
|
+
|
164
|
+
### Toggler
|
165
|
+
|
166
|
+
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 `FlagManager.prototype.new_toggler()`.
|
167
|
+
|
168
|
+
---
|
169
|
+
|
170
|
+
#### Instance Methods
|
171
|
+
|
172
|
+
##### `is_flag_active()`
|
173
|
+
|
174
|
+
Checks for flag status, whitelisted users, and rollout percentage in that order to determine whether the new feature is enabled.
|
175
|
+
|
176
|
+
- If the flag's active status is false, the function returns `false`
|
177
|
+
- If current user's UUID is in the whitelist of users, the function returns `true`
|
178
|
+
- If current user's UUID hashes to a value within user rollout percentage, the function returns `true`
|
179
|
+
- If current user's UUID hashes to a value outside user rollout percentage, the function returns `false`
|
180
|
+
|
181
|
+
**Parameters:**
|
182
|
+
|
183
|
+
- `null`
|
184
|
+
|
185
|
+
**Return Value**
|
186
|
+
|
187
|
+
- `true` or `flase` depending on whether the feature flag is active
|
16
188
|
|
17
|
-
|
189
|
+
---
|
18
190
|
|
19
|
-
|
191
|
+
##### `emit_success()`
|
20
192
|
|
21
|
-
|
193
|
+
Records a successful operation to the Redis Timeseries database, with key `flagId:success` and value of current timestamp
|
22
194
|
|
23
|
-
|
195
|
+
**Parameters:**
|
24
196
|
|
25
|
-
|
197
|
+
- `null`
|
26
198
|
|
27
|
-
|
199
|
+
**Return Value**
|
28
200
|
|
29
|
-
|
201
|
+
- `null`
|
30
202
|
|
31
|
-
|
203
|
+
---
|
32
204
|
|
33
|
-
|
205
|
+
##### `emit_failure()`
|
34
206
|
|
35
|
-
|
207
|
+
Records a failure operation to the Redis Timeseries database, with key `flagId:success` and value of current timestamp
|
36
208
|
|
37
|
-
|
209
|
+
**Parameters:**
|
38
210
|
|
39
|
-
|
211
|
+
- `null`
|
40
212
|
|
41
|
-
|
213
|
+
**Return Value**
|
42
214
|
|
43
|
-
|
215
|
+
- `null`
|
@@ -2,40 +2,45 @@ require_relative 'nats_client'
|
|
2
2
|
require_relative 'redis_timeseries_client'
|
3
3
|
require_relative 'toggler'
|
4
4
|
|
5
|
-
class
|
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),
|
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
|
-
|
25
|
+
@flags
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
|
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
|
34
|
-
|
32
|
+
def get_user_context
|
33
|
+
@user_context
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def disconnect
|
37
|
+
@nats_client.disconnect
|
38
|
+
@redis_ts_client.disconnect
|
39
39
|
end
|
40
|
-
|
41
|
-
|
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
|
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
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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 |
|
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
|
-
|
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:
|
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
|
data/lib/tailslide/toggler.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'digest'
|
2
2
|
|
3
3
|
class Toggler
|
4
|
-
attr_reader :flag_name, :get_flags, :
|
4
|
+
attr_reader :flag_name, :get_flags, :emit_redis_signal, :user_context
|
5
5
|
attr_accessor :app_id, :flag_id
|
6
|
-
|
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[
|
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[
|
38
|
-
raise Exception
|
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(
|
43
|
+
|
44
|
+
def set_flag_id_and_app_id(_flag_name)
|
43
45
|
matching_flag = get_matching_flag
|
44
|
-
self.flag_id = matching_flag[
|
45
|
-
self.app_id = matching_flag[
|
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[
|
51
|
+
flag['white_listed_users'].split(',').include?(user_context)
|
50
52
|
end
|
51
|
-
|
53
|
+
|
52
54
|
def validate_user_rollout(flag)
|
53
|
-
rollout = flag[
|
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[
|
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
|
+
|
data/lib/tailslide/version.rb
CHANGED
data/lib/tailslide.rb
CHANGED
data/tailslide-0.1.3.gem
ADDED
Binary file
|
data/test.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require "async"
|
2
2
|
# require "./lib/tailslide/nats_client.rb"
|
3
3
|
require_relative "lib/tailslide/flag_manager.rb"
|
4
|
-
require_relative 'lib/tailslide/toggler'
|
5
4
|
|
6
5
|
# def logMessage(message)
|
7
6
|
# p message
|
@@ -9,15 +8,15 @@ require_relative 'lib/tailslide/toggler'
|
|
9
8
|
|
10
9
|
# config = {server_url: "localhost:4222", callback: :p, token: 'myToken', stream:"flags", subject:'1'}
|
11
10
|
app_id = "1"
|
12
|
-
flag_name = '
|
11
|
+
flag_name = 'App 1 Flag 1'
|
13
12
|
flag_config = {"flag_name": flag_name}
|
14
13
|
|
15
|
-
config = {nats_server:'localhost:4222', stream:'
|
14
|
+
config = {nats_server:'localhost:4222', stream:'flags_ruleset', app_id:app_id, sdk_key:'myToken', user_context:'375d39e6-9c3f-4f58-80bd-e5960b710295',
|
16
15
|
redis_host:'localhost', redis_port:6379}
|
17
16
|
|
18
17
|
|
19
18
|
Async do |task|
|
20
|
-
manager =
|
19
|
+
manager = FlagManager.new(**config)
|
21
20
|
manager.initialize_flags
|
22
21
|
flag_toggler = manager.new_toggler(flag_config)
|
23
22
|
|
@@ -29,14 +28,18 @@ Async do |task|
|
|
29
28
|
puts "Flag in #{app_id} with name \"#{flag_name}\" is not active!"
|
30
29
|
flag_toggler.emit_failure()
|
31
30
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
|
32
|
+
count = 0
|
33
|
+
limit = 20
|
34
|
+
while count < limit do
|
35
|
+
if rand < 1
|
36
|
+
flag_toggler.emit_success
|
37
|
+
puts "Emitting success"
|
38
|
+
else
|
39
|
+
flag_toggler.emit_failure
|
40
|
+
puts "Emitting failure"
|
41
|
+
end
|
42
|
+
sleep 1
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
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.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Liou
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2022-
|
14
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: async
|
@@ -93,9 +93,8 @@ files:
|
|
93
93
|
- lib/tailslide/redis_timeseries_client.rb
|
94
94
|
- lib/tailslide/toggler.rb
|
95
95
|
- lib/tailslide/version.rb
|
96
|
-
- redis_test.rb
|
97
96
|
- sig/tailslide.rbs
|
98
|
-
- tailslide-0.1.
|
97
|
+
- tailslide-0.1.3.gem
|
99
98
|
- test.rb
|
100
99
|
homepage: https://github.com/tailslide-io/tailslide.rb
|
101
100
|
licenses:
|
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
|