Skip to content

Commit

Permalink
Fork the context + h_factory when factoring an event.
Browse files Browse the repository at this point in the history
  • Loading branch information
blambeau committed May 20, 2022
1 parent 83bc2c5 commit a8a375b
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 31 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ Unfortunately it comes with a couple of BREAKING changes:
contract expects the event type to be a fully classified
class name (subclass of Event) and will attempt to factor
one. The second argument is no longer a world (Hash) but
a context instance to attach to the event (a dup is made).
a context instance to attach to the event. A context fork
is made, using the event context data passed through the
Context h_factory (if event contains context info).

* `Startback::Engine` constructor takes ServerEngine options
under a `:server_engine` key (was the options themselves).
Expand Down
7 changes: 7 additions & 0 deletions lib/startback/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def to_json(*args, &bl)
to_h.to_json(*args, &bl)
end

def fork(h = nil)
dup.tap{|duped|
self.class.h_factor!(duped, h) if h
yield(duped) if block_given?
}
end

def dup
super.tap{|c|
c.send(:clean_factored!)
Expand Down
1 change: 1 addition & 0 deletions lib/startback/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def initialize(type, data, context = nil)
def self.json(src, context)
parsed = JSON.parse(src)
klass = Kernel.const_get(parsed['type'])
context = context.fork(parsed['context']) if context
klass.new(parsed['type'], parsed['data'], context)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/startback/event/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def create_agents
end

def factor_event(event_data)
Event.json(event_data, context.dup)
Event.json(event_data, context)
end

class Runner
Expand Down
20 changes: 20 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ module SpecHelpers
c.include SpecHelpers
end

class SubContext < Startback::Context
attr_accessor :foo
h_factory do |c,h|
c.foo = h["foo"]
end
h_dump do |h|
h.merge!("foo" => foo)
end
end

class SubContext
attr_accessor :bar
h_factory do |c,h|
c.bar = h["bar"]
end
h_dump do |h|
h.merge!("bar" => bar)
end
end

class User
class Changed < Startback::Event
end
Expand Down
10 changes: 3 additions & 7 deletions spec/unit/context/test_dup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
module Startback
describe Context, "dup" do

class Subcontext < Context
attr_accessor :foo
end

let(:context) {
Subcontext.new.tap{|s| s.foo = "bar" }
SubContext.new.tap{|s| s.foo = "bar" }
}

class ContextRelatedAbstraction
Expand All @@ -27,7 +23,7 @@ def initialize(context)
expect(x).not_to be(context)
}
expect(seen).to be(got)
expect(got).to be_a(Subcontext)
expect(got).to be_a(SubContext)
expect(got).not_to be(context)
expect(got.foo).to eql("bar")
end
Expand All @@ -43,4 +39,4 @@ def initialize(context)
end

end
end
end
38 changes: 38 additions & 0 deletions spec/unit/context/test_fork.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'spec_helper'

module Startback
describe Context, "fork" do

it 'is a simple dup without args' do
context = SubContext.new
context.foo = ['hello']

forked = context.fork
puts "Forked: #{forked.inspect}"
expect(fork).not_to be(context)
expect(forked.foo).to eql(['hello'])
expect(forked.foo).to be(context.foo)
end

it 'yields the context if a block is provided' do
context = SubContext.new

seen = false
context.fork({ 'foo' => 'hello' }) do |forked|
expect(fork).not_to be(context)
expect(forked.foo).to eql('hello')
seen = true
end
expect(seen).to eql(true)
end

it 'uses the factory on the hash provided' do
context = SubContext.new

forked = context.fork({ 'foo' => 'hello' })
expect(fork).not_to be(context)
expect(forked.foo).to eql('hello')
end

end
end
20 changes: 0 additions & 20 deletions spec/unit/context/test_h_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,6 @@ module Startback
expect(Context.new.to_json).to eql("{}")
end

class SubContext < Context
attr_accessor :foo
h_factory do |c,h|
c.foo = h["foo"]
end
h_dump do |h|
h.merge!("foo" => foo)
end
end

class SubContext
attr_accessor :bar
h_factory do |c,h|
c.bar = h["bar"]
end
h_dump do |h|
h.merge!("bar" => bar)
end
end

it 'allows installing factories' do
expect(Context.h_factories).to be_empty
expect(SubContext.h_factories.size).to eql(2)
Expand Down
7 changes: 5 additions & 2 deletions spec/unit/test_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ module Startback
end

it 'accepts an explicit context as second argument' do
evt = Event.json(JSON_SRC, 12)
expect(evt.context).to eql(12)
c = SubContext.new.tap{|x| x.foo = 'hello' }
evt = Event.json(JSON_SRC, c)
expect(evt.context).not_to be(c)
expect(evt.context).to be_a(SubContext)
expect(evt.context.foo).to eql('hello')
end
end

Expand Down

0 comments on commit a8a375b

Please sign in to comment.