zack 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+
2
+ = 0.1.0 / 05-31-2010
3
+
4
+ * Initial release.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+
2
+ Copyright (c) 2010 Kaspar Schiess, Patrick Marchi
3
+
4
+ Permission is hereby granted, free of charge, to any person
5
+ obtaining a copy of this software and associated documentation
6
+ files (the "Software"), to deal in the Software without
7
+ restriction, including without limitation the rights to use,
8
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the
10
+ Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,49 @@
1
+ INTRO
2
+
3
+ zack climbs the beanstalk and may even return a golden harp from the sky. zack
4
+ allows you to do RPC via beanstalkd. It will encode your messages and handle
5
+ return values.
6
+
7
+ SYNOPSIS
8
+
9
+ # Server
10
+ class Server
11
+ def answer
12
+ puts 'answer called'
13
+ 42
14
+ end
15
+ end
16
+
17
+ require 'zack'
18
+ Zack::Server.new(
19
+ 'the_answer_to_life_the_universe_and_everything',
20
+ :simple => Server,
21
+ :server => 'localhost:11300'
22
+ ).run
23
+
24
+ # Client
25
+ require 'zack'
26
+ answer = Zack::Client.
27
+ new(
28
+ 'the_answer_to_life_the_universe_and_everything',
29
+ :server => 'localhost:11300',
30
+ :with_answer => [:answer]).
31
+ answer
32
+
33
+ puts "The answer is #{answer}!"
34
+
35
+ This will output 'answer called' on the server and 'The answer is 41!' on the
36
+ client.
37
+
38
+ zack is a small library that doesn't do much more than what has been shown
39
+ above.
40
+
41
+ COMPATIBILITY
42
+
43
+ Should run with most rubies of the 1.8 and 1.9 generations.
44
+
45
+ STATUS
46
+
47
+ Useful and useable. First release.
48
+
49
+ (c) Kaspar Schiess, Patrick Marchi
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require "rubygems"
2
+ require "rake/gempackagetask"
3
+ require "rake/rdoctask"
4
+
5
+ require "spec"
6
+ require "spec/rake/spectask"
7
+ Spec::Rake::SpecTask.new
8
+
9
+ task :default => :spec
10
+
11
+ # This builds the actual gem. For details of what all these options
12
+ # mean, and other ones you can add, check the documentation here:
13
+ #
14
+ # http://rubygems.org/read/chapter/20
15
+ #
16
+ spec = Gem::Specification.new do |s|
17
+
18
+ # Change these as appropriate
19
+ s.name = "zack"
20
+ s.version = "0.1.0"
21
+ s.summary = "Ruby RPC calls via beanstalkd"
22
+ s.authors = ['Kaspar Schiess', 'Patrick Marchi']
23
+ s.email = ["kaspar.schiess@absurd.li", 'patrick.marchi@geo.uzh.ch']
24
+ s.homepage = "http://github.com/kschiess/zack"
25
+
26
+ s.has_rdoc = true
27
+ s.extra_rdoc_files = %w(README)
28
+ s.rdoc_options = %w(--main README)
29
+
30
+ # Add any extra files to include in the gem
31
+ s.files = %w(History.txt LICENSE Rakefile README) + Dir.glob("{spec,lib/**/*}")
32
+ s.require_paths = ["lib"]
33
+
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")
37
+
38
+ # If your tests use any gems, include them here
39
+ s.add_development_dependency("rspec")
40
+ s.add_development_dependency("flexmock")
41
+ end
42
+
43
+ # This task actually builds the gem. We also regenerate a static
44
+ # .gemspec file, which is useful if something (i.e. GitHub) will
45
+ # be automatically building a gem for this project. If you're not
46
+ # using GitHub, edit as appropriate.
47
+ #
48
+ # To publish your gem online, install the 'gemcutter' gem; Read more
49
+ # about that here: http://gemcutter.org/pages/gem_docs
50
+ Rake::GemPackageTask.new(spec) do |pkg|
51
+ pkg.gem_spec = spec
52
+
53
+ # Generate the gemspec file for github.
54
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
55
+ File.open(file, "w") {|f| f << spec.to_ruby }
56
+ end
57
+
58
+ # Generate documentation
59
+ Rake::RDocTask.new do |rd|
60
+ rd.main = "README"
61
+ rd.rdoc_files.include("README", "lib/**/*.rb")
62
+ rd.rdoc_dir = "rdoc"
63
+ end
64
+
65
+ desc 'Clear out RDoc and generated packages'
66
+ task :clean => [:clobber_rdoc, :clobber_package] do
67
+ rm "#{spec.name}.gemspec"
68
+ end
@@ -0,0 +1,41 @@
1
+
2
+ require 'digest/md5' # ruby 1.9
3
+
4
+ # Client part of Zack RPC
5
+ #
6
+ class Zack::Client
7
+ def initialize(tube_name, opts={})
8
+ server = opts[:server] || 'beanstalk:11300'
9
+
10
+ @connection = Beanstalk::Connection.new(server, tube_name)
11
+
12
+ @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
+ @answer_queue_name = "answer_"+digest.hexdigest
18
+ end
19
+ end
20
+
21
+ def respond_to?(msg)
22
+ true
23
+ end
24
+ def method_missing(sym, *args, &result_callback)
25
+ message = [sym, args]
26
+
27
+ if @with_answer.include? sym
28
+ message << @answer_queue_name
29
+ end
30
+
31
+ @connection.put message.to_yaml
32
+
33
+ if @with_answer.include? sym
34
+ @connection.watch @answer_queue_name
35
+ answer = @connection.reserve
36
+ return YAML.load(answer.body)
37
+ end
38
+
39
+ return nil
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+
2
+ # Server side for RPC calls.
3
+ #
4
+ class Zack::Server
5
+ class SimpleFactory < Struct.new(:implementation_klass)
6
+ def produce; implementation_klass.new; end
7
+ end
8
+
9
+ attr_reader :tube_name
10
+
11
+ def initialize(tube_name, opts={})
12
+ server = opts[:server] || 'beanstalk:11300'
13
+
14
+ if opts.has_key? :factory
15
+ @factory = opts[:factory]
16
+ elsif opts.has_key? :simple
17
+ @factory = SimpleFactory.new(opts[:simple])
18
+ else
19
+ raise ArgumentError, "Either :factory or :simple argument must be given."
20
+ end
21
+
22
+ @tube_name = tube_name
23
+ @connection = Beanstalk::Connection.new(server, tube_name)
24
+ end
25
+
26
+ # Handles exactly one request.
27
+ #
28
+ def handle_request
29
+ job = @connection.reserve
30
+ begin
31
+ sym, args, answer_tube = YAML.load(job.body)
32
+
33
+ instance = @factory.produce
34
+ retval = instance.send(sym, *args)
35
+
36
+ if answer_tube
37
+ @connection.use answer_tube
38
+ @connection.put retval.to_yaml
39
+ @connection.use tube_name
40
+ end
41
+ ensure
42
+ job.delete
43
+ end
44
+ end
45
+
46
+ # Runs the server and keeps running until the world ends (or the process,
47
+ # whichever comes first).
48
+ #
49
+ def run
50
+ loop do
51
+ handle_request
52
+ end
53
+ end
54
+ end
data/lib/zack.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'beanstalk-client'
2
+ require 'yaml'
3
+
4
+ module Zack; end
5
+
6
+ require 'zack/server'
7
+ require 'zack/client'
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zack
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Kaspar Schiess
14
+ - Patrick Marchi
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-05-31 00:00:00 +02:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ name: beanstalk-client
24
+ prerelease: false
25
+ requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ hash: 19
31
+ segments:
32
+ - 1
33
+ - 0
34
+ - 2
35
+ version: 1.0.2
36
+ type: :runtime
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ prerelease: false
41
+ requirement: &id002 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ hash: 3
47
+ segments:
48
+ - 0
49
+ version: "0"
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: flexmock
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ type: :development
65
+ version_requirements: *id003
66
+ description:
67
+ email:
68
+ - kaspar.schiess@absurd.li
69
+ - patrick.marchi@geo.uzh.ch
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files:
75
+ - README
76
+ files:
77
+ - History.txt
78
+ - LICENSE
79
+ - Rakefile
80
+ - README
81
+ - lib/zack/client.rb
82
+ - lib/zack/server.rb
83
+ - lib/zack.rb
84
+ has_rdoc: true
85
+ homepage: http://github.com/kschiess/zack
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options:
90
+ - --main
91
+ - README
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ hash: 3
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ requirements: []
113
+
114
+ rubyforge_project:
115
+ rubygems_version: 1.3.7
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Ruby RPC calls via beanstalkd
119
+ test_files: []
120
+