serf 0.10.0 → 0.11.0
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/.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
|