serf 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.travis.yml +7 -0
- data/Gemfile +20 -26
- data/Guardfile +16 -0
- data/NOTICE.txt +1 -1
- data/README.md +223 -207
- data/Rakefile +3 -18
- data/lib/serf/builder.rb +31 -136
- data/lib/serf/errors/policy_failure.rb +10 -0
- data/lib/serf/middleware/error_handler.rb +53 -0
- data/lib/serf/middleware/parcel_freezer.rb +36 -0
- data/lib/serf/middleware/parcel_masher.rb +39 -0
- data/lib/serf/middleware/policy_checker.rb +31 -0
- data/lib/serf/middleware/uuid_tagger.rb +13 -11
- data/lib/serf/parcel_builder.rb +30 -0
- data/lib/serf/serfer.rb +27 -66
- data/lib/serf/util/error_handling.rb +13 -36
- data/lib/serf/util/protected_call.rb +2 -2
- data/lib/serf/util/uuidable.rb +14 -38
- data/lib/serf/version.rb +1 -1
- data/schemas/{caught_exception_event.json → serf/events/caught_error.json} +4 -7
- data/serf.gemspec +22 -101
- data/spec/serf/builder_spec.rb +44 -0
- data/spec/serf/errors/policy_failure_spec.rb +11 -0
- data/spec/serf/middleware/error_handler_spec.rb +48 -0
- data/spec/serf/middleware/parcel_freezer_spec.rb +20 -0
- data/spec/serf/middleware/parcel_masher_spec.rb +30 -0
- data/spec/serf/middleware/policy_checker_spec.rb +70 -0
- data/spec/serf/middleware/uuid_tagger_spec.rb +32 -0
- data/spec/serf/parcel_builder_spec.rb +46 -0
- data/spec/serf/serfer_spec.rb +61 -0
- data/spec/serf/util/error_handling_spec.rb +35 -0
- data/spec/serf/util/null_object_spec.rb +26 -0
- data/spec/serf/util/options_extraction_spec.rb +62 -0
- data/spec/serf/util/protected_call_spec.rb +33 -0
- data/spec/serf/util/uuidable_spec.rb +56 -0
- data/spec/serf_spec.rb +1 -4
- data/spec/spec_helper.rb +3 -0
- data/spec/support/error_handling_wrapper.rb +5 -0
- data/spec/support/factories.rb +32 -0
- data/spec/support/failing_policy.rb +9 -0
- data/spec/support/json_schema_tester.rb +14 -0
- data/spec/support/options_extraction_wrapper.rb +10 -0
- data/spec/support/passing_policy.rb +7 -0
- data/spec/support/protected_call_wrapper.rb +5 -0
- metadata +81 -131
- data/.document +0 -5
- data/.rspec +0 -1
- data/Gemfile.lock +0 -58
- data/docs/thread_pools.txt +0 -16
- data/lib/serf/command.rb +0 -79
- data/lib/serf/error.rb +0 -11
- data/lib/serf/errors/not_found.rb +0 -8
- data/lib/serf/middleware/girl_friday_async.rb +0 -39
- data/lib/serf/middleware/masherize.rb +0 -25
- data/lib/serf/routing/regexp_matcher.rb +0 -35
- data/lib/serf/routing/route.rb +0 -35
- data/lib/serf/routing/route_set.rb +0 -64
- data/schemas/message_accepted_event.json +0 -14
data/lib/serf/command.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'active_support/concern'
|
2
|
-
require 'active_support/core_ext/class/attribute'
|
3
|
-
|
4
|
-
require 'serf/util/error_handling'
|
5
|
-
require 'serf/util/options_extraction'
|
6
|
-
require 'serf/util/protected_call'
|
7
|
-
require 'serf/util/uuidable'
|
8
|
-
|
9
|
-
module Serf
|
10
|
-
|
11
|
-
##
|
12
|
-
# A base class for Serf users to implement a Command pattern.
|
13
|
-
#
|
14
|
-
# class MyCommand
|
15
|
-
# include Serf::Command
|
16
|
-
#
|
17
|
-
# def initialize(*contructor_params, &block)
|
18
|
-
# # Do some validation here, or extra parameter setting with the args
|
19
|
-
# @model = opts :model, MyModel
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# def call(request, context)
|
23
|
-
# # Do something w/ request, opts and context.
|
24
|
-
# item = @model.find request.model_id
|
25
|
-
# # create a new hashie of UUIDs, which we will use as the base
|
26
|
-
# # hash of our response
|
27
|
-
# response = create_uuids request
|
28
|
-
# response.kind = 'my_command/events/did_something'
|
29
|
-
# response.item = item
|
30
|
-
# return response
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# constructor_params = [1, 2, 3, 4, etc]
|
35
|
-
# block = Proc.new {}
|
36
|
-
# request = ::Hashie::Mash.new
|
37
|
-
# context = ::Hashie::Mash.new user: current_user
|
38
|
-
# MyCommand.call(request, context, *contructor_params, &block)
|
39
|
-
#
|
40
|
-
module Command
|
41
|
-
extend ActiveSupport::Concern
|
42
|
-
|
43
|
-
# Including Serf::Util::*... Order matters, kind of, here.
|
44
|
-
include Serf::Util::Uuidable
|
45
|
-
include Serf::Util::OptionsExtraction
|
46
|
-
include Serf::Util::ProtectedCall
|
47
|
-
include Serf::Util::ErrorHandling
|
48
|
-
|
49
|
-
def call(request, context=nil *args, &block)
|
50
|
-
raise NotImplementedError
|
51
|
-
end
|
52
|
-
|
53
|
-
module ClassMethods
|
54
|
-
|
55
|
-
##
|
56
|
-
# Class method that both builds then executes the unit of work.
|
57
|
-
#
|
58
|
-
# @param request the request
|
59
|
-
# @param context the context about the request. Things like the
|
60
|
-
# requesting :user for ACL.
|
61
|
-
# @param *args remaining contructor arguments
|
62
|
-
# @param &block the block to pass to constructor
|
63
|
-
#
|
64
|
-
def call(request, context=::Hashie::Mash.new, *args, &block)
|
65
|
-
self.build(*args, &block).call(request, context)
|
66
|
-
end
|
67
|
-
|
68
|
-
##
|
69
|
-
# Factory build method that creates an object of the implementing
|
70
|
-
# class' unit of work with the given parameters. By default,
|
71
|
-
# This just calls the class new method.
|
72
|
-
#
|
73
|
-
def build(*args, &block)
|
74
|
-
new *args, &block
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/lib/serf/error.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'girl_friday'
|
2
|
-
|
3
|
-
require 'serf/util/options_extraction'
|
4
|
-
require 'serf/util/uuidable'
|
5
|
-
|
6
|
-
module Serf
|
7
|
-
module Middleware
|
8
|
-
|
9
|
-
class GirlFridayAsync
|
10
|
-
include Serf::Util::OptionsExtraction
|
11
|
-
|
12
|
-
attr_reader :uuidable
|
13
|
-
attr_reader :queue
|
14
|
-
|
15
|
-
def initialize(app, *args)
|
16
|
-
extract_options! args
|
17
|
-
|
18
|
-
@uuidable = opts :uuidable, Serf::Util::Uuidable
|
19
|
-
|
20
|
-
@queue = ::GirlFriday::WorkQueue.new(
|
21
|
-
opts(:name, :serf_runner),
|
22
|
-
:size => opts(:workers, 1)) do |env|
|
23
|
-
app.call env
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def call(env)
|
28
|
-
queue.push env
|
29
|
-
response = uuidable.create_uuids env.message
|
30
|
-
response.kind = 'serf/messages/message_accepted_event'
|
31
|
-
response.message = env.message
|
32
|
-
response.context = env.context
|
33
|
-
return response
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'hashie'
|
2
|
-
|
3
|
-
module Serf
|
4
|
-
module Middleware
|
5
|
-
|
6
|
-
##
|
7
|
-
# Middleware to turn an env into a Hashie::Mash.
|
8
|
-
#
|
9
|
-
class Masherize
|
10
|
-
|
11
|
-
##
|
12
|
-
# @param app the app
|
13
|
-
#
|
14
|
-
def initialize(app)
|
15
|
-
@app = app
|
16
|
-
end
|
17
|
-
|
18
|
-
def call(env)
|
19
|
-
@app.call Hashie::Mash.new(env)
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'serf/util/options_extraction'
|
2
|
-
|
3
|
-
module Serf
|
4
|
-
module Routing
|
5
|
-
|
6
|
-
##
|
7
|
-
# A matcher that does a regexp match on a specific field
|
8
|
-
# in the given Env. By default, we use this to do regexp matching
|
9
|
-
# on message kinds for routing.
|
10
|
-
#
|
11
|
-
class RegexpMatcher
|
12
|
-
include Serf::Util::OptionsExtraction
|
13
|
-
|
14
|
-
attr_reader :regexp
|
15
|
-
attr_reader :field
|
16
|
-
|
17
|
-
def initialize(regexp, *args)
|
18
|
-
extract_options! args
|
19
|
-
|
20
|
-
@regexp = regexp
|
21
|
-
@field = opts :field, :kind
|
22
|
-
end
|
23
|
-
|
24
|
-
def ===(env)
|
25
|
-
return regexp === env[field]
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.build(*args, &block)
|
29
|
-
new *args, &block
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
data/lib/serf/routing/route.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require 'serf/util/options_extraction'
|
2
|
-
|
3
|
-
module Serf
|
4
|
-
module Routing
|
5
|
-
|
6
|
-
class Route
|
7
|
-
include Serf::Util::OptionsExtraction
|
8
|
-
|
9
|
-
attr_reader :policies
|
10
|
-
attr_reader :command
|
11
|
-
|
12
|
-
def initialize(*args, &block)
|
13
|
-
extract_options! args
|
14
|
-
@policies = opts :policies, []
|
15
|
-
@command = opts! :command
|
16
|
-
end
|
17
|
-
|
18
|
-
def check_policies!(request, context)
|
19
|
-
for policy in policies do
|
20
|
-
policy.check! request, context
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def execute!(*args, &block)
|
25
|
-
command.call *args, &block
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.build(*args, &block)
|
29
|
-
new *args, &block
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'serf/routing/regexp_matcher'
|
2
|
-
require 'serf/util/options_extraction'
|
3
|
-
|
4
|
-
module Serf
|
5
|
-
module Routing
|
6
|
-
|
7
|
-
##
|
8
|
-
# RouteSet resolves a list of matched routes to execute based on
|
9
|
-
# criteria from associated 'matcher' objects.
|
10
|
-
#
|
11
|
-
class RouteSet
|
12
|
-
include Serf::Util::OptionsExtraction
|
13
|
-
|
14
|
-
attr_reader :routes
|
15
|
-
attr_reader :matchers
|
16
|
-
attr_reader :regexp_matcher_factory
|
17
|
-
|
18
|
-
def initialize(*args, &block)
|
19
|
-
extract_options! args
|
20
|
-
@routes = {}
|
21
|
-
@matchers = []
|
22
|
-
@regexp_matcher_factory = opts(
|
23
|
-
:regexp_matcher_factory,
|
24
|
-
::Serf::Routing::RegexpMatcher)
|
25
|
-
end
|
26
|
-
|
27
|
-
##
|
28
|
-
# Connects a matcher (String or an Object implementing ===) to routes.
|
29
|
-
#
|
30
|
-
def add(matcher, route)
|
31
|
-
# Maybe we have an non-String matcher. Handle the Regexp case.
|
32
|
-
# We only keep track of matchers if it isn't a string because
|
33
|
-
# string matchers are just pulled out of routes by key lookup.
|
34
|
-
matcher = regexp_matcher_factory.build matcher if matcher.kind_of? Regexp
|
35
|
-
matchers << matcher unless matcher.is_a? String
|
36
|
-
|
37
|
-
# We add the (matcher+routes) into our routes
|
38
|
-
routes[matcher] ||= []
|
39
|
-
routes[matcher].push route
|
40
|
-
end
|
41
|
-
|
42
|
-
##
|
43
|
-
# @param [Hash] request The input message to match for routes.
|
44
|
-
# @return [Array] List of routes that matched.
|
45
|
-
#
|
46
|
-
def resolve(request, context)
|
47
|
-
resolved_routes = []
|
48
|
-
resolved_routes.concat routes.fetch(request[:kind]) { [] }
|
49
|
-
matchers.each do |matcher|
|
50
|
-
resolved_routes.concat routes[matcher] if matcher === request
|
51
|
-
end
|
52
|
-
return resolved_routes
|
53
|
-
end
|
54
|
-
|
55
|
-
##
|
56
|
-
# Default factory method.
|
57
|
-
#
|
58
|
-
def self.build(*args, &block)
|
59
|
-
new *args, &block
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|