daikon 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{daikon}
8
- s.version = "0.7.4"
8
+ s.version = "0.7.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nick Quaranto"]
12
- s.date = %q{2011-02-11}
12
+ s.date = %q{2011-02-17}
13
13
  s.default_executable = %q{daikon}
14
14
  s.description = %q{daikon, a radishapp.com client}
15
15
  s.email = %q{nick@quaran.to}
@@ -32,7 +32,6 @@ Gem::Specification.new do |s|
32
32
  "lib/daikon/configuration.rb",
33
33
  "lib/daikon/daemon.rb",
34
34
  "lib/daikon/monitor.rb",
35
- "lib/daikon/namespace_tools.rb",
36
35
  "lib/daikon/redis_hacks.rb",
37
36
  "spec/client_spec.rb",
38
37
  "spec/configuration_spec.rb",
@@ -18,7 +18,6 @@ $LOAD_PATH.unshift __DIR__ unless
18
18
  $LOAD_PATH.include?(__DIR__) ||
19
19
  $LOAD_PATH.include?(File.expand_path(__DIR__))
20
20
 
21
- require 'daikon/namespace_tools'
22
21
  require 'daikon/configuration'
23
22
  require 'daikon/client'
24
23
  require 'daikon/daemon'
@@ -26,5 +25,5 @@ require 'daikon/monitor'
26
25
  require 'daikon/redis_hacks'
27
26
 
28
27
  module Daikon
29
- VERSION = "0.7.4"
28
+ VERSION = "0.7.5"
30
29
  end
@@ -1,7 +1,5 @@
1
1
  module Daikon
2
2
  class Client
3
- include NamespaceTools
4
-
5
3
  EXCEPTIONS = [Timeout::Error,
6
4
  Errno::EINVAL,
7
5
  Errno::ECONNRESET,
@@ -58,21 +56,6 @@ module Daikon
58
56
  "Content-Type" => "application/json"})
59
57
  end
60
58
 
61
- def fetch_commands
62
- raw_commands = request(:get, "/api/v1/commands.json")
63
- commands = JSON.parse(raw_commands.body)
64
-
65
- commands.each do |id, command|
66
- result = evaluate_redis(command)
67
- pretty = StringIO.new
68
- PP.pp(result, pretty)
69
-
70
- push :put, "/api/v1/commands/#{id}.json", {"response" => pretty.string.strip}
71
- end
72
- rescue *EXCEPTIONS => ex
73
- exception(ex)
74
- end
75
-
76
59
  def rotate_monitor(start, stop)
77
60
  payload = monitor.rotate.merge({
78
61
  "start" => start,
@@ -89,41 +72,5 @@ module Daikon
89
72
  rescue *EXCEPTIONS => ex
90
73
  exception(ex)
91
74
  end
92
-
93
- def evaluate_redis(command)
94
- # Attempt to parse the given command string.
95
- argv =
96
- begin
97
- Shellwords.shellwords(command.to_s)
98
- rescue Exception => e
99
- exception(e)
100
- return e.message
101
- end
102
- return "No command received." unless argv[0]
103
-
104
- begin
105
- execute_redis(argv)
106
- rescue Exception => e
107
- exception(e)
108
- e.message
109
- end
110
- end
111
-
112
- def namespace
113
- nil
114
- end
115
-
116
- def execute_redis(argv)
117
- # Apply the current namespace to any fields that need it.
118
- argv = namespace_input(namespace, *argv)
119
-
120
- raise "Not a Redis command." unless argv.kind_of? Array
121
-
122
- # Send the command to Redis.
123
- result = redis.send(*argv)
124
-
125
- # Remove the namespace from any commands that return a key.
126
- denamespace_output namespace, argv.first, result
127
- end
128
75
  end
129
76
  end
@@ -59,6 +59,9 @@ module Daikon
59
59
  def push(raw_command)
60
60
  command, key, *rest = raw_command.strip.gsub('"', '').split
61
61
  command.upcase!
62
+
63
+ return unless ALL_COMMANDS.member?(command)
64
+
62
65
  lock do
63
66
  incr_command(command)
64
67
  incr_total(command)
@@ -85,7 +88,7 @@ module Daikon
85
88
  end
86
89
 
87
90
  def incr_command(command)
88
- data["commands"][command] += 1 if ALL_COMMANDS.member?(command)
91
+ data["commands"][command] += 1
89
92
  end
90
93
 
91
94
  def incr_key(key)
@@ -37,72 +37,6 @@ describe Daikon::Client, "setup" do
37
37
  end
38
38
  end
39
39
 
40
- shared_examples_for "a command api consumer" do
41
- it "sends a request for commands" do
42
- http.should have_received(:request).with(
43
- :method => "GET",
44
- :path => "/api/v1/commands.json",
45
- :headers => {"Authorization" => api_key})
46
- end
47
-
48
- it "processes each command" do
49
- subject.should have_received(:evaluate_redis).with("INCR foo")
50
- subject.should have_received(:evaluate_redis).with("DECR foo")
51
- end
52
-
53
- it "shoots the results back to radish" do
54
- results = {"response" => "9999"}.to_json
55
-
56
- headers = {
57
- "Authorization" => api_key,
58
- "Content-Length" => results.size.to_s,
59
- "Content-Type" => "application/json"
60
- }
61
-
62
- http.should have_received(:request).with(
63
- :method => "PUT",
64
- :path => "/api/v1/commands/42.json",
65
- :body => results,
66
- :headers => headers)
67
-
68
- http.should have_received(:request).with(
69
- :method => "PUT",
70
- :path => "/api/v1/commands/43.json",
71
- :body => results,
72
- :headers => headers)
73
- end
74
- end
75
-
76
- describe Daikon::Client, "fetching commands" do
77
- subject { Daikon::Client.new }
78
- let(:body) { {"42" => "INCR foo", "43" => "DECR foo"}.to_json }
79
- let(:http) { stub("http", :request => Excon::Response.new(:body => body)) }
80
-
81
- before do
82
- subject.stubs(:evaluate_redis => 9999)
83
- subject.stubs(:http => http)
84
-
85
- subject.setup(config)
86
- subject.fetch_commands
87
- end
88
-
89
- context "with default configuration" do
90
- let(:api_key) { config.api_key }
91
- let(:server) { "https://radish.heroku.com" }
92
- let(:config) { Daikon::Configuration.new([]) }
93
-
94
- it_should_behave_like "a command api consumer"
95
- end
96
-
97
- context "with custom settings" do
98
- let(:api_key) { "0987654321" }
99
- let(:server) { "http://localhost:9999" }
100
- let(:config) { Daikon::Configuration.new(["-k", api_key, "-s", "http://localhost:9999"]) }
101
-
102
- it_should_behave_like "a command api consumer"
103
- end
104
- end
105
-
106
40
  describe Daikon::Client, "when server is down" do
107
41
  subject { Daikon::Client.new }
108
42
  before do
@@ -114,7 +48,7 @@ describe Daikon::Client, "when server is down" do
114
48
 
115
49
  it "does not commit suicide" do
116
50
  lambda {
117
- subject.fetch_commands
51
+ subject.report_info
118
52
  }.should_not raise_error
119
53
  end
120
54
  end
@@ -129,7 +63,7 @@ describe Daikon::Client, "when it returns bad json" do
129
63
 
130
64
  it "does not commit suicide" do
131
65
  lambda {
132
- subject.fetch_commands
66
+ subject.report_info
133
67
  }.should_not raise_error
134
68
  end
135
69
  end
@@ -194,27 +128,6 @@ describe Daikon::Client, "rotate monitor" do
194
128
  end
195
129
  end
196
130
 
197
- describe Daikon::Client, "pretty printing results" do
198
- subject { Daikon::Client.new }
199
- let(:body) { {"13" => "LRANGE foo 0 -1"}.to_json }
200
- let(:list) { %w[apples bananas carrots] }
201
- let(:server) { "https://radish.heroku.com" }
202
- let(:config) { Daikon::Configuration.new }
203
- let(:http) { stub("http", :request => Excon::Response.new(:body => body)) }
204
-
205
- before do
206
- subject.stubs(:evaluate_redis => list, :http => http)
207
- subject.setup(config)
208
- subject.fetch_commands
209
- end
210
-
211
- it "returns pretty printed results" do
212
- http.should have_received(:request).with(has_entry(
213
- :body => {"response" => "[\"apples\", \"bananas\", \"carrots\"]"}.to_json
214
- ))
215
- end
216
- end
217
-
218
131
  shared_examples_for "a info api consumer" do
219
132
  it "shoots the results back to radish" do
220
133
  headers = {
@@ -160,3 +160,17 @@ describe Daikon::Monitor, "#rotate that collects namespaces" do
160
160
  data["namespaces"]["s3"].should == 1
161
161
  end
162
162
  end
163
+
164
+ describe Daikon::Monitor, "#rotate with values that have spaces" do
165
+ before do
166
+ subject.parse("set g:2470920:mrn 11")
167
+ subject.parse("Email Error")
168
+ end
169
+
170
+ it "keeps track of namespace accesses" do
171
+ data = subject.rotate
172
+ data["commands"].should == {"SET" => 1}
173
+ data["keys"].should == {"g:2470920:mrn" => 1}
174
+ data["namespaces"].should == {"g" => 1}
175
+ end
176
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 4
9
- version: 0.7.4
8
+ - 5
9
+ version: 0.7.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Nick Quaranto
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-11 00:00:00 -05:00
17
+ date: 2011-02-17 00:00:00 -05:00
18
18
  default_executable: daikon
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -165,7 +165,6 @@ files:
165
165
  - lib/daikon/configuration.rb
166
166
  - lib/daikon/daemon.rb
167
167
  - lib/daikon/monitor.rb
168
- - lib/daikon/namespace_tools.rb
169
168
  - lib/daikon/redis_hacks.rb
170
169
  - spec/client_spec.rb
171
170
  - spec/configuration_spec.rb
@@ -1,122 +0,0 @@
1
- module Daikon
2
- module NamespaceTools
3
- def namespace_input(ns, command, *args)
4
- command = command.to_s.downcase
5
-
6
- case command
7
-
8
- when "multi", "exec", "discard"
9
-
10
- # No arguments.
11
-
12
- [ command ]
13
-
14
- when "exists", "del", "type", "keys", "ttl", "set", "get", "getset",
15
- "setnx", "incr", "incrby", "decr", "decrby", "rpush", "lpush",
16
- "llen", "lrange", "ltrim", "lindex", "lset", "lrem", "lpop", "rpop",
17
- "sadd", "srem", "spop", "scard", "sismember", "smembers", "srandmember",
18
- "zadd", "zrem", "zincrby", "zrange", "zrevrange", "zrangebyscore",
19
- "zcard", "zscore", "zremrangebyscore", "expire", "expireat", "hlen",
20
- "hkeys", "hvals", "hgetall", "hset", "hget", "hincrby", "hexists",
21
- "hdel", "hmset"
22
-
23
- # Only the first argument is a key.
24
-
25
- head = add_namespace(ns, args.first)
26
- tail = args[1, args.length - 1] || []
27
-
28
- [ command, head, *tail ]
29
-
30
- when "smove"
31
-
32
- # The first two parmeters are keys.
33
-
34
- result = [ command ]
35
-
36
- args.each_with_index do |arg, i|
37
- result << ((i == 0 || i == 1) ? add_namespace(ns, arg) : arg)
38
- end
39
-
40
- result
41
-
42
- when "mget", "rpoplpush", "sinter", "sunion", "sdiff", "info",
43
- "sinterstore", "sunionstore", "sdiffstore", "dbsize"
44
-
45
- # All arguments are keys.
46
-
47
- keys = add_namespace(ns, args)
48
-
49
- [ command, *keys ]
50
-
51
- when "mset", "msetnx"
52
-
53
- # Every other argument is a key, starting with the first.
54
-
55
- hash1 = Hash[*args]
56
- hash2 = {}
57
-
58
- hash1.each do |k, v|
59
- hash2[add_namespace(ns, k)] = hash1.delete(k)
60
- end
61
-
62
- [ command, hash2 ]
63
-
64
- when "sort"
65
-
66
- return [] if args.count == 0
67
-
68
- key = add_namespace(ns, args.shift)
69
- parms = {}
70
-
71
- while keyword = args.shift.andand.downcase
72
- case keyword
73
- when "by", "get", "store"
74
- k = keyword.intern
75
- v = add_namespace(ns, args.shift)
76
-
77
- parms[k] = v
78
- when "limit"
79
- parms[:limit] = [ args.shift.to_i, args.shift.to_i ]
80
- when "asc", "desc", "alpha"
81
- parms[:order].andand << " "
82
- parms[:order] ||= ""
83
- parms[:order] << keyword
84
- end
85
- end
86
-
87
- [ command, key, parms ]
88
-
89
- end
90
- end
91
-
92
- def denamespace_output(namespace, command, result)
93
- case command.to_s.downcase
94
-
95
- when "keys"
96
- remove_namespace namespace, result
97
-
98
- else
99
- result
100
-
101
- end
102
- end
103
-
104
- def add_namespace(namespace, key)
105
- return key unless namespace
106
-
107
- case key
108
- when String then "#{namespace}:#{key}"
109
- when Array then key.map {|k| add_namespace(namespace, k)}
110
- end
111
- end
112
-
113
- def remove_namespace(namespace, key)
114
- return key unless namespace
115
-
116
- case key
117
- when String then key.gsub(/^#{namespace}:/, "")
118
- when Array then key.map {|k| remove_namespace(namespace, k)}
119
- end
120
- end
121
- end
122
- end