nchan_tools 0.1.11 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/nchan-redis-debug +15 -5
- data/lib/nchan_tools/rdsck.rb +123 -3
- data/lib/nchan_tools/version.rb +1 -1
- data/nchan_tools.gemspec +2 -0
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c506959c2eba296db96ed5e1598412798117f4e33bae4a909e223148a829b4a
|
4
|
+
data.tar.gz: 4f178a9eac6fa954d06b5f9f4d6d21cb5c3e6320390e3f422fdcb0589e5276d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 183363cebe229289e9c3eb0c0989a2816b7bb06c2f3650a81fdad8b5a22c1a2502bd182081a49bbcdf076d0eef219f0ae8f3ccff6a31252e8a137d1940347231
|
7
|
+
data.tar.gz: e5c09c1e6759dd835fb9699a96e63e6d2bbb7ae7adefac324cae19083f0921d3699fc88bdeb54dde4810153ed9cf528d22f9829688c8f9a02fb2f547f507debf
|
data/exe/nchan-redis-debug
CHANGED
@@ -15,14 +15,19 @@ opt_parser=OptionParser.new do |opts|
|
|
15
15
|
opt[:url]=v
|
16
16
|
end
|
17
17
|
opts.on("-q", "--quiet", "output only results without any other information") do
|
18
|
-
opt[:quiet]=
|
19
|
-
opts[:verbose] = !opt[:quiet]
|
18
|
+
opt[:quiet]=true
|
20
19
|
end
|
21
20
|
opts.on("--list-channels", "list all Nchan channels on Redis server or cluster") do |v|
|
22
21
|
opt[:command]=:filter_channels
|
23
22
|
end
|
23
|
+
opts.on("--watch-channels", "watch for changes in Nchan channels on Redis server or cluster") do |v|
|
24
|
+
opt[:command]=:watch_channels
|
25
|
+
end
|
26
|
+
opts.on("--set-notify-keyspace-events", "when using --watch-channels, sets the notify-keyspace-events Redis config before starting. May not be possible if the redis 'config' command is disabled") do
|
27
|
+
opt[:set_notify_keyspace_events] = true
|
28
|
+
end
|
24
29
|
opts.on("--filter-channels-min-subscribers=[NUMBER]") do |v|
|
25
|
-
opt[:command]
|
30
|
+
opt[:command]||=:filter_channels
|
26
31
|
opt[:min_subscribers]=v.to_i
|
27
32
|
end
|
28
33
|
end
|
@@ -40,6 +45,8 @@ opt_parser.banner= <<~EOB
|
|
40
45
|
EOB
|
41
46
|
opt_parser.parse!
|
42
47
|
|
48
|
+
opt[:verbose] = !opt[:quiet]
|
49
|
+
|
43
50
|
rdsck = Rdsck.new opt
|
44
51
|
if not rdsck.connect
|
45
52
|
STDERR.puts "failed to connect to #{opt[:url]}"
|
@@ -48,10 +55,13 @@ end
|
|
48
55
|
|
49
56
|
case opt[:command]
|
50
57
|
when :filter_channels
|
51
|
-
|
58
|
+
rdsck.dbg "scanning for channels #{opt[:min_subscribers] && "with subscribers >= #{opt[:min_subscribers]}"}"
|
52
59
|
chans = rdsck.filter_channels(min_subscribers: opt[:min_subscribers])
|
53
|
-
|
60
|
+
rdsck.dbg "found #{chans.count} channel#{chans.count != 1 && "s"}#{chans.count == 0 ? "." : ":"}"
|
54
61
|
puts chans.join("\n")
|
62
|
+
when :watch_channels
|
63
|
+
rdsck.dbg "watching for channels #{opt[:min_subscribers] && "with subscribers >= #{opt[:min_subscribers]}"}"
|
64
|
+
rdsck.watch_channels({min_subscribers: opt[:min_subscribers]}, opt[:set_notify_keyspace_events])
|
55
65
|
else
|
56
66
|
puts "Nothing to do"
|
57
67
|
end
|
data/lib/nchan_tools/rdsck.rb
CHANGED
@@ -1,4 +1,40 @@
|
|
1
1
|
class Rdsck
|
2
|
+
require "async"
|
3
|
+
require "async/redis"
|
4
|
+
|
5
|
+
#doesn't support psubscribe by default. can you believe it?!
|
6
|
+
class Async::Redis::Context::Psubscribe < Async::Redis::Context::Subscribe
|
7
|
+
MESSAGE = 'pmessage'
|
8
|
+
|
9
|
+
def listen
|
10
|
+
while response = @connection.read_response
|
11
|
+
return response if response.first == MESSAGE
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def subscribe(channels)
|
16
|
+
@connection.write_request ['PSUBSCRIBE', *channels]
|
17
|
+
@connection.flush
|
18
|
+
end
|
19
|
+
|
20
|
+
def unsubscribe(channels)
|
21
|
+
@connection.write_request ['PUNSUBSCRIBE', *channels]
|
22
|
+
@connection.flush
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Async::Redis::Client
|
27
|
+
def psubscribe(*channels)
|
28
|
+
context = Async::Redis::Context::Psubscribe.new(@pool, channels)
|
29
|
+
return context unless block_given?
|
30
|
+
begin
|
31
|
+
yield context
|
32
|
+
ensure
|
33
|
+
context.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
2
38
|
attr_accessor :url, :verbose, :namespace
|
3
39
|
attr_accessor :redis, :masters
|
4
40
|
|
@@ -22,9 +58,10 @@ class Rdsck
|
|
22
58
|
|
23
59
|
def connect
|
24
60
|
begin
|
25
|
-
puts "connect to #{@url}"
|
26
61
|
@redis=Redis.new url: @url
|
62
|
+
|
27
63
|
mode = redis.info["redis_mode"]
|
64
|
+
|
28
65
|
rescue StandardError => e
|
29
66
|
STDERR.puts e.message
|
30
67
|
return false
|
@@ -33,7 +70,6 @@ class Rdsck
|
|
33
70
|
if mode == "cluster"
|
34
71
|
@redis.close
|
35
72
|
begin
|
36
|
-
puts "cluster-connect to #{@url}"
|
37
73
|
@redis=Redis.new cluster: [@url]
|
38
74
|
@redis.ping
|
39
75
|
rescue StandardError => e
|
@@ -71,6 +107,90 @@ class Rdsck
|
|
71
107
|
#...
|
72
108
|
end
|
73
109
|
|
110
|
+
class Watch
|
111
|
+
def initialize(rdsck, node, filters, set_notify_config = nil)
|
112
|
+
@rdsck = rdsck
|
113
|
+
@sync = node
|
114
|
+
@filters = filters
|
115
|
+
@set_notify_config = set_notify_config
|
116
|
+
@host, @port, @location = @sync.connection[:host], @sync.connection[:port]
|
117
|
+
@url = @sync.connection[:id]
|
118
|
+
@async = Async::Redis::Client.new(Async::IO::Endpoint.tcp(@host, @port))
|
119
|
+
if set_notify_config
|
120
|
+
@rdsck.dbg "set #{@url} notify-keyspace-events to \"Kh\""
|
121
|
+
@prev_notify_keyspace_event_config = @sync.config("get", "notify-keyspace-events")
|
122
|
+
@prev_notify_keyspace_event_config = @prev_notify_keyspace_event_config[1] if @prev_notify_keyspace_event_config
|
123
|
+
|
124
|
+
@sync.config :set, "notify-keyspace-events", "Kh"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def watch(task)
|
129
|
+
task.async do
|
130
|
+
#puts "subscribeme"
|
131
|
+
while true do
|
132
|
+
@async.psubscribe "__keyspace*__:{channel:*}" do |ctx|
|
133
|
+
type, pattern, name, msg = ctx.listen
|
134
|
+
#puts "TYPE: #{type}, PAT:#{pattern}, NAME:#{name}, MSG:#{msg}"
|
135
|
+
m=name.match(/^__.*__:(\{.*\})/)
|
136
|
+
if m && m[1]
|
137
|
+
key = m[1]
|
138
|
+
|
139
|
+
filtered = false
|
140
|
+
subs = nil
|
141
|
+
|
142
|
+
if @filters[:min_subscribers]
|
143
|
+
subs = @sync.hget key, "fake_subscribers"
|
144
|
+
subs = subs.to_i
|
145
|
+
filtered = true if subs < @filters[:min_subscribers]
|
146
|
+
end
|
147
|
+
|
148
|
+
if !filtered
|
149
|
+
if subs
|
150
|
+
puts "#{key} subscribers: #{subs}"
|
151
|
+
else
|
152
|
+
puts "#{key}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def stop
|
163
|
+
@async.close
|
164
|
+
if @set_notify_config
|
165
|
+
@rdsck.dbg "set #{@url} notify-keyspace-events back to #{@prev_notify_keyspace_event_config}"
|
166
|
+
@sync.config(:set, "notify-keyspace-events", @prev_notify_keyspace_event_config)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def watch_channels(filters={}, set_notify_keyspace_events=nil)
|
172
|
+
watchers = []
|
173
|
+
@masters.each do |m|
|
174
|
+
watchers << Watch.new(self, m, filters, set_notify_keyspace_events)
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
begin
|
179
|
+
Async do |task|
|
180
|
+
watchers.each do |watcher|
|
181
|
+
watcher.watch(task)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
rescue Interrupt => e
|
185
|
+
dbg "stopping watch"
|
186
|
+
ensure
|
187
|
+
watchers.each do |watcher|
|
188
|
+
watcher.stop
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
74
194
|
def filter_channels(filters={})
|
75
195
|
script = <<~EOF
|
76
196
|
local prev_cursor = ARGV[1]
|
@@ -102,7 +222,7 @@ class Rdsck
|
|
102
222
|
|
103
223
|
results = []
|
104
224
|
batch_size=500
|
105
|
-
masters.each do |m|
|
225
|
+
@masters.each do |m|
|
106
226
|
hash = m.script "load", script
|
107
227
|
cursor, pattern = "0", "{channel:*}"
|
108
228
|
loop do
|
data/lib/nchan_tools/version.rb
CHANGED
data/nchan_tools.gemspec
CHANGED
@@ -30,6 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency "celluloid-io"
|
31
31
|
spec.add_dependency "HDRHistogram"
|
32
32
|
spec.add_dependency "redis", "~>4.2.0"
|
33
|
+
spec.add_dependency "async"
|
34
|
+
spec.add_dependency "async-redis"
|
33
35
|
|
34
36
|
spec.add_dependency "websocket-driver"
|
35
37
|
spec.add_dependency 'websocket-extensions'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nchan_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leo Ponomarev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|
@@ -108,6 +108,34 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 4.2.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: async
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: async-redis
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
111
139
|
- !ruby/object:Gem::Dependency
|
112
140
|
name: websocket-driver
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,7 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
296
|
- !ruby/object:Gem::Version
|
269
297
|
version: '0'
|
270
298
|
requirements: []
|
271
|
-
rubygems_version: 3.
|
299
|
+
rubygems_version: 3.2.7
|
272
300
|
signing_key:
|
273
301
|
specification_version: 4
|
274
302
|
summary: Development and testing utilities for Nchan
|