Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to dynamically enrich events metadata by using with_metadata #327

Merged
merged 16 commits into from
May 3, 2018

Conversation

jakubkosinski
Copy link
Contributor

@jakubkosinski jakubkosinski commented Apr 30, 2018

#325

Instead of using metadata_proc when initializing RubyEventStore::Client one can now
use with_metadata instance method to dynamically set the event metadata for all events
published inside a block, e.g.

event_store.with_metadata(request_ip: '127.0.0.1', correlation_id: '1234567890') do
event_store.publish(event)
end

with_metadata calls can be nested but the passed metadata will not be merged with one from
the upper level. This allows to clear the metadata set in the upper level by calling with_metadata(nil)

  • in this case only default timestamp will be added to published events metadata

@@ -1,5 +1,10 @@
Further changes can be tracked at [releases page](https://github.com/RailsEventStore/rails_event_store/releases).

### 0.15.0 (not released yet)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've moved changelog to https://github.com/RailsEventStore/rails_event_store/releases as the 1st line says :)

if metadata_proc
warn "`RubyEventStore::Client#metadata_proc` has been deprecated. Use `RubyEventStore::Client#with_metadata` instead."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure we want to deprecate it... Let me think/check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm too compilicated for quick review:

@@ -171,6 +171,16 @@ def within(&block)
Within.new(block, event_broker)
end

def with_metadata(metadata, &block)
previous_metadata = self.metadata
begin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we could use just ensure without begin

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you're right

Instead of using metadata_proc when initializing RubyEventStore::Client one can now
use with_context instance method to dynamically set the event metadata for all events
published inside a block, e.g.

```
event_store.with_metadata(request_ip: '127.0.0.1', correlation_id: '1234567890') do
   event_store.publish(event)
end
```

`with_metadata` calls can be nested but the passed metadata will not be merged with one from
the upper level. This allows to clear the metadata set in the upper level by calling `with_metadata(nil)`
- in this case only default timestamp will be added to published events metadata
Instead of setting thread local variable, use with_metadata method from
the event_store instance taken from the app configuration.
If `config.event_store` is not set, no action is performed.

Custom request metadata proc is still taken from `config.x.rails_event_store.request_metadata`
If that is not present, the default proc is called
[ci skip]
It looks like the @app in the middleware is not an instance of `Rails::Application`
so we cannot just read config from there. But we can use the Rails global
and read configuration from there
Store metadata in thread local variable that has unique name for each instance
so that you can nest `RubyEventStore::Client#with_metadata` calls of different
client instances without overwriting the metadata
Simplify middleware so that it only calls the app in Client#with_request_metadata block
if config.event_store is set

You can now set the custom request_metadata proc in `RailsEventStore::Client`, the default
proc returns the remote IP & request ID from ActionDispatch::Request created from the env
[ci skip]
When with_metadata calls are nested, merge the metadata instead of overwriting it
request = ::Rack::MockRequest.new(::Rack::Lint.new(Middleware.new(
->(env) { [200, {}, ['Hello World']] },
->(env) { { kaka: 'dudu' } } )))
specify 'calls app within with_metadata block when app has configured the event store instance' do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that a bit too much of testing implementation details, something which one would call klasotesty?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvmd, changed later

require 'rails_event_store/middleware'
require 'rack/lint'

module RailsEventStore
RSpec.describe Middleware do
specify 'lint' do
request = ::Rack::MockRequest.new(::Rack::Lint.new(Middleware.new(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have you decided to removeRack::Lint that verifies Middleware in accordance to Rack specification?

@@ -126,17 +133,142 @@ module RubyEventStore
end

specify 'published event metadata will be enriched by proc execution' do
client = RubyEventStore::Client.new(repository: InMemoryRepository.new, metadata_proc: ->{ {request_id: '127.0.0.1'} })
client = silence_warnings { RubyEventStore::Client.new(repository: InMemoryRepository.new, metadata_proc: ->{ {request_id: '127.0.0.1'} }) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this silence_warnings necessary here with output(deprecation_warning).to_stderr above?

@mostlyobvious
Copy link
Member

Looks good, the questions remain open and can be addressed async -- as usual.

@mostlyobvious mostlyobvious merged commit 06f6f34 into master May 3, 2018
@mostlyobvious mostlyobvious deleted the with-metadata branch May 3, 2018 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants