kjess 1.0.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.
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