Skip to content

Commit

Permalink
add event and event serializers logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmad-elassuty committed Aug 13, 2020
1 parent 5c941c5 commit d9f6c53
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@

# rspec failure tracking
.rspec_status

# Debug
.byebug_history
38 changes: 38 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,40 @@ PATH
remote: .
specs:
event_router (0.1.0)
activejob

GEM
remote: https://rubygems.org/
specs:
activejob (6.0.3.2)
activesupport (= 6.0.3.2)
globalid (>= 0.3.6)
activesupport (6.0.3.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
byebug (11.1.3)
coderay (1.1.3)
concurrent-ruby (1.1.7)
connection_pool (2.2.3)
diff-lcs (1.3)
globalid (0.4.2)
activesupport (>= 4.2.0)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
method_source (1.0.0)
minitest (5.14.1)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (~> 0.13.0)
rack (2.2.3)
rake (12.3.3)
redis (4.2.1)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
Expand All @@ -21,14 +49,24 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.1)
sidekiq (6.1.1)
connection_pool (>= 2.2.2)
rack (~> 2.0)
redis (>= 4.2.0)
thread_safe (0.3.6)
tzinfo (1.2.7)
thread_safe (~> 0.1)
zeitwerk (2.4.0)

PLATFORMS
ruby

DEPENDENCIES
event_router!
pry-byebug
rake (~> 12.0)
rspec (~> 3.0)
sidekiq

BUNDLED WITH
2.1.4
7 changes: 7 additions & 0 deletions event_router.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,11 @@ Gem::Specification.new do |spec|
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

# Dependencies
spec.add_dependency "activejob"

# Development dependencies
spec.add_development_dependency "sidekiq"
spec.add_development_dependency "pry-byebug"
end
31 changes: 29 additions & 2 deletions lib/event_router.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
require "event_router/version"
require "event_router/error"
require "active_job"
require "event_router/destination"
require "event_router/event"
require "event_router/event_serializer"
require "event_router/deliver_event_job"

require "examples/order_placed"

require "pry"

module EventRouter
class Error < StandardError; end
# Your code goes here...
module_function

def run_example
ActiveJob::Serializers.add_serializers EventSerializer

Examples::OrderPlaced.publish(order_id: 1)
end

def publish(event)
DeliverEventJob.perform_later(:notifications, event)
end

# def publish(events)
# events = Array(events)
#
# events.map(&:destinations).flatten.each do |destination|
# DeliverEventJob.perform_later(destination, event: event)
# end
# end
end
14 changes: 14 additions & 0 deletions lib/event_router/deliver_event_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require "pry"

module EventRouter
class DeliverEventJob < ActiveJob::Base
self.queue_adapter = :sidekiq

def perform(destination, event)
binding.pry
event.destinations[destination]&.process(event)
end
end
end
19 changes: 19 additions & 0 deletions lib/event_router/destination.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module EventRouter
class Destination
attr_reader :name, :handler, :handler_method

def initialize(name, handler:, method: nil)
@name = name
@handler = handler
@handler_method = method
end

def process(event)
@handler_method ||= event.underscore_name

handler.send(handler_method, event)
end
end
end
6 changes: 6 additions & 0 deletions lib/event_router/error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

module EventRouter
class Error < StandardError; end
end

49 changes: 49 additions & 0 deletions lib/event_router/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

require "securerandom"

module EventRouter
class Event
attr_reader :uid, :correlation_id, :created_at, :payload

class_attribute :destinations, default: {}, instance_writer: false

def initialize(uid: SecureRandom.uuid, correlation_id: SecureRandom.uuid, created_at: Time.current, **payload)
@uid = uid
@correlation_id = correlation_id
@created_at = created_at
@payload = payload
end

def to_hash
{
uid: uid,
correlation_id: correlation_id,
payload: payload,
created_at: created_at,
_er_klass: self.class.name
}
end

def underscore_name
self.class.name.demodulize.underscore
end

class << self
def inherited(base)
base.destinations = destinations.dup
super
end

def deliver_to(name, opts = {})
destinations[name] = EventRouter::Destination.new(name, **opts)
end

def publish(**attrs)
event = new(**attrs)

EventRouter.publish(event)
end
end
end
end
29 changes: 29 additions & 0 deletions lib/event_router/event_serializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module EventRouter
class EventSerializer < ActiveJob::Serializers::ObjectSerializer
def serialize(event)
event_attrs = event.to_hash
payload = event_attrs.delete(:payload)
serialized_payload = ActiveJob::Arguments.serialize(payload)
serialized_event = super(event_attrs)

serialized_event.merge(payload: serialized_payload)
end

def deserialize(hash)
hash["_er_klass"].constantize.new(
uid: hash["uid"],
correlation_id: hash["correlation_id"],
created_at: Time.parse(hash["created_at"]),
**ActiveJob::Arguments.deserialize(hash["payload"]).to_h
)
end

private

def klass
Event
end
end
end
14 changes: 14 additions & 0 deletions lib/examples/event_store/order_placed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module EventRouter
module Examples
module EventStore
class OrderPlaced
def self.handle(event)
binding.pry
true
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/examples/notifications.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module EventRouter
module Examples
module Notifications
module_function

def order_placed(event)
binding.pry
true
end
end
end
end
17 changes: 17 additions & 0 deletions lib/examples/order_placed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require_relative "notifications"
require_relative "event_store/order_placed"

module EventRouter
module Examples
class OrderPlaced < EventRouter::Event
deliver_to :notifications,
handler: EventRouter::Examples::Notifications

deliver_to :event_store,
handler: EventRouter::Examples::EventStore::OrderPlaced,
method: :handle
end
end
end
2 changes: 2 additions & 0 deletions sidekiq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:queues:
- [default, 1]

0 comments on commit d9f6c53

Please sign in to comment.