serf 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -4
- data/Gemfile.lock +27 -17
- data/README.md +317 -120
- data/docs/thread_pools.txt +16 -0
- data/lib/serf/builder.rb +126 -162
- data/lib/serf/command.rb +113 -0
- data/lib/serf/message.rb +16 -2
- data/lib/serf/messages/caught_exception_event.rb +10 -7
- data/lib/serf/routing/endpoint.rb +49 -0
- data/lib/serf/routing/registry.rb +66 -0
- data/lib/serf/runners/direct.rb +52 -0
- data/lib/serf/runners/event_machine.rb +71 -0
- data/lib/serf/runners/girl_friday.rb +73 -0
- data/lib/serf/runners/helper.rb +23 -0
- data/lib/serf/serfer.rb +112 -25
- data/lib/serf/util/{with_error_handling.rb → error_handling.rb} +23 -10
- data/lib/serf/util/options_extraction.rb +106 -0
- data/lib/serf/version.rb +2 -2
- data/serf.gemspec +31 -20
- metadata +60 -33
- data/lib/serf/runners/direct_runner.rb +0 -60
- data/lib/serf/runners/em_runner.rb +0 -62
- data/lib/serf/util/route_endpoint.rb +0 -37
- data/lib/serf/util/route_set.rb +0 -82
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'serf/runners/helper'
|
2
|
+
require 'serf/util/error_handling'
|
3
|
+
|
4
|
+
module Serf
|
5
|
+
module Runners
|
6
|
+
|
7
|
+
##
|
8
|
+
# Direct runner drives the execution of a handler for given messages.
|
9
|
+
# This class deals with error handling and pushing handler results
|
10
|
+
# to proper error or results channels.
|
11
|
+
#
|
12
|
+
# NOTES:
|
13
|
+
# * Results returned from handlers are pushed to response channel.
|
14
|
+
# * Errors raised by handlers are pushed to error channel, not response.
|
15
|
+
#
|
16
|
+
class Direct
|
17
|
+
include Serf::Util::ErrorHandling
|
18
|
+
include Serf::Runners::Helper
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
extract_options! args
|
22
|
+
opts! :response_channel
|
23
|
+
end
|
24
|
+
|
25
|
+
def call(handlers, context)
|
26
|
+
results = []
|
27
|
+
handlers.each do |handler|
|
28
|
+
ok, run_result = with_error_handling(context) do
|
29
|
+
handler.call
|
30
|
+
end
|
31
|
+
run_result = run_result.is_a?(Hash) ? [run_result] : Array(run_result)
|
32
|
+
|
33
|
+
# We only post to the response channel if we didn't catch and error.
|
34
|
+
# But we add both error and success results to the 'results' to
|
35
|
+
# pass back to the caller of the runner. This may be a background
|
36
|
+
# runner, which then the results are ignored. But it may have been
|
37
|
+
# the Serfer, which means all results should go back to the user
|
38
|
+
# as this was a foreground (synchronous) execution.
|
39
|
+
results.concat run_result
|
40
|
+
push_results run_result if ok
|
41
|
+
end
|
42
|
+
return results
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.build(options={})
|
46
|
+
self.new options
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
require 'serf/messages/message_accepted_event'
|
4
|
+
require 'serf/runners/direct'
|
5
|
+
require 'serf/util/error_handling'
|
6
|
+
|
7
|
+
module Serf
|
8
|
+
module Runners
|
9
|
+
|
10
|
+
##
|
11
|
+
# This runner simply wraps another runner to execute in the
|
12
|
+
# EventMachine deferred threadpool.
|
13
|
+
#
|
14
|
+
# NOTE: Because the Serfer class validates messages before
|
15
|
+
# sending them to runners (and handlers), this class simply
|
16
|
+
# responds to the calling client with an 'MessageAcceptedEvent'
|
17
|
+
# to signal that the message will be processed later.
|
18
|
+
#
|
19
|
+
# Errors caught here will simply be logged. This is because
|
20
|
+
# the wrapped runner *MUST* handle its own errors. If an error
|
21
|
+
# should propagate up here, then it was most likely an error
|
22
|
+
# that occurred in a rescue block... we don't want to complicate
|
23
|
+
# any extra pushing to error channels because that may have
|
24
|
+
# been the cause of the error.
|
25
|
+
#
|
26
|
+
class EventMachine
|
27
|
+
include Serf::Util::ErrorHandling
|
28
|
+
|
29
|
+
def initialize(*args)
|
30
|
+
extract_options! args
|
31
|
+
|
32
|
+
# Manditory: Need a runner because this class is just a wrapper.
|
33
|
+
@runner = opts! :runner
|
34
|
+
|
35
|
+
@mae_class = opts(
|
36
|
+
:message_accepted_event_class,
|
37
|
+
::Serf::Messages::MessageAcceptedEvent)
|
38
|
+
|
39
|
+
@evm = opts :event_machine, ::EventMachine
|
40
|
+
@logger = opts :logger, ::Serf::Util::NullObject.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def call(handlers, context)
|
44
|
+
# This queues up each handler to be run separately.
|
45
|
+
handlers.each do |handler|
|
46
|
+
@evm.defer(proc do
|
47
|
+
begin
|
48
|
+
with_error_handling(context) do
|
49
|
+
@runner.call [handler], context
|
50
|
+
end
|
51
|
+
rescue => e
|
52
|
+
@logger.fatal(
|
53
|
+
"EventMachineThread: #{e.inspect}\n\n#{e.backtrace.join("\n")}")
|
54
|
+
end
|
55
|
+
end)
|
56
|
+
end
|
57
|
+
return @mae_class.new(message: context)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.build(options={})
|
61
|
+
options[:runner] = options.fetch(:runner) {
|
62
|
+
factory = options[:runner_factory] || ::Serf::Runners::Direct
|
63
|
+
factory.build options
|
64
|
+
}
|
65
|
+
self.new options
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'girl_friday'
|
2
|
+
|
3
|
+
require 'serf/messages/message_accepted_event'
|
4
|
+
require 'serf/runners/helper'
|
5
|
+
require 'serf/util/error_handling'
|
6
|
+
|
7
|
+
module Serf
|
8
|
+
module Runners
|
9
|
+
|
10
|
+
##
|
11
|
+
#
|
12
|
+
class GirlFriday
|
13
|
+
include Serf::Util::ErrorHandling
|
14
|
+
include Serf::Runners::Helper
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
extract_options! args
|
18
|
+
|
19
|
+
# Mandatory response channel.
|
20
|
+
opts! :response_channel
|
21
|
+
|
22
|
+
# Create our worker queue that will accept tasks (handler and context).
|
23
|
+
# The worker is just a block that passes on the task to the
|
24
|
+
# actual worker method.
|
25
|
+
@queue = ::GirlFriday::WorkQueue.new(
|
26
|
+
opts(:queue_name, :serf_runner),
|
27
|
+
:size => opts(:queue_size, 1)) do |task|
|
28
|
+
perform task
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(handlers, context)
|
33
|
+
# Create our accepted event before we enqueue the handlers.
|
34
|
+
mae_class = opts(
|
35
|
+
:message_accepted_event_class,
|
36
|
+
::Serf::Messages::MessageAcceptedEvent)
|
37
|
+
event = mae_class.new message: context
|
38
|
+
|
39
|
+
# Push each handler into the queue along with a copy of the context.
|
40
|
+
handlers.each do |handler|
|
41
|
+
@queue.push(
|
42
|
+
handler: handler,
|
43
|
+
context: context.dup)
|
44
|
+
end
|
45
|
+
|
46
|
+
# We got here, we succeeded pushing all the works.
|
47
|
+
# Now we return our accepted event.
|
48
|
+
return event
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Builder method
|
53
|
+
#
|
54
|
+
def self.build(*args)
|
55
|
+
self.new *args
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Actually drives the execution of individual handlers passed to job
|
60
|
+
# queue.
|
61
|
+
#
|
62
|
+
def perform(task)
|
63
|
+
with_error_handling(task[:context]) do
|
64
|
+
task[:handler].call
|
65
|
+
run_result = run_result.is_a?(Hash) ? [run_result] : Array(run_result)
|
66
|
+
push_results run_result
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Serf
|
2
|
+
module Runners
|
3
|
+
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
##
|
7
|
+
# Loop over the results and push them to the response channel.
|
8
|
+
# Any error in pushing individual messages will result in
|
9
|
+
# a log event and an error channel event.
|
10
|
+
def push_results(results)
|
11
|
+
response_channel = opts! :response_channel
|
12
|
+
results.each do |message|
|
13
|
+
with_error_handling(message) do
|
14
|
+
response_channel.push message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/serf/serfer.rb
CHANGED
@@ -1,60 +1,147 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
1
3
|
require 'serf/error'
|
2
|
-
require 'serf/util/
|
4
|
+
require 'serf/util/error_handling'
|
3
5
|
|
4
6
|
module Serf
|
5
7
|
|
6
8
|
class Serfer
|
7
|
-
include ::Serf::Util::
|
9
|
+
include ::Serf::Util::ErrorHandling
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
extract_options! args
|
8
13
|
|
9
|
-
|
10
|
-
|
11
|
-
@route_sets = options[:route_sets] || {}
|
14
|
+
# Map of Runners to Registries
|
15
|
+
@registries = opts :registries, {}
|
12
16
|
|
13
|
-
#
|
14
|
-
@
|
15
|
-
@error_event_class = options[:error_event_class]
|
16
|
-
@logger = options[:logger]
|
17
|
+
# Additional serf infrastructure options to pass to Endpoints#build.
|
18
|
+
@serf_options = opts :serf_options, {}
|
17
19
|
|
18
20
|
# Options for handling the requests
|
19
|
-
@not_found =
|
21
|
+
@not_found = opts :not_found, lambda { |env|
|
20
22
|
raise ArgumentError, 'Handler Not Found'
|
21
|
-
|
23
|
+
}
|
22
24
|
end
|
23
25
|
|
24
26
|
##
|
25
|
-
# Rack-like call to run set of handlers for a message
|
27
|
+
# Rack-like call to run a set of handlers for a message
|
26
28
|
#
|
27
29
|
def call(env)
|
28
30
|
# We normalize by symbolizing the env keys
|
29
31
|
env = env.symbolize_keys
|
30
32
|
|
31
|
-
#
|
32
|
-
|
33
|
-
results = []
|
34
|
-
@route_sets.each do |route_set, runner|
|
35
|
-
with_error_handling(env) do
|
36
|
-
endpoints = route_set.match_routes env
|
37
|
-
if endpoints.size > 0
|
38
|
-
matched_routes = true
|
39
|
-
results.concat Array(runner.run(endpoints, env))
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
33
|
+
# Call the processor
|
34
|
+
matched, results = process_request env
|
43
35
|
|
44
36
|
# If we don't have any handlers, do the not_found call.
|
45
37
|
# NOTE: Purposefully not wrapping this in exception handling.
|
46
|
-
return @not_found.call env unless
|
38
|
+
return @not_found.call env unless matched > 0
|
47
39
|
|
48
40
|
return results
|
49
41
|
rescue => e
|
50
42
|
e.extend(::Serf::Error)
|
51
43
|
raise e
|
52
44
|
end
|
45
|
+
alias_method :push, :call
|
46
|
+
alias_method :<<, :call
|
53
47
|
|
54
48
|
def self.build(options={})
|
55
49
|
self.new options
|
56
50
|
end
|
57
51
|
|
52
|
+
protected
|
53
|
+
|
54
|
+
##
|
55
|
+
# Do the work of processing the env.
|
56
|
+
# 1. Match our endpoints to run, keep associated with their runner.
|
57
|
+
# 2. Turn endpoints into actual handlers that can be called by runners.
|
58
|
+
# 3. Call runner to process the endpoints
|
59
|
+
# 4. Return results
|
60
|
+
#
|
61
|
+
# NOTES:
|
62
|
+
# * Any error in matching will be raised to the caller, not absorbed by
|
63
|
+
# the error handler.
|
64
|
+
# * Any error in Handler creation from endpoint will be caught by the
|
65
|
+
# error handler, (1) pushed to the error channel and (2)
|
66
|
+
# an error event will included in the results pass back to caller.
|
67
|
+
# (a) There may be successul handlers created that can complete.
|
68
|
+
# * If the runner raises an error, it will be caught and the error
|
69
|
+
# event will be appended to the results. This is so one
|
70
|
+
# runner failure will not affect another runner's run.
|
71
|
+
# Each runner SHOULD do their own error handling so errors in
|
72
|
+
# one handler will not affect another in the list of handlers the runner
|
73
|
+
# is to process.
|
74
|
+
# * RUNNERS MUST push errors they catch to the error channel.
|
75
|
+
#
|
76
|
+
def process_request(env)
|
77
|
+
# This will be the work we need to do.
|
78
|
+
# This is a hash of runners to handlers to run.
|
79
|
+
tasks = {}
|
80
|
+
|
81
|
+
# We're going to concat all the results
|
82
|
+
results = []
|
83
|
+
|
84
|
+
# Figure out which endpoints to run.
|
85
|
+
matches = match_endpoints env
|
86
|
+
|
87
|
+
# Now we go head and create our Tasks (Units of Work)
|
88
|
+
# for each of the matched endpoints (with their runners).
|
89
|
+
matches.each do |runner, endpoints|
|
90
|
+
# We create the unit of work
|
91
|
+
handlers = endpoints.map{ |endpoint|
|
92
|
+
# We try to build the endpoint. Any errors here will
|
93
|
+
# be caught and returned to the caller.
|
94
|
+
# This is so individual building of tasks do not affect other tasks.
|
95
|
+
ok, obj = with_error_handling(env) do
|
96
|
+
endpoint.build env.dup, @serf_options
|
97
|
+
end
|
98
|
+
# The return of this if/else statement will be result of map item.
|
99
|
+
if ok
|
100
|
+
obj
|
101
|
+
else
|
102
|
+
results << obj
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
}.
|
106
|
+
select{ |h| !h.nil? }
|
107
|
+
|
108
|
+
# No we enqueue the units of work into our task queue
|
109
|
+
# List could be empty because all build calls could have error out.
|
110
|
+
tasks[runner] = handlers if handlers.size > 0
|
111
|
+
end
|
112
|
+
|
113
|
+
# We call the runners with the handlers they need to execute.
|
114
|
+
# Errors raised by the runner are pushed to the error channel.
|
115
|
+
# Errors here are also passed back the caller of the SerfApp.
|
116
|
+
#
|
117
|
+
tasks.each do |runner, handlers|
|
118
|
+
ok, run_result = with_error_handling(env) do
|
119
|
+
runner.call handlers, env
|
120
|
+
end
|
121
|
+
# We need to coerce the runner's results (nil, Hash, Array, Object)
|
122
|
+
# into an Array of messages.
|
123
|
+
# now we concat this run's results to our total results list.
|
124
|
+
run_result = run_result.is_a?(Hash) ? [run_result] : Array(run_result)
|
125
|
+
results.concat run_result
|
126
|
+
end
|
127
|
+
|
128
|
+
return matches.size, results
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Figure out which endpoints to run
|
133
|
+
#
|
134
|
+
def match_endpoints(env)
|
135
|
+
matches = {}
|
136
|
+
|
137
|
+
@registries.each do |runner, registry|
|
138
|
+
endpoints = registry.match env
|
139
|
+
matches[runner] = endpoints if endpoints.size > 0
|
140
|
+
end
|
141
|
+
|
142
|
+
return matches
|
143
|
+
end
|
144
|
+
|
58
145
|
end
|
59
146
|
|
60
147
|
end
|
@@ -1,14 +1,18 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
1
3
|
require 'serf/messages/caught_exception_event'
|
2
4
|
require 'serf/util/null_object'
|
5
|
+
require 'serf/util/options_extraction'
|
3
6
|
|
4
7
|
module Serf
|
5
8
|
module Util
|
6
9
|
|
7
10
|
##
|
8
11
|
# Helper module to rescues exceptions from executing blocks of
|
9
|
-
# code, and then logs+
|
12
|
+
# code, and then logs+pushes the error event.
|
10
13
|
#
|
11
|
-
module
|
14
|
+
module ErrorHandling
|
15
|
+
include ::Serf::Util::OptionsExtraction
|
12
16
|
|
13
17
|
##
|
14
18
|
# A block wrapper to handle errors when executing a block.
|
@@ -20,22 +24,31 @@ module Util
|
|
20
24
|
# * @error_channel - ::Serf::Util::NullObject.new
|
21
25
|
#
|
22
26
|
def with_error_handling(context=nil)
|
23
|
-
yield
|
27
|
+
return true, yield
|
24
28
|
rescue => e
|
25
|
-
eec =
|
26
|
-
logger =
|
27
|
-
error_channel =
|
29
|
+
eec = opts :error_event_class, ::Serf::Messages::CaughtExceptionEvent
|
30
|
+
logger = opts :logger, ::Serf::Util::NullObject.new
|
31
|
+
error_channel = opts :error_channel, ::Serf::Util::NullObject.new
|
28
32
|
error_event = eec.new(
|
29
33
|
context: context,
|
30
|
-
|
31
|
-
|
34
|
+
error: e.class.to_s.tableize,
|
35
|
+
message: e.message,
|
36
|
+
backtrace: e.backtrace.join("\n"))
|
32
37
|
|
33
38
|
# log the error to our logger, and to our error channel.
|
34
39
|
logger.error error_event
|
35
|
-
|
40
|
+
begin
|
41
|
+
error_channel.push error_event
|
42
|
+
rescue => e1
|
43
|
+
logger.error("
|
44
|
+
Failed pushing to ErrorChannel:
|
45
|
+
#{e1.message}
|
46
|
+
#{e1.backtrace.join('\n')}
|
47
|
+
")
|
48
|
+
end
|
36
49
|
|
37
50
|
# We're done, so just return this error.
|
38
|
-
return error_event
|
51
|
+
return false, error_event
|
39
52
|
end
|
40
53
|
|
41
54
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Serf
|
2
|
+
module Util
|
3
|
+
|
4
|
+
##
|
5
|
+
# Module that provides helpers for dealing with options hash passed
|
6
|
+
# to initializers.
|
7
|
+
#
|
8
|
+
# class Example
|
9
|
+
# include Serf::Util::OptionsExtraction
|
10
|
+
#
|
11
|
+
# def initialize(*args, &block)
|
12
|
+
# extract_options! args
|
13
|
+
# puts args # Rest of args w/o the options hash.
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def do_work
|
17
|
+
# my_option = opts :my_option, 'Default Value'
|
18
|
+
# puts my_option
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# example = Example.new my_option: 'Another Value'
|
23
|
+
# example.do_work
|
24
|
+
# # => 'Another Value'
|
25
|
+
#
|
26
|
+
module OptionsExtraction
|
27
|
+
|
28
|
+
##
|
29
|
+
# Reader method for the options hash.
|
30
|
+
#
|
31
|
+
def options
|
32
|
+
return @options || {}
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Helper method to lookup an option from our options hash.
|
37
|
+
#
|
38
|
+
# Examples:
|
39
|
+
#
|
40
|
+
# # Optional parameter whose default value is nil.
|
41
|
+
# do_extra = opts :do_extra
|
42
|
+
#
|
43
|
+
# # Optional params that defaults to [1,2,3]
|
44
|
+
# start_array = opts :start_array, [1,2,3]
|
45
|
+
#
|
46
|
+
# Returns default value when:
|
47
|
+
# * Key is non-existent in Options Hash.
|
48
|
+
# * OR when the value of the key in the Options Hash is nil.
|
49
|
+
#
|
50
|
+
# Returns nil when:
|
51
|
+
# * Default is nil and the Options Hash lookup returns a nil.
|
52
|
+
# Options Hash returns a nil because of either a
|
53
|
+
# non-existent key or a nil value in said hash for said key.
|
54
|
+
#
|
55
|
+
def opts(key, default=nil, &block)
|
56
|
+
value = options[key]
|
57
|
+
value = default if value.nil?
|
58
|
+
value = block.call if value.nil? && block
|
59
|
+
return value
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Use this lookup helper if a nil value is unacceptable for processing.
|
64
|
+
#
|
65
|
+
# There are cases where an option may have a default value for a feature,
|
66
|
+
# but the caller may just want to disable said feature. To do so,
|
67
|
+
# users of this module should allow for the caller to pass in 'false'
|
68
|
+
# as an option value instead of nil to disable said feature. The
|
69
|
+
# implementer will have to do a boolean check of the returned option value
|
70
|
+
# and disable accordingly.
|
71
|
+
#
|
72
|
+
# Examples:
|
73
|
+
#
|
74
|
+
# # Has a default logger, but we can disable logging by passing false.
|
75
|
+
# # If caller had passed in nil for :logger, it would have
|
76
|
+
# # defaulted to ::Log4r['my_logger'].
|
77
|
+
# logger = opts! :logger, ::Log4r['my_logger']
|
78
|
+
# logger = Serf::NullObject.new unless logger
|
79
|
+
#
|
80
|
+
# # Here we force the end user to pass in a Non-nil option as a
|
81
|
+
# # mandatory parameter.
|
82
|
+
# max_threads = opts! :max_threads
|
83
|
+
#
|
84
|
+
# Raises error when `opts` returns a nil.
|
85
|
+
#
|
86
|
+
def opts!(key, default=nil, &block)
|
87
|
+
value = opts key, default, &block
|
88
|
+
raise "Nil value found for option: #{key}, #{default}" if value.nil?
|
89
|
+
return value
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
##
|
95
|
+
# Extracts the options from the arguments list.
|
96
|
+
#
|
97
|
+
def extract_options!(args)
|
98
|
+
_, @options = args.last.is_a?(::Hash) ?
|
99
|
+
[true, args.pop.dup] :
|
100
|
+
[false, {}]
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
data/lib/serf/version.rb
CHANGED
data/serf.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "serf"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.7.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Benjamin Yu"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-03-13"
|
13
13
|
s.description = "Event-Driven SOA with CQRS"
|
14
14
|
s.email = "benjaminlyu@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,22 +25,27 @@ Gem::Specification.new do |s|
|
|
25
25
|
"NOTICE.txt",
|
26
26
|
"README.md",
|
27
27
|
"Rakefile",
|
28
|
+
"docs/thread_pools.txt",
|
28
29
|
"lib/serf.rb",
|
29
30
|
"lib/serf/builder.rb",
|
31
|
+
"lib/serf/command.rb",
|
30
32
|
"lib/serf/error.rb",
|
31
33
|
"lib/serf/message.rb",
|
32
34
|
"lib/serf/messages/caught_exception_event.rb",
|
33
35
|
"lib/serf/messages/message_accepted_event.rb",
|
34
36
|
"lib/serf/middleware/uuid_tagger.rb",
|
35
|
-
"lib/serf/
|
36
|
-
"lib/serf/
|
37
|
+
"lib/serf/routing/endpoint.rb",
|
38
|
+
"lib/serf/routing/registry.rb",
|
39
|
+
"lib/serf/runners/direct.rb",
|
40
|
+
"lib/serf/runners/event_machine.rb",
|
41
|
+
"lib/serf/runners/girl_friday.rb",
|
42
|
+
"lib/serf/runners/helper.rb",
|
37
43
|
"lib/serf/serfer.rb",
|
44
|
+
"lib/serf/util/error_handling.rb",
|
38
45
|
"lib/serf/util/null_object.rb",
|
46
|
+
"lib/serf/util/options_extraction.rb",
|
39
47
|
"lib/serf/util/regexp_matcher.rb",
|
40
|
-
"lib/serf/util/route_endpoint.rb",
|
41
|
-
"lib/serf/util/route_set.rb",
|
42
48
|
"lib/serf/util/uuidable.rb",
|
43
|
-
"lib/serf/util/with_error_handling.rb",
|
44
49
|
"lib/serf/version.rb",
|
45
50
|
"serf.gemspec",
|
46
51
|
"spec/serf_spec.rb",
|
@@ -49,7 +54,7 @@ Gem::Specification.new do |s|
|
|
49
54
|
s.homepage = "http://github.com/byu/serf"
|
50
55
|
s.licenses = ["Apache 2.0"]
|
51
56
|
s.require_paths = ["lib"]
|
52
|
-
s.rubygems_version = "1.8.
|
57
|
+
s.rubygems_version = "1.8.17"
|
53
58
|
s.summary = "Event-Driven SOA with CQRS"
|
54
59
|
|
55
60
|
if s.respond_to? :specification_version then
|
@@ -59,36 +64,42 @@ Gem::Specification.new do |s|
|
|
59
64
|
s.add_runtime_dependency(%q<activesupport>, [">= 3.2.0"])
|
60
65
|
s.add_runtime_dependency(%q<i18n>, [">= 0.6.0"])
|
61
66
|
s.add_runtime_dependency(%q<uuidtools>, [">= 2.1.2"])
|
62
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.
|
63
|
-
s.add_development_dependency(%q<yard>, ["~> 0.
|
64
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.
|
65
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.
|
67
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
68
|
+
s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
|
69
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.22"])
|
70
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
66
71
|
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
72
|
+
s.add_development_dependency(%q<log4r>, ["~> 1.1.10"])
|
67
73
|
s.add_development_dependency(%q<msgpack>, [">= 0.4.6"])
|
68
74
|
s.add_development_dependency(%q<eventmachine>, [">= 0.12.10"])
|
75
|
+
s.add_development_dependency(%q<girl_friday>, ["~> 0.9.7"])
|
69
76
|
else
|
70
77
|
s.add_dependency(%q<activesupport>, [">= 3.2.0"])
|
71
78
|
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
72
79
|
s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
|
73
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
74
|
-
s.add_dependency(%q<yard>, ["~> 0.
|
75
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.
|
76
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
80
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
81
|
+
s.add_dependency(%q<yard>, ["~> 0.7.5"])
|
82
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.22"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
77
84
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
85
|
+
s.add_dependency(%q<log4r>, ["~> 1.1.10"])
|
78
86
|
s.add_dependency(%q<msgpack>, [">= 0.4.6"])
|
79
87
|
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
88
|
+
s.add_dependency(%q<girl_friday>, ["~> 0.9.7"])
|
80
89
|
end
|
81
90
|
else
|
82
91
|
s.add_dependency(%q<activesupport>, [">= 3.2.0"])
|
83
92
|
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
84
93
|
s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
|
85
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
86
|
-
s.add_dependency(%q<yard>, ["~> 0.
|
87
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.
|
88
|
-
s.add_dependency(%q<jeweler>, ["~> 1.
|
94
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
95
|
+
s.add_dependency(%q<yard>, ["~> 0.7.5"])
|
96
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.22"])
|
97
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
89
98
|
s.add_dependency(%q<simplecov>, [">= 0"])
|
99
|
+
s.add_dependency(%q<log4r>, ["~> 1.1.10"])
|
90
100
|
s.add_dependency(%q<msgpack>, [">= 0.4.6"])
|
91
101
|
s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
|
102
|
+
s.add_dependency(%q<girl_friday>, ["~> 0.9.7"])
|
92
103
|
end
|
93
104
|
end
|
94
105
|
|