zack 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ = 0.2.0 / ???
2
+
3
+ + Starting with this version, zack depends on Cod for all its inner workings
4
+ and just adds RPC. This makes it lean to the point of nonexistence.
5
+
6
+ = 0.1.3 / not released
7
+
8
+ + All calls now have a default timeout of 10 seconds. Timeouts reset the
9
+ queue in a good state. Look at the :timeout option on the client.
10
+
11
+ * The big refactoring, introducing Answer and Message.
12
+
13
+ + Server exception handling: Just run with a block that acts on the exception.
14
+
1
15
  = 0.1.2 / 09-11-2010
2
16
 
3
17
  * FIX: Don't read our own messages back (client)
data/Rakefile CHANGED
@@ -2,10 +2,9 @@ require "rubygems"
2
2
  require "rake/gempackagetask"
3
3
  require "rake/rdoctask"
4
4
 
5
- require "spec"
6
- require "spec/rake/spectask"
7
- Spec::Rake::SpecTask.new
8
-
5
+ require 'rspec'
6
+ require 'rspec/core/rake_task'
7
+ Rspec::Core::RakeTask.new
9
8
  task :default => :spec
10
9
 
11
10
  # This builds the actual gem. For details of what all these options
@@ -17,8 +16,8 @@ spec = Gem::Specification.new do |s|
17
16
 
18
17
  # Change these as appropriate
19
18
  s.name = "zack"
20
- s.version = "0.1.2"
21
- s.summary = "Ruby RPC calls via beanstalkd"
19
+ s.version = "0.2.0"
20
+ s.summary = "Ruby RPC calls via Cod"
22
21
  s.authors = ['Kaspar Schiess', 'Patrick Marchi']
23
22
  s.email = ["kaspar.schiess@absurd.li", 'mail@patrickmarchi.ch']
24
23
  s.homepage = "http://github.com/kschiess/zack"
@@ -31,9 +30,8 @@ spec = Gem::Specification.new do |s|
31
30
  s.files = %w(History.txt LICENSE Rakefile README) + Dir.glob("{spec,lib/**/*}")
32
31
  s.require_paths = ["lib"]
33
32
 
34
- # If you want to depend on other gems, add them here, along with any
35
- # relevant versions
36
- s.add_dependency("beanstalk-client", "~> 1.0.2")
33
+ s.add_dependency("cod", "~> 0.2")
34
+ s.add_dependency("beanstalk-client", "~> 1.0")
37
35
 
38
36
  # If your tests use any gems, include them here
39
37
  s.add_development_dependency("rspec")
data/lib/zack/client.rb CHANGED
@@ -1,46 +1,44 @@
1
1
 
2
- require 'digest/md5' # ruby 1.9
3
2
 
4
3
  # Client part of Zack RPC
5
4
  #
6
5
  class Zack::Client
6
+ attr_reader :service
7
+
7
8
  def initialize(tube_name, opts={})
8
9
  server = opts[:server] || 'beanstalk:11300'
9
-
10
- @connection = Beanstalk::Connection.new(server, tube_name)
11
-
10
+ # Only respond to these messages
11
+ @only = opts[:only] || proc { true }
12
+ # These have answers (wait for the server to answer)
12
13
  @with_answer = opts[:with_answer] || []
13
- unless @with_answer.empty?
14
- # Ain't it beautiful
15
- digest = Digest::MD5.new
16
- digest << @connection.instance_variable_get('@socket').addr.to_s
17
14
 
18
- @answer_queue_name = "answer_"+digest.hexdigest
19
- @answer_connection = Beanstalk::Connection.new(server, @answer_queue_name)
15
+ @outgoing = Cod.beanstalk(server, tube_name)
16
+ unless @with_answer.empty?
17
+ @incoming = Cod.beanstalk(server)
20
18
  end
19
+
20
+ @service = Cod::Client.new(@outgoing, @incoming, 1)
21
21
  end
22
22
 
23
23
  def respond_to?(msg)
24
- true
24
+ !! @only[msg]
25
25
  end
26
- def method_missing(sym, *args, &result_callback)
27
- message = [sym, args]
26
+ def method_missing(sym, *args, &block)
27
+ super unless respond_to?(sym)
28
28
 
29
- if @with_answer.include? sym
30
- message << @answer_queue_name
31
- end
32
-
33
- @connection.put message.to_yaml
29
+ raise ArgumentError, "Can't call methods remotely with a block" if block
34
30
 
35
- if @with_answer.include? sym
36
- answer = @answer_connection.reserve
37
- begin
38
- return YAML.load(answer.body)
39
- ensure
40
- answer.delete
41
- end
31
+ if has_answer?(sym)
32
+ return service.call([sym, args])
33
+ else
34
+ service.notify [sym, args]
35
+ return nil
42
36
  end
43
-
44
- return nil
37
+ rescue Cod::Channel::TimeoutError
38
+ raise Zack::ServiceTimeout, "No response from server in the allowed time."
39
+ end
40
+
41
+ def has_answer?(sym)
42
+ @with_answer.include?(sym.to_sym)
45
43
  end
46
44
  end
data/lib/zack/server.rb CHANGED
@@ -5,8 +5,8 @@ class Zack::Server
5
5
  class SimpleFactory < Struct.new(:implementation_klass)
6
6
  def produce; implementation_klass.new; end
7
7
  end
8
-
9
- attr_reader :tube_name
8
+
9
+ attr_reader :service
10
10
 
11
11
  def initialize(tube_name, opts={})
12
12
  server = opts[:server] || 'beanstalk:11300'
@@ -19,50 +19,43 @@ class Zack::Server
19
19
  raise ArgumentError, "Either :factory or :simple argument must be given."
20
20
  end
21
21
 
22
- @tube_name = tube_name
23
- @connection = Beanstalk::Connection.new(server, tube_name)
22
+ channel = Cod.beanstalk(server, tube_name)
23
+ @service = Cod::Service.new(channel)
24
24
  end
25
25
 
26
26
  # Handles exactly one request.
27
27
  #
28
28
  def handle_request
29
- job = @connection.reserve
30
- sym, args, answer_tube = nil, nil, nil
31
- begin
32
- sym, args, answer_tube = YAML.load(job.body)
33
- ensure
34
- # If yaml decoding crashes, the message is probably invalid. Delete it.
35
- # If an exception is raised later on, we treat the request as satisfied.
36
- job.delete
37
- end
38
-
39
- instance = @factory.produce
40
- retval = instance.send(sym, *args)
41
-
42
- if answer_tube
43
- on_tube(answer_tube) do
44
- @connection.put retval.to_yaml
45
- end
46
- end
29
+ service.one { |(sym, args)|
30
+ instance = @factory.produce
31
+
32
+ instance.send(sym, *args)
33
+ }
47
34
  end
48
35
 
49
36
  # Runs the server and keeps running until the world ends (or the process,
50
37
  # whichever comes first).
51
38
  #
52
- def run
39
+ def run(&block)
53
40
  loop do
54
- handle_request
41
+ exception_handling(block) do
42
+ handle_request
43
+ end
55
44
  end
56
45
  end
57
46
 
58
47
  private
59
- def on_tube(temporary_tube_name)
60
- begin
61
- @connection.use temporary_tube_name
62
-
48
+ # Defines how the server handles exception.
49
+ #
50
+ def exception_handling(exception_handler)
51
+ if exception_handler
52
+ begin
53
+ yield
54
+ rescue => exception
55
+ exception_handler.call(exception)
56
+ end
57
+ else
63
58
  yield
64
- ensure
65
- @connection.use @tube_name
66
59
  end
67
60
  end
68
61
  end
data/lib/zack.rb CHANGED
@@ -1,7 +1,12 @@
1
- require 'beanstalk-client'
2
- require 'yaml'
3
1
 
4
- module Zack; end
2
+ require 'cod'
5
3
 
6
- require 'zack/server'
7
- require 'zack/client'
4
+ module Zack
5
+ autoload :Server, 'zack/server'
6
+ autoload :Client, 'zack/client'
7
+
8
+ # Gets raised when the server doesn't answer within the currently configured
9
+ # timeout for a message that waits for an answer.
10
+ #
11
+ class ServiceTimeout < StandardError; end
12
+ end
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zack
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
4
+ prerelease:
5
+ version: 0.2.0
10
6
  platform: ruby
11
7
  authors:
12
8
  - Kaspar Schiess
@@ -15,50 +11,53 @@ autorequire:
15
11
  bindir: bin
16
12
  cert_chain: []
17
13
 
18
- date: 2010-11-09 00:00:00 +01:00
14
+ date: 2011-04-27 00:00:00 +02:00
19
15
  default_executable:
20
16
  dependencies:
21
17
  - !ruby/object:Gem::Dependency
22
- name: beanstalk-client
18
+ name: cod
23
19
  prerelease: false
24
20
  requirement: &id001 !ruby/object:Gem::Requirement
25
21
  none: false
26
22
  requirements:
27
23
  - - ~>
28
24
  - !ruby/object:Gem::Version
29
- segments:
30
- - 1
31
- - 0
32
- - 2
33
- version: 1.0.2
25
+ version: "0.2"
34
26
  type: :runtime
35
27
  version_requirements: *id001
36
28
  - !ruby/object:Gem::Dependency
37
- name: rspec
29
+ name: beanstalk-client
38
30
  prerelease: false
39
31
  requirement: &id002 !ruby/object:Gem::Requirement
32
+ none: false
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: "1.0"
37
+ type: :runtime
38
+ version_requirements: *id002
39
+ - !ruby/object:Gem::Dependency
40
+ name: rspec
41
+ prerelease: false
42
+ requirement: &id003 !ruby/object:Gem::Requirement
40
43
  none: false
41
44
  requirements:
42
45
  - - ">="
43
46
  - !ruby/object:Gem::Version
44
- segments:
45
- - 0
46
47
  version: "0"
47
48
  type: :development
48
- version_requirements: *id002
49
+ version_requirements: *id003
49
50
  - !ruby/object:Gem::Dependency
50
51
  name: flexmock
51
52
  prerelease: false
52
- requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirement: &id004 !ruby/object:Gem::Requirement
53
54
  none: false
54
55
  requirements:
55
56
  - - ">="
56
57
  - !ruby/object:Gem::Version
57
- segments:
58
- - 0
59
58
  version: "0"
60
59
  type: :development
61
- version_requirements: *id003
60
+ version_requirements: *id004
62
61
  description:
63
62
  email:
64
63
  - kaspar.schiess@absurd.li
@@ -92,23 +91,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
91
  requirements:
93
92
  - - ">="
94
93
  - !ruby/object:Gem::Version
95
- segments:
96
- - 0
97
94
  version: "0"
98
95
  required_rubygems_version: !ruby/object:Gem::Requirement
99
96
  none: false
100
97
  requirements:
101
98
  - - ">="
102
99
  - !ruby/object:Gem::Version
103
- segments:
104
- - 0
105
100
  version: "0"
106
101
  requirements: []
107
102
 
108
103
  rubyforge_project:
109
- rubygems_version: 1.3.7
104
+ rubygems_version: 1.5.2
110
105
  signing_key:
111
106
  specification_version: 3
112
- summary: Ruby RPC calls via beanstalkd
107
+ summary: Ruby RPC calls via Cod
113
108
  test_files: []
114
109