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.
Files changed (59) hide show
  1. data/.gitignore +21 -0
  2. data/.travis.yml +7 -0
  3. data/Gemfile +20 -26
  4. data/Guardfile +16 -0
  5. data/NOTICE.txt +1 -1
  6. data/README.md +223 -207
  7. data/Rakefile +3 -18
  8. data/lib/serf/builder.rb +31 -136
  9. data/lib/serf/errors/policy_failure.rb +10 -0
  10. data/lib/serf/middleware/error_handler.rb +53 -0
  11. data/lib/serf/middleware/parcel_freezer.rb +36 -0
  12. data/lib/serf/middleware/parcel_masher.rb +39 -0
  13. data/lib/serf/middleware/policy_checker.rb +31 -0
  14. data/lib/serf/middleware/uuid_tagger.rb +13 -11
  15. data/lib/serf/parcel_builder.rb +30 -0
  16. data/lib/serf/serfer.rb +27 -66
  17. data/lib/serf/util/error_handling.rb +13 -36
  18. data/lib/serf/util/protected_call.rb +2 -2
  19. data/lib/serf/util/uuidable.rb +14 -38
  20. data/lib/serf/version.rb +1 -1
  21. data/schemas/{caught_exception_event.json → serf/events/caught_error.json} +4 -7
  22. data/serf.gemspec +22 -101
  23. data/spec/serf/builder_spec.rb +44 -0
  24. data/spec/serf/errors/policy_failure_spec.rb +11 -0
  25. data/spec/serf/middleware/error_handler_spec.rb +48 -0
  26. data/spec/serf/middleware/parcel_freezer_spec.rb +20 -0
  27. data/spec/serf/middleware/parcel_masher_spec.rb +30 -0
  28. data/spec/serf/middleware/policy_checker_spec.rb +70 -0
  29. data/spec/serf/middleware/uuid_tagger_spec.rb +32 -0
  30. data/spec/serf/parcel_builder_spec.rb +46 -0
  31. data/spec/serf/serfer_spec.rb +61 -0
  32. data/spec/serf/util/error_handling_spec.rb +35 -0
  33. data/spec/serf/util/null_object_spec.rb +26 -0
  34. data/spec/serf/util/options_extraction_spec.rb +62 -0
  35. data/spec/serf/util/protected_call_spec.rb +33 -0
  36. data/spec/serf/util/uuidable_spec.rb +56 -0
  37. data/spec/serf_spec.rb +1 -4
  38. data/spec/spec_helper.rb +3 -0
  39. data/spec/support/error_handling_wrapper.rb +5 -0
  40. data/spec/support/factories.rb +32 -0
  41. data/spec/support/failing_policy.rb +9 -0
  42. data/spec/support/json_schema_tester.rb +14 -0
  43. data/spec/support/options_extraction_wrapper.rb +10 -0
  44. data/spec/support/passing_policy.rb +7 -0
  45. data/spec/support/protected_call_wrapper.rb +5 -0
  46. metadata +81 -131
  47. data/.document +0 -5
  48. data/.rspec +0 -1
  49. data/Gemfile.lock +0 -58
  50. data/docs/thread_pools.txt +0 -16
  51. data/lib/serf/command.rb +0 -79
  52. data/lib/serf/error.rb +0 -11
  53. data/lib/serf/errors/not_found.rb +0 -8
  54. data/lib/serf/middleware/girl_friday_async.rb +0 -39
  55. data/lib/serf/middleware/masherize.rb +0 -25
  56. data/lib/serf/routing/regexp_matcher.rb +0 -35
  57. data/lib/serf/routing/route.rb +0 -35
  58. data/lib/serf/routing/route_set.rb +0 -64
  59. 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,11 +0,0 @@
1
- module Serf
2
-
3
- ##
4
- # Module used to tag caught exceptions in this library's code to
5
- # let clients (of the library) know that said exceptions came from
6
- # within this code.
7
- #
8
- module Error
9
- end
10
-
11
- end
@@ -1,8 +0,0 @@
1
- module Serf
2
- module Errors
3
-
4
- class NotFound < RuntimeError
5
- end
6
-
7
- end
8
- end
@@ -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
@@ -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
@@ -1,14 +0,0 @@
1
- {
2
- "description": "Message Kind: serf/messages/message_accepted_event",
3
- "type": "object",
4
- "properties": {
5
- "message": {
6
- "type": "object",
7
- "required": true
8
- },
9
- "uuid": {
10
- "type": "string",
11
- "required": true
12
- }
13
- }
14
- }