kjess 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/CONTRIBUTING.md +45 -0
  2. data/HISTORY.rdoc +5 -0
  3. data/LICENSE +16 -0
  4. data/Manifest.txt +53 -0
  5. data/README.rdoc +44 -0
  6. data/Rakefile +337 -0
  7. data/example/client_test.rb +73 -0
  8. data/lib/kjess.rb +11 -0
  9. data/lib/kjess/client.rb +289 -0
  10. data/lib/kjess/connection.rb +119 -0
  11. data/lib/kjess/error.rb +5 -0
  12. data/lib/kjess/protocol.rb +76 -0
  13. data/lib/kjess/request.rb +31 -0
  14. data/lib/kjess/request/delete.rb +11 -0
  15. data/lib/kjess/request/dump_stats.rb +7 -0
  16. data/lib/kjess/request/flush.rb +11 -0
  17. data/lib/kjess/request/flush_all.rb +7 -0
  18. data/lib/kjess/request/get.rb +21 -0
  19. data/lib/kjess/request/quit.rb +7 -0
  20. data/lib/kjess/request/reload.rb +7 -0
  21. data/lib/kjess/request/set.rb +19 -0
  22. data/lib/kjess/request/shutdown.rb +7 -0
  23. data/lib/kjess/request/stats.rb +7 -0
  24. data/lib/kjess/request/status.rb +8 -0
  25. data/lib/kjess/request/version.rb +8 -0
  26. data/lib/kjess/response.rb +76 -0
  27. data/lib/kjess/response/client_error.rb +19 -0
  28. data/lib/kjess/response/deleted.rb +5 -0
  29. data/lib/kjess/response/dumped_stats.rb +48 -0
  30. data/lib/kjess/response/end.rb +5 -0
  31. data/lib/kjess/response/eof.rb +5 -0
  32. data/lib/kjess/response/error.rb +13 -0
  33. data/lib/kjess/response/flushed_all_queues.rb +6 -0
  34. data/lib/kjess/response/not_found.rb +5 -0
  35. data/lib/kjess/response/not_stored.rb +5 -0
  36. data/lib/kjess/response/reloaded_config.rb +6 -0
  37. data/lib/kjess/response/server_error.rb +18 -0
  38. data/lib/kjess/response/stats.rb +60 -0
  39. data/lib/kjess/response/stored.rb +5 -0
  40. data/lib/kjess/response/unknown.rb +3 -0
  41. data/lib/kjess/response/value.rb +26 -0
  42. data/lib/kjess/response/version.rb +10 -0
  43. data/lib/kjess/stats_cache.rb +31 -0
  44. data/spec/client_spec.rb +265 -0
  45. data/spec/kestrel_server.rb +137 -0
  46. data/spec/request/set_spec.rb +13 -0
  47. data/spec/request/version_spec.rb +17 -0
  48. data/spec/request_spec.rb +30 -0
  49. data/spec/response/client_error_spec.rb +17 -0
  50. data/spec/spec_helper.rb +12 -0
  51. data/spec/utils.rb +18 -0
  52. data/spec/version_spec.rb +9 -0
  53. data/tasks/kestrel.rake +70 -0
  54. metadata +193 -0
@@ -0,0 +1,137 @@
1
+ require 'json'
2
+ require 'spec/utils'
3
+ require 'net/http'
4
+ module KJess::Spec
5
+ class KestrelServer
6
+
7
+ class << self
8
+ def version
9
+ "2.3.4"
10
+ end
11
+
12
+ def dir
13
+ File.join( KJess::Spec.project_root, "kestrel/kestrel-#{version}" )
14
+ end
15
+
16
+ def zip
17
+ "#{dir}.zip"
18
+ end
19
+
20
+ def jar
21
+ File.join( dir, "kestrel_2.9.1-#{version}.jar" )
22
+ end
23
+
24
+ def queue_path
25
+ File.join( dir, 'data' )
26
+ end
27
+
28
+ def log_path
29
+ File.join( dir, 'logs' )
30
+ end
31
+
32
+ def log_file
33
+ File.join( log_path, 'kestrel.log' )
34
+ end
35
+
36
+ def config_file
37
+ File.join( dir, 'config', 'kjess.scala' )
38
+ end
39
+
40
+ def config_contents
41
+ contents = <<_EOC
42
+ import com.twitter.conversions.storage._
43
+ import com.twitter.conversions.time._
44
+ import com.twitter.logging.config._
45
+ import com.twitter.ostrich.admin.config._
46
+ import net.lag.kestrel.config._
47
+
48
+ new KestrelConfig {
49
+ listenAddress = "0.0.0.0"
50
+ memcacheListenPort = 22133
51
+
52
+ queuePath = "#{KJess::Spec::KestrelServer.queue_path}"
53
+
54
+ clientTimeout = 30.seconds
55
+
56
+ expirationTimerFrequency = 1.second
57
+
58
+ maxOpenTransactions = 100
59
+
60
+ // default queue settings:
61
+ default.defaultJournalSize = 16.megabytes
62
+ default.maxMemorySize = 128.megabytes
63
+ default.maxJournalSize = 1.gigabyte
64
+
65
+ admin.httpPort = 2223
66
+
67
+ admin.statsNodes = new StatsConfig {
68
+ reporters = new TimeSeriesCollectorConfig
69
+ }
70
+
71
+ loggers = new LoggerConfig {
72
+ level = Level.DEBUG
73
+ handlers = new FileHandlerConfig {
74
+ filename = "#{KJess::Spec::KestrelServer.log_file}"
75
+ roll = Policy.Never
76
+ }
77
+ }
78
+ }
79
+ _EOC
80
+ end
81
+
82
+ def get_response( path )
83
+ uri = URI.parse( "http://localhost:2223/#{path}" )
84
+ resp = Net::HTTP.get_response( uri )
85
+ JSON.parse( resp.body )
86
+ end
87
+
88
+ def start
89
+ Dir.chdir( KJess::Spec::KestrelServer.dir ) do
90
+ cmd = "java -server -Xmx1024m -Dstage=kjess -jar #{KJess::Spec::KestrelServer.jar} &"
91
+ puts cmd
92
+ system( cmd )
93
+ loop do
94
+ break if is_running?
95
+ end
96
+ puts "Started."
97
+ end
98
+ end
99
+
100
+ def is_running?
101
+ return "pong" == ping
102
+ rescue Exception => e
103
+ false
104
+ end
105
+
106
+ def is_stopped?
107
+ return !is_running?
108
+ end
109
+
110
+ def status
111
+ puts "Running" if "pong" == ping
112
+ rescue Exception
113
+ puts "Stopped."
114
+ end
115
+
116
+ def stop
117
+ shutdown
118
+ loop do
119
+ break if is_stopped?
120
+ end
121
+ puts "Stopped."
122
+ end
123
+
124
+ def ping
125
+ get_response('ping')['response']
126
+ end
127
+
128
+ def shutdown
129
+ h = get_response( 'shutdown' )
130
+ return h['response'] == "ok"
131
+ rescue => e
132
+ false
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe KJess::Request::Set do
4
+ it "converts to the protocol" do
5
+ s = KJess::Request::Set.new( :queue_name => 'test', :data => 'a job' )
6
+ s.to_protocol.must_equal "SET test 0 0 5\r\na job\r\n"
7
+ end
8
+
9
+ it "sets the expriation time" do
10
+ s = KJess::Request::Set.new( :queue_name => 'test', :expiration => 42, :data => 'a job' )
11
+ s.to_protocol.must_equal "SET test 0 42 5\r\na job\r\n"
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe KJess::Request::Version do
4
+
5
+ it "has a keyword" do
6
+ KJess::Request::Version.keyword.must_equal "VERSION"
7
+ end
8
+
9
+ it "converts to the protocol" do
10
+ v = KJess::Request::Version.new
11
+ v.to_protocol.must_equal "VERSION\r\n"
12
+ end
13
+
14
+ it "has a valid response" do
15
+ KJess::Request::Version.valid_responses.size.must_equal 1
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ class KJess::Spec::TestRequest < KJess::Request
4
+ keyword "TEST"
5
+ arity 1
6
+
7
+ def parse_options_to_args( opts )
8
+ opts.values
9
+ end
10
+ end
11
+
12
+ describe KJess::Response do
13
+ it "defines a keyword for child classes" do
14
+ KJess::Spec::TestRequest.keyword.must_equal 'TEST'
15
+ end
16
+
17
+ it "uses a callback to parse the options to args" do
18
+ r = KJess::Spec::TestRequest.new( :foo => 'this' )
19
+ r.args.must_equal %w[ this ]
20
+ end
21
+
22
+ it "converts the request into a protocol stream" do
23
+ r = KJess::Spec::TestRequest.new( :foo => 'that' )
24
+ r.to_protocol.must_equal "TEST that\r\n"
25
+ end
26
+
27
+ it "registers child classes" do
28
+ KJess::Request.registry['TEST'].must_equal KJess::Spec::TestRequest
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe KJess::ClientError do
4
+ before do
5
+ @client = KJess::Client.new
6
+ end
7
+
8
+ after do
9
+ KJess::Spec.reset_server( @client )
10
+ end
11
+
12
+ it "raises a client error if we send an invalid command" do
13
+ lambda { @client.send_recv( KJess::Request::Status.new ) }.must_raise KJess::ClientError
14
+ end
15
+ end
16
+
17
+
@@ -0,0 +1,12 @@
1
+ if RUBY_VERSION >= '1.9.2' then
2
+ require 'simplecov'
3
+ puts "Using coverage!"
4
+ SimpleCov.start if ENV['COVERAGE']
5
+ end
6
+
7
+ gem 'minitest'
8
+ require 'minitest/autorun'
9
+ require 'minitest/pride'
10
+ require 'kjess'
11
+ require 'utils'
12
+
@@ -0,0 +1,18 @@
1
+ module KJess
2
+ module Spec
3
+ ROOT = File.expand_path( "..", __FILE__ )
4
+ def self.project_root
5
+ File.expand_path( "..", ROOT )
6
+ end
7
+
8
+ def self.reset_server( client )
9
+ client.flush_all
10
+ qlist = client.stats['queues']
11
+ if qlist then
12
+ qlist.keys.each do |q|
13
+ client.delete( q )
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'kjess'
3
+
4
+ describe KJess::VERSION do
5
+ it 'should have a #.#.# format' do
6
+ KJess::VERSION.must_match( /\A\d+\.\d+\.\d+\Z/ )
7
+ KJess::VERSION.to_s.must_match( /\A\d+\.\d+\.\d+\Z/ )
8
+ end
9
+ end
@@ -0,0 +1,70 @@
1
+ load 'spec/kestrel_server.rb'
2
+
3
+ namespace :kestrel do
4
+
5
+ directory 'kestrel'
6
+ file KJess::Spec::KestrelServer.zip => 'kestrel' do
7
+ require 'uri'
8
+ require 'net/http'
9
+
10
+ url = ::URI.parse("http://robey.github.com/kestrel/download/kestrel-#{KJess::Spec::KestrelServer.erver.version}.zip")
11
+
12
+ puts "downloading #{url.to_s} to #{KJess::Spec::KestrelServer.zip} ..."
13
+ File.open( KJess::Spec::KestrelServer.erver.zip, "wb+") do |f|
14
+ res = Net::HTTP.get_response( url )
15
+ f.write( res.body )
16
+ end
17
+ end
18
+
19
+
20
+ file KJess::Spec::KestrelServer.jar => KJess::Spec::KestrelServer.zip do
21
+ require 'zip'
22
+ puts "extracting #{KJess::Spec::KestrelServer.zip}"
23
+ Zip::ZipFile.open( KJess::Spec::KestrelServer.zip ) do |zipfile|
24
+ zipfile.entries.each do |entry|
25
+ next unless entry.file?
26
+ dest_name = File.join('kestrel', entry.name.strip)
27
+ dirname = File.dirname( dest_name )
28
+ FileUtils.mkdir_p( dirname ) unless File.directory?( dirname )
29
+ entry.extract( dest_name ) { true }
30
+ end
31
+ end
32
+ end
33
+
34
+ desc "Unpack kestrel to use for testing"
35
+ task :extract => KJess::Spec::KestrelServer.jar
36
+
37
+ directory KJess::Spec::KestrelServer.queue_path
38
+ directory KJess::Spec::KestrelServer.log_path
39
+
40
+ file KJess::Spec::KestrelServer.config_file => [ KJess::Spec::KestrelServer.jar,
41
+ KJess::Spec::KestrelServer.queue_path,
42
+ KJess::Spec::KestrelServer.log_path ] do
43
+ File.open( KJess::Spec::KestrelServer.config_file, "w+" ) do |f|
44
+ puts "Writing #{KJess::Spec::KestrelServer.config_file}"
45
+ f.write( KJess::Spec::KestrelServer.config_contents )
46
+ end
47
+ end
48
+
49
+ desc "Start a kestrel server"
50
+ task :start => KJess::Spec::KestrelServer.config_file do
51
+ KJess::Spec::KestrelServer.start
52
+ end
53
+
54
+ desc "Stop a kestrel server"
55
+ task :stop => KJess::Spec::KestrelServer.config_file do
56
+ KJess::Spec::KestrelServer.stop
57
+ end
58
+
59
+ desc "See the status of the kestrel server"
60
+ task :status => KJess::Spec::KestrelServer.config_file do
61
+ KJess::Spec::KestrelServer.status
62
+ end
63
+
64
+ task :clean do
65
+ FileUtils.rm_rf( KJess::Spec::KestrelServer.dir, :verbose => true )
66
+ end
67
+ end
68
+
69
+ task :clean => 'kestrel:clean'
70
+ task :test => KJess::Spec::KestrelServer.config_file
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kjess
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jeremy Hinegardner
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-10-31 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rake
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 11
29
+ segments:
30
+ - 0
31
+ - 9
32
+ - 2
33
+ - 2
34
+ version: 0.9.2.2
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: minitest
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 11
46
+ segments:
47
+ - 3
48
+ - 3
49
+ - 0
50
+ version: 3.3.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rdoc
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ hash: 31
62
+ segments:
63
+ - 3
64
+ - 12
65
+ version: "3.12"
66
+ type: :development
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: zip
70
+ prerelease: false
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 11
77
+ segments:
78
+ - 2
79
+ - 0
80
+ - 2
81
+ version: 2.0.2
82
+ type: :development
83
+ version_requirements: *id004
84
+ description: KJess is a pure ruby Kestrel client that supports Kestrel's Memcache style protocol.
85
+ email: jeremy@copiousfreetime.org
86
+ executables: []
87
+
88
+ extensions: []
89
+
90
+ extra_rdoc_files:
91
+ - HISTORY.rdoc
92
+ - Manifest.txt
93
+ - README.rdoc
94
+ files:
95
+ - CONTRIBUTING.md
96
+ - HISTORY.rdoc
97
+ - LICENSE
98
+ - Manifest.txt
99
+ - README.rdoc
100
+ - Rakefile
101
+ - example/client_test.rb
102
+ - lib/kjess.rb
103
+ - lib/kjess/client.rb
104
+ - lib/kjess/connection.rb
105
+ - lib/kjess/error.rb
106
+ - lib/kjess/protocol.rb
107
+ - lib/kjess/request.rb
108
+ - lib/kjess/request/delete.rb
109
+ - lib/kjess/request/dump_stats.rb
110
+ - lib/kjess/request/flush.rb
111
+ - lib/kjess/request/flush_all.rb
112
+ - lib/kjess/request/get.rb
113
+ - lib/kjess/request/quit.rb
114
+ - lib/kjess/request/reload.rb
115
+ - lib/kjess/request/set.rb
116
+ - lib/kjess/request/shutdown.rb
117
+ - lib/kjess/request/stats.rb
118
+ - lib/kjess/request/status.rb
119
+ - lib/kjess/request/version.rb
120
+ - lib/kjess/response.rb
121
+ - lib/kjess/response/client_error.rb
122
+ - lib/kjess/response/deleted.rb
123
+ - lib/kjess/response/dumped_stats.rb
124
+ - lib/kjess/response/end.rb
125
+ - lib/kjess/response/eof.rb
126
+ - lib/kjess/response/error.rb
127
+ - lib/kjess/response/flushed_all_queues.rb
128
+ - lib/kjess/response/not_found.rb
129
+ - lib/kjess/response/not_stored.rb
130
+ - lib/kjess/response/reloaded_config.rb
131
+ - lib/kjess/response/server_error.rb
132
+ - lib/kjess/response/stats.rb
133
+ - lib/kjess/response/stored.rb
134
+ - lib/kjess/response/unknown.rb
135
+ - lib/kjess/response/value.rb
136
+ - lib/kjess/response/version.rb
137
+ - lib/kjess/stats_cache.rb
138
+ - spec/client_spec.rb
139
+ - spec/kestrel_server.rb
140
+ - spec/request/set_spec.rb
141
+ - spec/request/version_spec.rb
142
+ - spec/request_spec.rb
143
+ - spec/response/client_error_spec.rb
144
+ - spec/spec_helper.rb
145
+ - spec/utils.rb
146
+ - spec/version_spec.rb
147
+ - tasks/kestrel.rake
148
+ homepage: http://github.com/copiousfreetime/kjess
149
+ licenses: []
150
+
151
+ post_install_message:
152
+ rdoc_options:
153
+ - --main
154
+ - README.rdoc
155
+ - --markup
156
+ - tomdoc
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
166
+ - 0
167
+ version: "0"
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
175
+ - 0
176
+ version: "0"
177
+ requirements: []
178
+
179
+ rubyforge_project:
180
+ rubygems_version: 1.8.24
181
+ signing_key:
182
+ specification_version: 3
183
+ summary: KJess is a pure ruby Kestrel client that supports Kestrel's Memcache style protocol.
184
+ test_files:
185
+ - spec/client_spec.rb
186
+ - spec/kestrel_server.rb
187
+ - spec/request/set_spec.rb
188
+ - spec/request/version_spec.rb
189
+ - spec/request_spec.rb
190
+ - spec/response/client_error_spec.rb
191
+ - spec/spec_helper.rb
192
+ - spec/utils.rb
193
+ - spec/version_spec.rb