zack 0.1.2 → 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.
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