activemessaging-kestrel-adapter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.Rakefile.swp ADDED
Binary file
data/.bnsignore ADDED
@@ -0,0 +1,18 @@
1
+ # The list of files that should be ignored by Mr Bones.
2
+ # Lines that start with '#' are comments.
3
+ #
4
+ # A .gitignore file can be used instead by setting it as the ignore
5
+ # file in your Rakefile:
6
+ #
7
+ # Bones {
8
+ # ignore_file '.gitignore'
9
+ # }
10
+ #
11
+ # For a project with a C extension, the following would be a good set of
12
+ # exclude patterns (uncomment them if you want to use them):
13
+ # *.[oa]
14
+ # *~
15
+ announcement.txt
16
+ coverage
17
+ doc
18
+ pkg
data/History.txt ADDED
@@ -0,0 +1,7 @@
1
+ == 0.0.1 / 2011-02-02
2
+ * First release, actually works in a Rails application.
3
+
4
+ == 0.0.0 / 2011-01-31
5
+
6
+ * 1 major enhancement
7
+ * Birthday!
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ activemessaging-kestrel-adapter
2
+ ===========
3
+
4
+ This is an adapter to the kestrel messaging server for the ActiveMessaging framework. It is
5
+ in the early stages of development.
6
+
7
+ Features
8
+ --------
9
+
10
+ * send to any queue
11
+ * receive from any subscribed queue
12
+
13
+ Examples
14
+ --------
15
+
16
+ require 'activemessaging-kestrel-adapter'
17
+
18
+ # configure ActiveMessaging broker in an appropriate broker.yml file:
19
+ # development:
20
+ # adapter: kestrel
21
+ # servers: localhost:22133
22
+ config = YAML.load(File.read("broker.yml"))
23
+
24
+ adapter = ActiveMessaging::Adapter::Kestrel::Connection.new(config[:development])
25
+
26
+ adapter.send("arbitrarily_named_queue", "message as string")
27
+ adapter.subscribe("queue1")
28
+ adapter.subscribe("queue2")
29
+ adapter.receive # get a message from any of the subscribed queues, or nil if they are all empty
30
+
31
+
32
+ Requirements
33
+ ------------
34
+
35
+ * depends on memcached-client
36
+ * flesh out the configuration
37
+
38
+ Future
39
+ ------
40
+
41
+ * Handle a cluster of kestrel servers
42
+ * Write some tests (need a mock kestrel service?)
43
+
44
+ Install
45
+ -------
46
+
47
+ * gem install activemessaging-kestrel-adapter
48
+
49
+ Author
50
+ ------
51
+
52
+ Original author: Douglas A. Seifert <doug@dseifert.net>
53
+
54
+ License
55
+ -------
56
+
57
+ The MIT License
58
+
59
+ Copyright (c) 2011 Douglas A. Seifert
60
+
61
+ Permission is hereby granted, free of charge, to any person obtaining
62
+ a copy of this software and associated documentation files (the
63
+ 'Software'), to deal in the Software without restriction, including
64
+ without limitation the rights to use, copy, modify, merge, publish,
65
+ distribute, sublicense, and/or sell copies of the Software, and to
66
+ permit persons to whom the Software is furnished to do so, subject to
67
+ the following conditions:
68
+
69
+ The above copyright notice and this permission notice shall be
70
+ included in all copies or substantial portions of the Software.
71
+
72
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
73
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
74
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
75
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
76
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
77
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
78
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'bones'
3
+ rescue LoadError
4
+ abort '### Please install the "bones" gem ###'
5
+ end
6
+
7
+ task :default => 'test:run'
8
+ task 'gem:release' => 'test:run'
9
+
10
+ Bones {
11
+ name 'activemessaging-kestrel-adapter'
12
+ authors 'Douglas A. Seifert'
13
+ email 'doug@dseifert.net'
14
+ url 'http://github.org/seifertd/activemessaging-kestrel-adapter'
15
+ ignore_file '.gitignore'
16
+ readme_file 'README.md'
17
+ version '0.0.1'
18
+
19
+ depend_on 'memcache-client'
20
+
21
+ rdoc.include << 'README.md'
22
+
23
+ }
24
+
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(
4
+ File.join(File.dirname(__FILE__), %w[.. lib activemessaging-kestrel-adapter]))
5
+
6
+ # Put your code here
7
+
@@ -0,0 +1,8 @@
1
+ development:
2
+ servers: localhost:22133
3
+
4
+ test:
5
+ servers: localhost:22133
6
+
7
+ production:
8
+ servers: localhost:22133
@@ -0,0 +1,97 @@
1
+ require 'memcache'
2
+ require 'activemessaging/adapters/base'
3
+
4
+ module ActiveMessaging
5
+ module Adapters
6
+ # This module contains code to integrate the ActiveMessaging framework with a
7
+ # kestrel message queue server.
8
+ module Kestrel
9
+ # Simple struct for wrapping received messages
10
+ Message = Struct.new(:headers, :body, :command)
11
+
12
+ # Connection to a kestrel message queue server
13
+ class Connection < ActiveMessaging::Adapters::Base::Connection
14
+ include ActiveMessaging::Adapter
15
+ register :kestrel
16
+ attr_accessor :reliable
17
+ # Time to sleep between polls of empty queues
18
+ attr_accessor :receive_throttle
19
+ # Reconnect on error
20
+ attr_accessor :error_policy
21
+
22
+ def initialize(cfg)
23
+ @receive_throttle = cfg.delete(:receive_throttle) || 0.1
24
+ # TODO: Implement error policies
25
+ @error_policy = cfg.delete(:error_policy) || :reconnect
26
+ @config = cfg
27
+ @queues = {}
28
+ connect
29
+ nil
30
+ end
31
+
32
+ # Connect to the kestrel server using a Memcached client
33
+ def connect
34
+ @kestrel = MemCache.new(@config)
35
+ @kestrel.servers = @config[:servers]
36
+ end
37
+
38
+ # Subscribe to the named destination and begin receiving
39
+ # messages from it
40
+ def subscribe(destination_name, headers = {})
41
+ headers[:destination] = destination_name
42
+ if @queues[destination_name]
43
+ # TODO: Should you get an exception or no?
44
+ else
45
+ @queues[destination_name] = headers
46
+ end
47
+ nil
48
+ end
49
+
50
+ # Stop receiving messages from the named destination
51
+ def unsubscribe(destination_name, headers = {})
52
+ @queues.delete(destination_name)
53
+ end
54
+
55
+ # Send a message to the named destination. headers can
56
+ # include any of the following keys:
57
+ # :ttl => Set the time to live of the message in seconds
58
+ def send(destination_name, body, headers = {})
59
+ ttl = (headers[:ttl] || 0).to_i
60
+ if ttl <= 0
61
+ @kestrel.set(normalize(destination_name), body)
62
+ else
63
+ @kestrel.set(normalize(destination_name), body, ttl)
64
+ end
65
+ end
66
+
67
+ # Gets a message from any subscribed destination and returns it as a
68
+ # ActiveMessaging::Adaptors::Kestrel::Message object
69
+ def receive
70
+ # TODO: Is this what ActiveMessaging expects: can it handle a nil return?
71
+ #while (true)
72
+ # Get a message from a subscribed queue, but don't favor any queue over another
73
+ queues_to_check = @queues.size > 1 ? @queues.keys.sort_by{rand} : @queues.keys
74
+ queues_to_check.each do |queue|
75
+ if item = @kestrel.get(normalize(queue))
76
+ # TODO: ActiveMessaging ought to provide a way to do messaging
77
+ # without having to wrap the messages in another object
78
+ return Message.new({'destination' => queue}, item, 'MESSAGE')
79
+ end
80
+ end
81
+ # # Sleep a bit so we don't get into a spinloop
82
+ # sleep @receive_throttle
83
+ #end
84
+ return nil
85
+ end
86
+
87
+ private
88
+ def normalize(name)
89
+ # Kestrel doesn't like '/' chars in queue names, so get rid of them
90
+ # (and memoize the calculation)
91
+ @normalized_names ||= Hash.new {|h,k| h[k] = k.gsub('/', '--FS--')}
92
+ @normalized_names[name]
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,60 @@
1
+
2
+ module ActivemessagingKestrelAdapter
3
+
4
+ # :stopdoc:
5
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
+ VERSION = ::File.read(PATH + 'version.txt').strip
8
+ # :startdoc:
9
+
10
+ # Returns the library path for the module. If any arguments are given,
11
+ # they will be joined to the end of the libray path using
12
+ # <tt>File.join</tt>.
13
+ #
14
+ def self.libpath( *args )
15
+ rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
16
+ if block_given?
17
+ begin
18
+ $LOAD_PATH.unshift LIBPATH
19
+ rv = yield
20
+ ensure
21
+ $LOAD_PATH.shift
22
+ end
23
+ end
24
+ return rv
25
+ end
26
+
27
+ # Returns the lpath for the module. If any arguments are given,
28
+ # they will be joined to the end of the path using
29
+ # <tt>File.join</tt>.
30
+ #
31
+ def self.path( *args )
32
+ rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
33
+ if block_given?
34
+ begin
35
+ $LOAD_PATH.unshift PATH
36
+ rv = yield
37
+ ensure
38
+ $LOAD_PATH.shift
39
+ end
40
+ end
41
+ return rv
42
+ end
43
+
44
+ # Utility method used to require all files ending in .rb that lie in the
45
+ # directory below this file that has the same name as the filename passed
46
+ # in. Optionally, a specific _directory_ name can be passed in such that
47
+ # the _filename_ does not have to be equivalent to the directory.
48
+ #
49
+ def self.require_all_libs_relative_to( fname, dir = nil )
50
+ dir ||= ::File.basename(fname, '.*')
51
+ search_me = ::File.expand_path(
52
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
53
+
54
+ Dir.glob(search_me).sort.each {|rb| require rb}
55
+ end
56
+
57
+ end # module ActivemessagingKestrelAdapter
58
+
59
+ ActivemessagingKestrelAdapter.require_all_libs_relative_to(__FILE__, 'active_messaging')
60
+
@@ -0,0 +1,6 @@
1
+
2
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
3
+
4
+ describe ActivemessagingKestrelAdapter do
5
+ end
6
+
@@ -0,0 +1,15 @@
1
+
2
+ require File.expand_path(
3
+ File.join(File.dirname(__FILE__), %w[.. lib activemessaging-kestrel-adapter]))
4
+
5
+ Spec::Runner.configure do |config|
6
+ # == Mock Framework
7
+ #
8
+ # RSpec uses it's own mocking framework by default. If you prefer to
9
+ # use mocha, flexmock or RR, uncomment the appropriate line:
10
+ #
11
+ # config.mock_with :mocha
12
+ # config.mock_with :flexmock
13
+ # config.mock_with :rr
14
+ end
15
+
File without changes
data/version.txt ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activemessaging-kestrel-adapter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Douglas A. Seifert
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-02 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: memcache-client
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 49
30
+ segments:
31
+ - 1
32
+ - 8
33
+ - 3
34
+ version: 1.8.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: bones
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 3
48
+ - 6
49
+ - 2
50
+ version: 3.6.2
51
+ type: :development
52
+ version_requirements: *id002
53
+ description: |-
54
+ This is an adapter to the kestrel messaging server for the ActiveMessaging framework. It is
55
+ in the early stages of development.
56
+ email: doug@dseifert.net
57
+ executables:
58
+ - activemessaging-kestrel-adapter
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - History.txt
63
+ - README.md
64
+ - bin/activemessaging-kestrel-adapter
65
+ files:
66
+ - .Rakefile.swp
67
+ - .bnsignore
68
+ - History.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/activemessaging-kestrel-adapter
72
+ - config/kestrel.yml.sample
73
+ - lib/active_messaging/adapters/kestrel.rb
74
+ - lib/activemessaging-kestrel-adapter.rb
75
+ - spec/activemessaging-kestrel-adapter_spec.rb
76
+ - spec/spec_helper.rb
77
+ - test/test_activemessaging-kestrel-adapter.rb
78
+ - version.txt
79
+ has_rdoc: true
80
+ homepage: http://github.org/seifertd/activemessaging-kestrel-adapter
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options:
85
+ - --main
86
+ - README.md
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ requirements: []
108
+
109
+ rubyforge_project: activemessaging-kestrel-adapter
110
+ rubygems_version: 1.3.7
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: This is an adapter to the kestrel messaging server for the ActiveMessaging framework.
114
+ test_files:
115
+ - test/test_activemessaging-kestrel-adapter.rb