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

Consumers #3

Closed
vladfaust opened this issue Mar 14, 2019 · 2 comments
Closed

Consumers #3

vladfaust opened this issue Mar 14, 2019 · 2 comments
Labels
enhancement New feature or request rfc Request For Comments
Projects
Milestone

Comments

@vladfaust
Copy link
Member

vladfaust commented Mar 14, 2019

Introduce consumers which are guaranteed to handle an event exactly one time, based on their name (or class name if it is a class):

struct UserCreated
  include Onyx::EDA::Event

  def initialize(@user_id : Int32, @registration_request_id : String)
  end
end

struct RegistrationRequest
  include Onyx::EDA::Event

  def initialize(@name : String)
  end
end

# ---

class Registrar
  include Onyx::EDA::Consumer(RegistrationRequest)

  def consume(event)
    user = Onyx.query(User.new(name: event.name).insert.returning(:id))
    Onyx.emit(UserCreated.new(user.id, event._event_id))
  end
end

spawn Registrar.new.listen # RFC on better name

# Or

Onyx.consume(RegistrationRequest, name: "registrar") do |event|
  user = Onyx.query(User.new(name: event.name).insert.returning(:id))
  Onyx.emit(UserCreated.new(user.id, registration_request_id: event._event_id))
end

# ---

event_id = Onyx.emit(RegistrationRequest.new("John"))

Onyx.subscribe(self, UserCreated, event_id) do |event|
  pp event.user_id
end

An event can be broadcast to an arbitrary amount subscribers, but only to one consumer of this name. However, there can be an arbitrary amount of consumers with different names, for example in addition to the example above:

class AdminNotifier
  include Onyx::EDA::Consumer(RegistrationRequest)

  def consume(event)
    send_admin_email("New registration request")
  end
end
@vladfaust vladfaust added enhancement New feature or request rfc Request For Comments labels Mar 14, 2019
@aemadrid
Copy link

that interface looks great. I'm guessing you will use redis streams and consumer groups?

@vladfaust
Copy link
Member Author

@aemadrid for Redis, yes. BTW, I'm also planning on adding different MQs.

@vladfaust vladfaust added this to the next patch milestone Mar 14, 2019
@vladfaust vladfaust added this to To do in Kanban via automation Mar 14, 2019
@vladfaust vladfaust moved this from To do to In progress in Kanban Mar 26, 2019
vladfaust added a commit that referenced this issue Mar 29, 2019
BREAKING CHANGE: `Channel` is an abstract class now, use `Channel::Memory` and `Channel::Redis`.

BREAKING CHANGE: No need to pass a subscribing object to `Channel#subscribe` anymore. It returns `Channel::Subscription` instance which has `#unsubscribe` method.

BREAKING CHANGE: `Channel#subscribe` accepts `filter` or `consumer_id` arguments. The former enables event filtering and the latter enables consuming instead of subscribing. Closes #3 and also closes #4.

BREAKING CHANGE: `Channel#emit` returns the events themselves.

Added `Channel#await` method, which closes #5.

Events have an `#event_id` getter with random UUID by default, which closes #6.

Added `Subscriber` and `Consumer` modules.

Fixed requiring logic of events when using `Channel::Redis`, the requiring order should not matter anymore.

Also added triggering dependant Travis CI builds.
@vladfaust vladfaust modified the milestones: next patch, next minor Apr 2, 2019
Kanban automation moved this from In progress to Done Apr 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request rfc Request For Comments
Projects
Kanban
  
Done
Development

No branches or pull requests

2 participants