activemessaging-kestrel-adapter 0.0.1

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/.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