serf 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,6 +6,7 @@ source 'http://rubygems.org'
6
6
  # Requirements for both clients and servers.
7
7
  gem 'activesupport', '>= 3.2.0'
8
8
  gem 'i18n', '>= 0.6.0' # For ActiveSupport
9
+ gem 'hashie', ">= 1.2.0"
9
10
  # Used by Serf::Messages::*
10
11
  gem 'uuidtools', '>= 2.1.2'
11
12
 
@@ -14,12 +15,12 @@ gem 'uuidtools', '>= 2.1.2'
14
15
  group :development, :test do
15
16
  gem "rspec", "~> 2.8.0"
16
17
  gem "yard", "~> 0.7.5"
17
- gem "bundler", "~> 1.0.22"
18
+ gem "bundler", "~> 1.1.3"
18
19
  gem "jeweler", "~> 1.8.3"
19
20
  gem 'simplecov', '>= 0'
20
21
 
21
22
  # For our testing
22
- gem 'log4r', '~> 1.1.10'
23
+ gem 'log4r', '>= 1.1.10'
23
24
 
24
25
  # Soft Dependencies
25
26
  #gem 'log4r', '~> 1.1.9'
@@ -30,5 +31,5 @@ group :development, :test do
30
31
 
31
32
  # EventMachine is now optional runner
32
33
  gem 'eventmachine', '>= 0.12.10'
33
- gem 'girl_friday', '~> 0.9.7'
34
+ gem 'girl_friday', '>= 0.9.7'
34
35
  end
data/Gemfile.lock CHANGED
@@ -10,6 +10,7 @@ GEM
10
10
  girl_friday (0.9.7)
11
11
  connection_pool (~> 0.1.0)
12
12
  git (1.2.5)
13
+ hashie (1.2.0)
13
14
  i18n (0.6.0)
14
15
  jeweler (1.8.3)
15
16
  bundler (~> 1.0)
@@ -43,12 +44,13 @@ PLATFORMS
43
44
 
44
45
  DEPENDENCIES
45
46
  activesupport (>= 3.2.0)
46
- bundler (~> 1.0.22)
47
+ bundler (~> 1.1.3)
47
48
  eventmachine (>= 0.12.10)
48
- girl_friday (~> 0.9.7)
49
+ girl_friday (>= 0.9.7)
50
+ hashie (>= 1.2.0)
49
51
  i18n (>= 0.6.0)
50
52
  jeweler (~> 1.8.3)
51
- log4r (~> 1.1.10)
53
+ log4r (>= 1.1.10)
52
54
  msgpack (>= 0.4.6)
53
55
  rspec (~> 2.8.0)
54
56
  simplecov
data/README.md CHANGED
@@ -21,7 +21,7 @@ Messages are the representation of data, documents, etc that are
21
21
  marshalled from client to service, which represents the business
22
22
  level interaction of the service.
23
23
 
24
- Messages may be commands that a service must handle.
24
+ Messages may be command requests that a service must handle.
25
25
  Messages may be events that a service emits.
26
26
  Messages may be documents that represent state or business data.
27
27
 
@@ -59,54 +59,23 @@ Not implemented as yet:
59
59
  Service Libraries
60
60
  =================
61
61
 
62
- 1. Service Libraries SHOULD implement message classes that include the
63
- ::Serf::Message helper module.
64
- a. Barring that, they should conform to the idea that messages may be
65
- hashes that define at least one attribute: 'kind'.
62
+ 1. Service Libraries SHOULD implement messages as just hashes with
63
+ defined schemas (JSON Schema).
64
+ a. Required by all messages is the 'kind' field.
65
+ b. By default, Serf Commands will read in hashes and turn them into
66
+ more convenient Hashie::Mash objects.
66
67
  2. Serialization of the messages SHOULD BE Json or MessagePack (I hate XML).
67
- a. `to_hash` is also included.
68
+ a. Serf Builder will create Serf Apps that expect a HASH ENV as input
68
69
  3. Handlers MUST implement the 'build' class method, which
69
70
  MUST receive the ENV Hash as the first parameter, followed by supplemental
70
71
  arguments as declared in the DSL.
71
72
  4. Handler methods SHOULD return zero or more messages.
72
73
  a. Raised errors are caught and pushed to error channels.
74
+ b. Returned messages MUST be Hash based objects for Serialization.
73
75
  5. Handler methods SHOULD handle catch their business logic exceptions and
74
76
  return them as specialized messages that can be forwarded down error channels.
75
77
  Uncaught exceptions that are then caught by Serf are pushed as
76
- generic Serf::CaughtExceptionEvents, and are harder to deal with.
77
-
78
-
79
- Serf::Message
80
- -------------
81
-
82
- Users of the Serf::Message module need to be aware of that:
83
-
84
- 1. Messages MUST implement the `#attributes` method to use the
85
- default implementations of `to_msgpack`, `to_json`, and `to_hash`.
86
- 2. Messages MAY implement validation helpers (e.g. ActiveModel or
87
- Virtus + Aequitas (DataMapper)). This is purely to be helpful for
88
- receivers (Serf::Handlers) to validate the Messages before running
89
- code against its data. The Serf infrastructure code does not
90
- validate the Messages; it is the job of the handler code.
91
- 3. Messages MAY override `Message.parse` class method if they want
92
- different parsing (Message object instantiation) than
93
- `message_class.new *args`. This parse method is called in
94
- Serf::Handler when the handler class has defined a Message class
95
- to be used to deserialize the ENV for a handler action method.
96
- 3. Messages MAY override `Message#kind` instance method or `Message.kind`
97
- class method to specify a message `kind` that is different than
98
- the tableized name of the implementing ruby class.
99
- 4. Messages MAY override `Message#to_msgpack`, `Message#to_json`, or
100
- `Message#to_hash` to get alternate serialization.
101
-
102
- User that opt to roll their own Message class only need to be
103
- aware that:
104
-
105
- 1. Message classes MUST implement `Message.parse(env={})` class method
106
- if said message class is to be used as the target object representation
107
- of a received message (from ENV hash).
108
- a. Serf code makes this assumption when it finds an ENV
109
- hash that is to be parsed into a message object.
78
+ generic CaughtExceptionEvents, and are harder to deal with.
110
79
 
111
80
 
112
81
  Example With GirlFriday
@@ -118,7 +87,6 @@ Example With GirlFriday
118
87
 
119
88
  require 'serf/builder'
120
89
  require 'serf/command'
121
- require 'serf/message'
122
90
  require 'serf/middleware/uuid_tagger'
123
91
  require 'serf/util/options_extraction'
124
92
 
@@ -151,38 +119,20 @@ Example With GirlFriday
151
119
  end
152
120
  end
153
121
 
154
- # my_lib/my_message.rb
155
- # This class is stripped down minimal functionality that
156
- # ActiveModel or Aequitas/Virtus implements.
157
- class MyMessage
158
- include Serf::Util::OptionsExtraction
159
- include Serf::Message
160
-
161
- attr_accessor :data
162
-
163
- def initialize(*args)
164
- extract_options! args
165
- self.data = opts :data
166
- end
122
+ # my_lib/my_validator.rb
123
+ class MyValidator
167
124
 
168
- def attributes
169
- { 'data' => data }
125
+ def self.validate!(data)
126
+ raise 'Data is nil' if data[:data].nil?
170
127
  end
171
128
 
172
- def valid?
173
- !data.nil?
174
- end
175
-
176
- def full_error_messages
177
- 'Data is blank' if data.nil?
178
- end
179
129
  end
180
130
 
181
131
  # my_lib/my_overloaded_command.rb
182
132
  class MyOverloadedCommand
183
133
  include Serf::Command
184
134
 
185
- self.request_factory = MyMessage
135
+ self.request_validator = MyValidator
186
136
 
187
137
  def initialize(*args)
188
138
  super
@@ -304,6 +254,7 @@ Example With GirlFriday
304
254
  end
305
255
  logger.info "End Tick #{Thread.current.object_id}"
306
256
 
257
+
307
258
  Example With EventMachine
308
259
  =========================
309
260
 
@@ -313,7 +264,6 @@ Example With EventMachine
313
264
 
314
265
  require 'serf/builder'
315
266
  require 'serf/command'
316
- require 'serf/message'
317
267
  require 'serf/middleware/uuid_tagger'
318
268
  require 'serf/util/options_extraction'
319
269
 
@@ -347,37 +297,19 @@ Example With EventMachine
347
297
  end
348
298
 
349
299
  # my_lib/my_message.rb
350
- # This class is stripped down minimal functionality that
351
- # ActiveModel or Aequitas/Virtus implements.
352
- class MyMessage
353
- include Serf::Util::OptionsExtraction
354
- include Serf::Message
300
+ class MyValidator
355
301
 
356
- attr_accessor :data
357
-
358
- def initialize(*args)
359
- extract_options! args
360
- self.data = opts :data
361
- end
362
-
363
- def attributes
364
- { 'data' => data }
302
+ def self.validate!(data)
303
+ raise 'Data Missing Error' if data[:data].nil?
365
304
  end
366
305
 
367
- def valid?
368
- !data.nil?
369
- end
370
-
371
- def full_error_messages
372
- 'Data is blank' if data.nil?
373
- end
374
306
  end
375
307
 
376
308
  # my_lib/my_overloaded_command.rb
377
309
  class MyOverloadedCommand
378
310
  include Serf::Command
379
311
 
380
- self.request_factory = MyMessage
312
+ self.request_validator = MyValidator
381
313
 
382
314
  def initialize(*args)
383
315
  super
@@ -506,6 +438,7 @@ Example With EventMachine
506
438
  end
507
439
  end
508
440
 
441
+
509
442
  Contributing to serf
510
443
  ====================
511
444
 
data/lib/serf/command.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'active_support/concern'
2
2
  require 'active_support/core_ext/class/attribute'
3
3
 
4
+ require 'serf/util/mash_factory'
4
5
  require 'serf/util/options_extraction'
5
6
 
6
7
  module Serf
@@ -14,6 +15,10 @@ module Serf
14
15
  # # Set a default Message Parser for the class.
15
16
  # self.request_factory = MySerfRequestMessage
16
17
  #
18
+ # # Validate the request, like using JSON-Schema for hash
19
+ # # (or Hashie's Mash) requests.
20
+ # self.request_validator = MySerfRequestValidator
21
+ #
17
22
  # def initialize(*args, &block)
18
23
  # # Do some validation here, or extra parameter setting with the args
19
24
  # end
@@ -37,6 +42,8 @@ module Serf
37
42
 
38
43
  included do
39
44
  class_attribute :request_factory
45
+ __send__ 'request_factory=', Serf::Util::MashFactory
46
+ class_attribute :request_validator
40
47
  attr_reader :request
41
48
  end
42
49
 
@@ -45,11 +52,7 @@ module Serf
45
52
  end
46
53
 
47
54
  def validate_request!
48
- # We must verify that the request is valid, but only if the
49
- # request object isn't a hash.
50
- unless request.is_a?(Hash) || request.valid?
51
- raise ArgumentError, request.full_error_messages
52
- end
55
+ request_validator.validate! request if request_validator
53
56
  end
54
57
 
55
58
  module ClassMethods
@@ -86,14 +89,14 @@ module Serf
86
89
  # Set the request instance variable to whatever type of request we got.
87
90
  obj.instance_variable_set :@request, request
88
91
 
92
+ # Finalize the object's construction with the rest of the args & block.
93
+ obj.__send__ :initialize, *args, &block
94
+
89
95
  # Now validate that the request is ok.
90
96
  # Implementing classes MAY override this method to do different
91
97
  # kind of request validation.
92
98
  obj.validate_request!
93
99
 
94
- # Finalize the object's construction with the rest of the args & block.
95
- obj.__send__ :initialize, *args, &block
96
-
97
100
  return obj
98
101
  end
99
102
 
@@ -9,7 +9,6 @@ module Middleware
9
9
  # if the incoming request already has it.
10
10
  #
11
11
  class UuidTagger
12
- include Serf::Util::Uuidable
13
12
 
14
13
  ##
15
14
  # @param app the app
@@ -23,7 +22,7 @@ module Middleware
23
22
  def call(env)
24
23
  env = env.dup
25
24
  unless env[@field.to_sym] || env[@field.to_s]
26
- env[@field] = create_coded_uuid
25
+ env[@field] = Serf::Util::Uuidable.create_coded_uuid
27
26
  end
28
27
  @app.call env
29
28
  end
@@ -39,12 +39,6 @@ module More
39
39
  return results
40
40
  end
41
41
 
42
- # Overriding the Serf::Command validate_request! so it doesn't
43
- # call #valid? on the request object. This is because the incoming
44
- # request is another Command object itself.
45
- def validate_request!
46
- end
47
-
48
42
  end
49
43
 
50
44
  end
@@ -1,6 +1,5 @@
1
1
  require 'eventmachine'
2
2
 
3
- require 'serf/messages/message_accepted_event'
4
3
  require 'serf/runners/direct'
5
4
  require 'serf/util/error_handling'
6
5
 
@@ -32,10 +31,6 @@ module Runners
32
31
  # Manditory: Need a runner because this class is just a wrapper.
33
32
  @runner = opts! :runner
34
33
 
35
- @mae_class = opts(
36
- :message_accepted_event_class,
37
- ::Serf::Messages::MessageAcceptedEvent)
38
-
39
34
  @evm = opts :event_machine, ::EventMachine
40
35
  @logger = opts :logger, ::Serf::Util::NullObject.new
41
36
  end
@@ -54,7 +49,10 @@ module Runners
54
49
  end
55
50
  end)
56
51
  end
57
- return @mae_class.new(message: context)
52
+ return {
53
+ kind: 'serf/messages/message_accepted_event',
54
+ message: context
55
+ }
58
56
  end
59
57
 
60
58
  def self.build(options={})
@@ -1,6 +1,5 @@
1
1
  require 'girl_friday'
2
2
 
3
- require 'serf/messages/message_accepted_event'
4
3
  require 'serf/runners/helper'
5
4
  require 'serf/util/error_handling'
6
5
 
@@ -30,12 +29,6 @@ module Runners
30
29
  end
31
30
 
32
31
  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
32
  # Push each handler into the queue along with a copy of the context.
40
33
  handlers.each do |handler|
41
34
  @queue.push(
@@ -45,7 +38,10 @@ module Runners
45
38
 
46
39
  # We got here, we succeeded pushing all the works.
47
40
  # Now we return our accepted event.
48
- return event
41
+ return {
42
+ kind: 'serf/messages/message_accepted_event',
43
+ message: context
44
+ }
49
45
  end
50
46
 
51
47
  ##
@@ -1,6 +1,5 @@
1
1
  require 'active_support/core_ext/string/inflections'
2
2
 
3
- require 'serf/messages/caught_exception_event'
4
3
  require 'serf/util/null_object'
5
4
  require 'serf/util/options_extraction'
6
5
  require 'serf/util/protected_call'
@@ -14,7 +13,6 @@ module Util
14
13
  #
15
14
  # Including classes may have the following instance variables
16
15
  # to override the default values:
17
- # * @error_event_class - ::Serf::Messages::CaughtExceptionEvent
18
16
  # * @logger - ::Serf::Util::NullObject.new
19
17
  # * @error_channel - ::Serf::Util::NullObject.new
20
18
  module ErrorHandling
@@ -40,14 +38,15 @@ module Util
40
38
  # log the exception itself to the logger.
41
39
  #
42
40
  def handle_error(e, context=nil)
43
- eec = opts :error_event_class, ::Serf::Messages::CaughtExceptionEvent
44
41
  logger = opts :logger, ::Serf::Util::NullObject.new
45
42
  error_channel = opts :error_channel, ::Serf::Util::NullObject.new
46
- error_event = eec.new(
43
+ error_event = {
44
+ kind: 'serf/messages/caught_exception_event',
47
45
  context: context,
48
- error: e.class.to_s.tableize,
46
+ error: e.class.to_s.underscore,
49
47
  message: e.message,
50
- backtrace: e.backtrace.join("\n"))
48
+ backtrace: e.backtrace.join("\n")
49
+ }
51
50
 
52
51
  # log the error to our logger
53
52
  logger.error e
@@ -0,0 +1,18 @@
1
+ require 'hashie'
2
+
3
+ module Serf
4
+ module Util
5
+
6
+ ##
7
+ # A Request Factory that just coerces a REQUEST ENV hash message
8
+ # into a Hashie::Mash object for convenience key/value access.
9
+ #
10
+ module MashFactory
11
+
12
+ def self.build(message)
13
+ Hashie::Mash.new message
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -17,7 +17,7 @@ module Util
17
17
  #
18
18
  # NOTE: UUIDTools TimeStamp code creates a UTC based timestamp UUID.
19
19
  #
20
- def create_coded_uuid
20
+ def self.create_coded_uuid
21
21
  # All raw UUIDs are 16 bytes long. Base64 lengthens the string to
22
22
  # 24 bytes long. We chomp off the last two equal signs '==' to
23
23
  # trim the string length to 22 bytes. This gives us an overhead
@@ -30,10 +30,35 @@ module Util
30
30
  ##
31
31
  # @param coded_uuid a coded uuid to parse.
32
32
  #
33
- def parse_coded_uuid(coded_uuid)
33
+ def self.parse_coded_uuid(coded_uuid)
34
34
  UUIDTools::UUID.parse_raw Base64.urlsafe_decode64("#{coded_uuid}==")
35
35
  end
36
36
 
37
+ ##
38
+ # Create a new set of uuids.
39
+ #
40
+ def self.create_uuids(parent={})
41
+ {
42
+ uuid: create_coded_uuid,
43
+ parent_uuid: parent['uuid'],
44
+ origin_uuid: (
45
+ parent[:origin_uuid] ||
46
+ parent[:parent_uuid] ||
47
+ parent[:uuid])
48
+ }
49
+ end
50
+
51
+ ##
52
+ # Set a message's UUIDs with new UUIDs based on the parent's UUIDs.
53
+ #
54
+ def self.annotate_with_uuids!(message, parent={})
55
+ uuids = self.create_uuids parent
56
+ message[:uuid] ||= uuids[:uuid]
57
+ message[:parent_uuid] ||= uuids[:parent_uuid]
58
+ message[:origin_uuid] ||= uuids[:origin_uuid]
59
+ return nil
60
+ end
61
+
37
62
  end
38
63
 
39
64
  end
data/lib/serf/version.rb CHANGED
@@ -2,7 +2,7 @@ module Serf
2
2
 
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 8
5
+ MINOR = 9
6
6
  PATCH = 0
7
7
  BUILD = nil
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join '.'
@@ -0,0 +1,21 @@
1
+ {
2
+ "description": "Message Kind: serf/messages/caught_exception_event",
3
+ "type": "object",
4
+ "properties": {
5
+ "context": {
6
+ "type": "object"
7
+ },
8
+ "error": {
9
+ "type": "string"
10
+ },
11
+ "message": {
12
+ "type": "string"
13
+ },
14
+ "backtrace": {
15
+ "type": "string"
16
+ },
17
+ "uuid": {
18
+ "type": "string"
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,14 @@
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
+ }
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.0"
8
+ s.version = "0.9.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-04-19"
12
+ s.date = "2012-05-06"
13
13
  s.description = "Event-Driven SOA with CQRS"
14
14
  s.email = "benjaminlyu@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -30,12 +30,8 @@ Gem::Specification.new do |s|
30
30
  "lib/serf/builder.rb",
31
31
  "lib/serf/command.rb",
32
32
  "lib/serf/error.rb",
33
- "lib/serf/message.rb",
34
- "lib/serf/messages/caught_exception_event.rb",
35
- "lib/serf/messages/message_accepted_event.rb",
36
33
  "lib/serf/middleware/uuid_tagger.rb",
37
34
  "lib/serf/more/command_worker.rb",
38
- "lib/serf/more/uuid_fields.rb",
39
35
  "lib/serf/routing/endpoint.rb",
40
36
  "lib/serf/routing/registry.rb",
41
37
  "lib/serf/runners/direct.rb",
@@ -44,12 +40,15 @@ Gem::Specification.new do |s|
44
40
  "lib/serf/runners/helper.rb",
45
41
  "lib/serf/serfer.rb",
46
42
  "lib/serf/util/error_handling.rb",
43
+ "lib/serf/util/mash_factory.rb",
47
44
  "lib/serf/util/null_object.rb",
48
45
  "lib/serf/util/options_extraction.rb",
49
46
  "lib/serf/util/protected_call.rb",
50
47
  "lib/serf/util/regexp_matcher.rb",
51
48
  "lib/serf/util/uuidable.rb",
52
49
  "lib/serf/version.rb",
50
+ "schemas/caught_exception_event.json",
51
+ "schemas/message_accepted_event.json",
53
52
  "serf.gemspec",
54
53
  "spec/serf_spec.rb",
55
54
  "spec/spec_helper.rb"
@@ -66,43 +65,46 @@ Gem::Specification.new do |s|
66
65
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
67
66
  s.add_runtime_dependency(%q<activesupport>, [">= 3.2.0"])
68
67
  s.add_runtime_dependency(%q<i18n>, [">= 0.6.0"])
68
+ s.add_runtime_dependency(%q<hashie>, [">= 1.2.0"])
69
69
  s.add_runtime_dependency(%q<uuidtools>, [">= 2.1.2"])
70
70
  s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
71
71
  s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
72
- s.add_development_dependency(%q<bundler>, ["~> 1.0.22"])
72
+ s.add_development_dependency(%q<bundler>, ["~> 1.1.3"])
73
73
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
74
74
  s.add_development_dependency(%q<simplecov>, [">= 0"])
75
- s.add_development_dependency(%q<log4r>, ["~> 1.1.10"])
75
+ s.add_development_dependency(%q<log4r>, [">= 1.1.10"])
76
76
  s.add_development_dependency(%q<msgpack>, [">= 0.4.6"])
77
77
  s.add_development_dependency(%q<eventmachine>, [">= 0.12.10"])
78
- s.add_development_dependency(%q<girl_friday>, ["~> 0.9.7"])
78
+ s.add_development_dependency(%q<girl_friday>, [">= 0.9.7"])
79
79
  else
80
80
  s.add_dependency(%q<activesupport>, [">= 3.2.0"])
81
81
  s.add_dependency(%q<i18n>, [">= 0.6.0"])
82
+ s.add_dependency(%q<hashie>, [">= 1.2.0"])
82
83
  s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
83
84
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
84
85
  s.add_dependency(%q<yard>, ["~> 0.7.5"])
85
- s.add_dependency(%q<bundler>, ["~> 1.0.22"])
86
+ s.add_dependency(%q<bundler>, ["~> 1.1.3"])
86
87
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
87
88
  s.add_dependency(%q<simplecov>, [">= 0"])
88
- s.add_dependency(%q<log4r>, ["~> 1.1.10"])
89
+ s.add_dependency(%q<log4r>, [">= 1.1.10"])
89
90
  s.add_dependency(%q<msgpack>, [">= 0.4.6"])
90
91
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
91
- s.add_dependency(%q<girl_friday>, ["~> 0.9.7"])
92
+ s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
92
93
  end
93
94
  else
94
95
  s.add_dependency(%q<activesupport>, [">= 3.2.0"])
95
96
  s.add_dependency(%q<i18n>, [">= 0.6.0"])
97
+ s.add_dependency(%q<hashie>, [">= 1.2.0"])
96
98
  s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
97
99
  s.add_dependency(%q<rspec>, ["~> 2.8.0"])
98
100
  s.add_dependency(%q<yard>, ["~> 0.7.5"])
99
- s.add_dependency(%q<bundler>, ["~> 1.0.22"])
101
+ s.add_dependency(%q<bundler>, ["~> 1.1.3"])
100
102
  s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
101
103
  s.add_dependency(%q<simplecov>, [">= 0"])
102
- s.add_dependency(%q<log4r>, ["~> 1.1.10"])
104
+ s.add_dependency(%q<log4r>, [">= 1.1.10"])
103
105
  s.add_dependency(%q<msgpack>, [">= 0.4.6"])
104
106
  s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
105
- s.add_dependency(%q<girl_friday>, ["~> 0.9.7"])
107
+ s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
106
108
  end
107
109
  end
108
110
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-19 00:00:00.000000000 Z
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70198112141080 !ruby/object:Gem::Requirement
16
+ requirement: &70100670653360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70198112141080
24
+ version_requirements: *70100670653360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: i18n
27
- requirement: &70198112140280 !ruby/object:Gem::Requirement
27
+ requirement: &70100670652560 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,21 @@ dependencies:
32
32
  version: 0.6.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70198112140280
35
+ version_requirements: *70100670652560
36
+ - !ruby/object:Gem::Dependency
37
+ name: hashie
38
+ requirement: &70100670651180 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70100670651180
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: uuidtools
38
- requirement: &70198112138420 !ruby/object:Gem::Requirement
49
+ requirement: &70100670649260 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: 2.1.2
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *70198112138420
57
+ version_requirements: *70100670649260
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: rspec
49
- requirement: &70198112136940 !ruby/object:Gem::Requirement
60
+ requirement: &70100670647520 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ~>
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: 2.8.0
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70198112136940
68
+ version_requirements: *70100670647520
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: yard
60
- requirement: &70198112135260 !ruby/object:Gem::Requirement
71
+ requirement: &70100670646500 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ~>
@@ -65,21 +76,21 @@ dependencies:
65
76
  version: 0.7.5
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *70198112135260
79
+ version_requirements: *70100670646500
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: bundler
71
- requirement: &70198112134580 !ruby/object:Gem::Requirement
82
+ requirement: &70100670814180 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ~>
75
86
  - !ruby/object:Gem::Version
76
- version: 1.0.22
87
+ version: 1.1.3
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *70198112134580
90
+ version_requirements: *70100670814180
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: jeweler
82
- requirement: &70198112148060 !ruby/object:Gem::Requirement
93
+ requirement: &70100670813540 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ~>
@@ -87,10 +98,10 @@ dependencies:
87
98
  version: 1.8.3
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *70198112148060
101
+ version_requirements: *70100670813540
91
102
  - !ruby/object:Gem::Dependency
92
103
  name: simplecov
93
- requirement: &70198112146140 !ruby/object:Gem::Requirement
104
+ requirement: &70100670812840 !ruby/object:Gem::Requirement
94
105
  none: false
95
106
  requirements:
96
107
  - - ! '>='
@@ -98,21 +109,21 @@ dependencies:
98
109
  version: '0'
99
110
  type: :development
100
111
  prerelease: false
101
- version_requirements: *70198112146140
112
+ version_requirements: *70100670812840
102
113
  - !ruby/object:Gem::Dependency
103
114
  name: log4r
104
- requirement: &70198112145040 !ruby/object:Gem::Requirement
115
+ requirement: &70100670812100 !ruby/object:Gem::Requirement
105
116
  none: false
106
117
  requirements:
107
- - - ~>
118
+ - - ! '>='
108
119
  - !ruby/object:Gem::Version
109
120
  version: 1.1.10
110
121
  type: :development
111
122
  prerelease: false
112
- version_requirements: *70198112145040
123
+ version_requirements: *70100670812100
113
124
  - !ruby/object:Gem::Dependency
114
125
  name: msgpack
115
- requirement: &70198112144400 !ruby/object:Gem::Requirement
126
+ requirement: &70100670811380 !ruby/object:Gem::Requirement
116
127
  none: false
117
128
  requirements:
118
129
  - - ! '>='
@@ -120,10 +131,10 @@ dependencies:
120
131
  version: 0.4.6
121
132
  type: :development
122
133
  prerelease: false
123
- version_requirements: *70198112144400
134
+ version_requirements: *70100670811380
124
135
  - !ruby/object:Gem::Dependency
125
136
  name: eventmachine
126
- requirement: &70198112143700 !ruby/object:Gem::Requirement
137
+ requirement: &70100670810700 !ruby/object:Gem::Requirement
127
138
  none: false
128
139
  requirements:
129
140
  - - ! '>='
@@ -131,18 +142,18 @@ dependencies:
131
142
  version: 0.12.10
132
143
  type: :development
133
144
  prerelease: false
134
- version_requirements: *70198112143700
145
+ version_requirements: *70100670810700
135
146
  - !ruby/object:Gem::Dependency
136
147
  name: girl_friday
137
- requirement: &70198112142640 !ruby/object:Gem::Requirement
148
+ requirement: &70100670809960 !ruby/object:Gem::Requirement
138
149
  none: false
139
150
  requirements:
140
- - - ~>
151
+ - - ! '>='
141
152
  - !ruby/object:Gem::Version
142
153
  version: 0.9.7
143
154
  type: :development
144
155
  prerelease: false
145
- version_requirements: *70198112142640
156
+ version_requirements: *70100670809960
146
157
  description: Event-Driven SOA with CQRS
147
158
  email: benjaminlyu@gmail.com
148
159
  executables: []
@@ -164,12 +175,8 @@ files:
164
175
  - lib/serf/builder.rb
165
176
  - lib/serf/command.rb
166
177
  - lib/serf/error.rb
167
- - lib/serf/message.rb
168
- - lib/serf/messages/caught_exception_event.rb
169
- - lib/serf/messages/message_accepted_event.rb
170
178
  - lib/serf/middleware/uuid_tagger.rb
171
179
  - lib/serf/more/command_worker.rb
172
- - lib/serf/more/uuid_fields.rb
173
180
  - lib/serf/routing/endpoint.rb
174
181
  - lib/serf/routing/registry.rb
175
182
  - lib/serf/runners/direct.rb
@@ -178,12 +185,15 @@ files:
178
185
  - lib/serf/runners/helper.rb
179
186
  - lib/serf/serfer.rb
180
187
  - lib/serf/util/error_handling.rb
188
+ - lib/serf/util/mash_factory.rb
181
189
  - lib/serf/util/null_object.rb
182
190
  - lib/serf/util/options_extraction.rb
183
191
  - lib/serf/util/protected_call.rb
184
192
  - lib/serf/util/regexp_matcher.rb
185
193
  - lib/serf/util/uuidable.rb
186
194
  - lib/serf/version.rb
195
+ - schemas/caught_exception_event.json
196
+ - schemas/message_accepted_event.json
187
197
  - serf.gemspec
188
198
  - spec/serf_spec.rb
189
199
  - spec/spec_helper.rb
@@ -202,7 +212,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
212
  version: '0'
203
213
  segments:
204
214
  - 0
205
- hash: 3739935025256924512
215
+ hash: 2754574147578555547
206
216
  required_rubygems_version: !ruby/object:Gem::Requirement
207
217
  none: false
208
218
  requirements:
data/lib/serf/message.rb DELETED
@@ -1,56 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/class/attribute'
3
- require 'active_support/core_ext/string/inflections'
4
-
5
- module Serf
6
-
7
- ##
8
- # A module to represent a message that we're transporting over
9
- # the wire. This is mainly for commands and events in ED-SOA.
10
- # Optional, but useful for validations, etc.
11
- #
12
- module Message
13
- extend ActiveSupport::Concern
14
-
15
- included do
16
- class_attribute :kind
17
- send 'kind=', self.to_s.tableize.singularize
18
- class_attribute :model_name
19
- send 'model_name=', self.to_s
20
- end
21
-
22
- def to_hash
23
- attributes.merge kind: kind
24
- end
25
-
26
- def to_msgpack
27
- to_hash.to_msgpack
28
- end
29
-
30
- def to_json(*args)
31
- to_hash.to_json *args
32
- end
33
-
34
- def model
35
- self.class
36
- end
37
-
38
- def full_error_messages
39
- errors.full_messages.join '. '
40
- end
41
-
42
- module ClassMethods
43
-
44
- def parse(*args, &block)
45
- self.new *args, &block
46
- end
47
-
48
- def build(*args, &block)
49
- self.new *args, &block
50
- end
51
-
52
- end
53
-
54
- end
55
-
56
- end
@@ -1,49 +0,0 @@
1
- require 'serf/message'
2
- require 'serf/util/uuidable'
3
-
4
- module Serf
5
- module Messages
6
-
7
- ##
8
- # An event message to signal that the serf code caught an
9
- # exception during the processing of some message, which is
10
- # represented by the context field.
11
- #
12
- # Instances of this class are norminally pushed to an
13
- # error channel for out of band processing/notification.
14
- #
15
- class CaughtExceptionEvent
16
- include Serf::Message
17
- include Serf::Util::Uuidable
18
-
19
- attr_accessor :context
20
- attr_accessor :error
21
- attr_accessor :message
22
- attr_accessor :backtrace
23
-
24
- def initialize(options={})
25
- @context = options[:context]
26
- @error = options[:error]
27
- @message = options[:message]
28
- @backtrace = options[:backtrace]
29
- @uuid = options[:uuid]
30
- end
31
-
32
- def attributes
33
- {
34
- 'context' => @context,
35
- 'error' => @error,
36
- 'message' => @message,
37
- 'backtrace' => @backtrace,
38
- 'uuid' => (@uuid || create_coded_uuid)
39
- }
40
- end
41
-
42
- def to_s
43
- to_hash.to_s
44
- end
45
-
46
- end
47
-
48
- end
49
- end
@@ -1,38 +0,0 @@
1
- require 'serf/message'
2
- require 'serf/util/uuidable'
3
-
4
- module Serf
5
- module Messages
6
-
7
- ##
8
- # This event signals that the serf process has accepted a message
9
- # for processing at a later time. These events are normally sent
10
- # in response to calling clients, which is a separate signal
11
- # than any errors given.
12
- #
13
- class MessageAcceptedEvent
14
- include Serf::Message
15
- include Serf::Util::Uuidable
16
-
17
- attr_accessor :message
18
-
19
- def initialize(options={})
20
- @message = options[:message]
21
- @uuid = options[:uuid]
22
- end
23
-
24
- def attributes
25
- {
26
- 'message' => @message,
27
- 'uuid' => (@uuid || create_coded_uuid)
28
- }
29
- end
30
-
31
- def to_s
32
- to_hash.to_s
33
- end
34
-
35
- end
36
-
37
- end
38
- end
@@ -1,29 +0,0 @@
1
- require 'serf/util/uuidable'
2
-
3
- module Serf
4
- module More
5
-
6
- ##
7
- # Assumes that Virtus has already been included in the class that
8
- # also includes UuidFields.
9
- #
10
- module UuidFields
11
- extend Serf::Util::Uuidable
12
-
13
- def self.included(base)
14
- base.attribute :uuid, String, default: lambda { |o,a| create_coded_uuid }
15
- base.attribute :parent_uuid, String
16
- base.attribute :origin_uuid, String
17
- end
18
-
19
- def create_child_uuids
20
- {
21
- uuid: UuidFields.create_coded_uuid,
22
- parent_uuid: uuid,
23
- origin_uuid: (origin_uuid || parent_uuid || uuid)
24
- }
25
- end
26
- end
27
-
28
- end
29
- end