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 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
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.15.4
6
+ services:
7
+ - memcached
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'dalli/keys_match'
5
+ require 'irb'
6
+
7
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,2 @@
1
+ # frozen_string_literal: true
2
+ require 'dalli/keys_match'
@@ -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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Dalli
3
+ module KeysMatch
4
+ VERSION = '0.2.0'
5
+ end
6
+ 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: []