dalli-keys-match 0.2.0
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +5 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/dalli-keys-match.gemspec +29 -0
- data/lib/dalli-keys-match.rb +2 -0
- data/lib/dalli/keys_match.rb +82 -0
- data/lib/dalli/keys_match/configuration.rb +18 -0
- data/lib/dalli/keys_match/version.rb +6 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2b6875a0ca5dc289edfd2ee3a9000a2ac338558b
|
4
|
+
data.tar.gz: a89d71e02345a54730ff8d939f718ffe8320b626
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 312ed9714d7ad958fba934410622a0702048b2e455948041235d4e32d25549e4f4aa2aba24c3f8a14666b034371275f100b257507fa28f34797f17eeee857116
|
7
|
+
data.tar.gz: 6bcd5241247222d179a2c3113a6f52a7ad7733a9994ec682edc8aa497af6bb3f0f8c54f94a38470e02162ba75ec24e1df611c4fd89581573fa4c6927df321c2e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Dalli KeysMatch
|
2
|
+
|
3
|
+
This gem add to the [Dalli::Client](https://github.com/petergoldstein/dalli) methods to list/filter/delete keys using regexp or string patterns.
|
4
|
+
|
5
|
+
IMPORTANT: It's not recommended to use in production. Memcached binary protocol does not implement `stats cachedump` command. We are using telnet as workaround. And I recommend using it in the development environment or background jobs.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'dalli-keys-match'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install dalli-keys-match
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
```
|
25
|
+
require 'dalli/keys_match'
|
26
|
+
|
27
|
+
> client = Dalli::Client.new('localhost:11211')
|
28
|
+
=> #<Dalli::Client:0x007fcb14afe830 @servers=["localhost:11211"], @options={}, @ring=nil>
|
29
|
+
> client.set('dalli-keys-match-1' , 1)
|
30
|
+
=> 10163216984091656192
|
31
|
+
> client.set('dalli-keys-match-2' , 2)
|
32
|
+
=> 10235274578129584128
|
33
|
+
> client.keys(/dalli-keys-match-\d/)
|
34
|
+
=> ["dalli-keys-match-2", "dalli-keys-match-1"]
|
35
|
+
> client.keys('dalli-keys-match-')
|
36
|
+
=> ["dalli-keys-match-2", "dalli-keys-match-1"]
|
37
|
+
> client.delete_matched(/dalli-keys-match-1/)
|
38
|
+
=> 1
|
39
|
+
> client.keys(/dalli-keys-match-\d/)
|
40
|
+
=> ["dalli-keys-match-2"]
|
41
|
+
```
|
42
|
+
|
43
|
+
### Optional Configuration
|
44
|
+
```
|
45
|
+
Dalli::KeysMatch.config.telnet = {
|
46
|
+
'Timeout' => 30,
|
47
|
+
'Prompt' => /(^END$)/,
|
48
|
+
}
|
49
|
+
```
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/marcosgz/dalli-keys-match.
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dalli/keys_match/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'dalli-keys-match'
|
8
|
+
spec.version = Dalli::KeysMatch::VERSION
|
9
|
+
spec.authors = ['Marcos G. Zimmermann']
|
10
|
+
spec.email = ['marcos@marcosz.com.br']
|
11
|
+
spec.license = 'MIT'
|
12
|
+
|
13
|
+
spec.summary = %q{Dalli::KeysMatch extends Dalli with functions to deal with keys}
|
14
|
+
spec.description = %q{Dalli::KeysMatch extends Dalli with a function that allow you to list or remove keys using optional filters}
|
15
|
+
spec.homepage = 'https://github.com/marcosgz/dalli-keys-match'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_runtime_dependency 'net-telnet', '~> 0.1.1'
|
25
|
+
spec.add_runtime_dependency 'dalli', '>= 1.0.0'
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.15'
|
27
|
+
spec.add_development_dependency 'rake', '~> 12.1', '>= 12.1.0'
|
28
|
+
spec.add_development_dependency 'rspec', '~> 3.6'
|
29
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'net/telnet'
|
3
|
+
require 'dalli'
|
4
|
+
require 'dalli/keys_match/configuration'
|
5
|
+
require 'dalli/keys_match/version'
|
6
|
+
|
7
|
+
module Dalli
|
8
|
+
module KeysMatch
|
9
|
+
|
10
|
+
def config
|
11
|
+
@config ||= Configuration.new
|
12
|
+
end
|
13
|
+
module_function :config
|
14
|
+
|
15
|
+
module Server
|
16
|
+
# Memcached does not implement binary protocol for cachedump key. Using telnet as workaround
|
17
|
+
# https://github.com/memcached/memcached/wiki/BinaryProtocolRevamped#stat
|
18
|
+
def stats_cachedump(id, size, pattern = nil)
|
19
|
+
[].tap do |keys|
|
20
|
+
telnet.cmd("String" => "stats cachedump #{id} #{size}").split("\n").each do |line|
|
21
|
+
if /ITEM (.+) \[\d+ b; \d+ s\]/ =~ line
|
22
|
+
case pattern.class.name
|
23
|
+
when 'NilClass'
|
24
|
+
keys << $1
|
25
|
+
when 'Regexp'
|
26
|
+
cache_key = $1
|
27
|
+
keys << cache_key if cache_key =~ pattern
|
28
|
+
else
|
29
|
+
keys << $1 if $1[pattern.to_s]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def close_telnet!
|
37
|
+
return unless @telnet
|
38
|
+
@telnet.close
|
39
|
+
@telnet = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def telnet
|
43
|
+
@telnet ||= begin
|
44
|
+
configs = Dalli::KeysMatch.config.telnet(
|
45
|
+
'Host' => hostname,
|
46
|
+
'Port' => port
|
47
|
+
)
|
48
|
+
Net::Telnet.new(configs)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Client
|
54
|
+
def keys(pattern = nil)
|
55
|
+
result = []
|
56
|
+
ring.servers.each do |server|
|
57
|
+
next unless server.alive?
|
58
|
+
items = server.request(:stats, 'items')
|
59
|
+
slabs = items.inject({}) do |r, (k,v)|
|
60
|
+
r[$1] = v if k =~ /items:(\d+):number/
|
61
|
+
r
|
62
|
+
end
|
63
|
+
slabs.each do |id, size|
|
64
|
+
result.push(*server.stats_cachedump(id, size, pattern))
|
65
|
+
end
|
66
|
+
server.close_telnet!
|
67
|
+
end
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def delete_matched(pattern)
|
72
|
+
return 0 if pattern.nil?
|
73
|
+
|
74
|
+
matches = keys(pattern)
|
75
|
+
matches.map { |k| delete(k) }.select { |r| r }.size
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
Dalli::Server.send(:include, Dalli::KeysMatch::Server)
|
82
|
+
Dalli::Client.send(:include, Dalli::KeysMatch::Client)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Dalli
|
2
|
+
module KeysMatch
|
3
|
+
class Configuration
|
4
|
+
TELNET_DEFAULS = {
|
5
|
+
'Prompt' => /(^END$)/,
|
6
|
+
'Timeout' => 20
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@telnet = TELNET_DEFAULS.merge options.fetch(:telnet, {})
|
11
|
+
end
|
12
|
+
|
13
|
+
def telnet(args = {})
|
14
|
+
@telnet.merge args
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dalli-keys-match
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcos G. Zimmermann
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: net-telnet
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dalli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.15'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.15'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '12.1'
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 12.1.0
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '12.1'
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 12.1.0
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '3.6'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '3.6'
|
89
|
+
description: Dalli::KeysMatch extends Dalli with a function that allow you to list
|
90
|
+
or remove keys using optional filters
|
91
|
+
email:
|
92
|
+
- marcos@marcosz.com.br
|
93
|
+
executables: []
|
94
|
+
extensions: []
|
95
|
+
extra_rdoc_files: []
|
96
|
+
files:
|
97
|
+
- ".gitignore"
|
98
|
+
- ".rspec"
|
99
|
+
- ".travis.yml"
|
100
|
+
- Gemfile
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
103
|
+
- bin/console
|
104
|
+
- bin/setup
|
105
|
+
- dalli-keys-match.gemspec
|
106
|
+
- lib/dalli-keys-match.rb
|
107
|
+
- lib/dalli/keys_match.rb
|
108
|
+
- lib/dalli/keys_match/configuration.rb
|
109
|
+
- lib/dalli/keys_match/version.rb
|
110
|
+
homepage: https://github.com/marcosgz/dalli-keys-match
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.5.1
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Dalli::KeysMatch extends Dalli with functions to deal with keys
|
134
|
+
test_files: []
|