{"action":"created","issue":{"url":"https://api.github.com/repos/hanami/utils/issues/160","repository_url":"https://api.github.com/repos/hanami/utils","labels_url":"https://api.github.com/repos/hanami/utils/issues/160/labels{/name}","comments_url":"https://api.github.com/repos/hanami/utils/issues/160/comments","events_url":"https://api.github.com/repos/hanami/utils/issues/160/events","html_url":"https://github.com/hanami/utils/pull/160","id":183097867,"number":160,"title":"Introducing Hanami::Events","user":{"login":"jodosha","id":5089,"avatar_url":"https://avatars.githubusercontent.com/u/5089?v=3","gravatar_id":"","url":"https://api.github.com/users/jodosha","html_url":"https://github.com/jodosha","followers_url":"https://api.github.com/users/jodosha/followers","following_url":"https://api.github.com/users/jodosha/following{/other_user}","gists_url":"https://api.github.com/users/jodosha/gists{/gist_id}","starred_url":"https://api.github.com/users/jodosha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jodosha/subscriptions","organizations_url":"https://api.github.com/users/jodosha/orgs","repos_url":"https://api.github.com/users/jodosha/repos","events_url":"https://api.github.com/users/jodosha/events{/privacy}","received_events_url":"https://api.github.com/users/jodosha/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/hanami/utils/labels/feature","name":"feature","color":"bfe5bf"}],"state":"open","locked":false,"assignee":{"login":"jodosha","id":5089,"avatar_url":"https://avatars.githubusercontent.com/u/5089?v=3","gravatar_id":"","url":"https://api.github.com/users/jodosha","html_url":"https://github.com/jodosha","followers_url":"https://api.github.com/users/jodosha/followers","following_url":"https://api.github.com/users/jodosha/following{/other_user}","gists_url":"https://api.github.com/users/jodosha/gists{/gist_id}","starred_url":"https://api.github.com/users/jodosha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jodosha/subscriptions","organizations_url":"https://api.github.com/users/jodosha/orgs","repos_url":"https://api.github.com/users/jodosha/repos","events_url":"https://api.github.com/users/jodosha/events{/privacy}","received_events_url":"https://api.github.com/users/jodosha/received_events","type":"User","site_admin":false},"assignees":[{"login":"jodosha","id":5089,"avatar_url":"https://avatars.githubusercontent.com/u/5089?v=3","gravatar_id":"","url":"https://api.github.com/users/jodosha","html_url":"https://github.com/jodosha","followers_url":"https://api.github.com/users/jodosha/followers","following_url":"https://api.github.com/users/jodosha/following{/other_user}","gists_url":"https://api.github.com/users/jodosha/gists{/gist_id}","starred_url":"https://api.github.com/users/jodosha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jodosha/subscriptions","organizations_url":"https://api.github.com/users/jodosha/orgs","repos_url":"https://api.github.com/users/jodosha/repos","events_url":"https://api.github.com/users/jodosha/events{/privacy}","received_events_url":"https://api.github.com/users/jodosha/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/hanami/utils/milestones/16","html_url":"https://github.com/hanami/utils/milestones/next","labels_url":"https://api.github.com/repos/hanami/utils/milestones/16/labels","id":1931583,"number":16,"title":"next","description":"","creator":{"login":"jodosha","id":5089,"avatar_url":"https://avatars.githubusercontent.com/u/5089?v=3","gravatar_id":"","url":"https://api.github.com/users/jodosha","html_url":"https://github.com/jodosha","followers_url":"https://api.github.com/users/jodosha/followers","following_url":"https://api.github.com/users/jodosha/following{/other_user}","gists_url":"https://api.github.com/users/jodosha/gists{/gist_id}","starred_url":"https://api.github.com/users/jodosha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jodosha/subscriptions","organizations_url":"https://api.github.com/users/jodosha/orgs","repos_url":"https://api.github.com/users/jodosha/repos","events_url":"https://api.github.com/users/jodosha/events{/privacy}","received_events_url":"https://api.github.com/users/jodosha/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":6,"state":"open","created_at":"2016-08-09T07:51:12Z","updated_at":"2016-10-14T16:47:42Z","due_on":null,"closed_at":null},"comments":12,"created_at":"2016-10-14T16:47:41Z","updated_at":"2016-10-15T13:36:34Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/hanami/utils/pulls/160","html_url":"https://github.com/hanami/utils/pull/160","diff_url":"https://github.com/hanami/utils/pull/160.diff","patch_url":"https://github.com/hanami/utils/pull/160.patch"},"body":"## Basic events framework for Hanami\r\n\r\n### Usage\r\n\r\n#### Subscribe With A Proc\r\n\r\n```ruby\r\nrequire 'concurrent'\r\nrequire 'hanami/events'\r\nrequire 'ostruct'\r\n\r\nHanami::Events.subscribe('signup') do |event|\r\n  puts \"New signup: #{event[:user].email}\"\r\nend\r\n\r\nuser = OpenStruct.new(id: 1, email: \"user@hanamirb.org\")\r\nHanami::Events.broadcast('signup', user: user)\r\n\r\n  # => \"New signup: user@hanamirb.org\r\n```\r\n\r\n#### Subscribe With An object\r\n\r\n```ruby\r\nrequire 'concurrent'\r\nrequire 'hanami/events'\r\nrequire 'ostruct'\r\n\r\nclass WelcomeMailer\r\n  def call(event)\r\n    puts \"New welcome message for: #{event[:user].email}\"\r\n  end\r\nend\r\n\r\nHanami::Events.subscribe('signup', WelcomeMailer.new)\r\n\r\nuser = OpenStruct.new(id: 1, email: \"user@hanamirb.org\")\r\nHanami::Events.broadcast('signup', user: user)\r\n\r\n  # => \"New welcome message for: user@hanamirb.org\r\n```\r\n\r\n#### Include Mixin\r\n\r\n```ruby\r\nrequire 'concurrent'\r\nrequire 'hanami/events'\r\nrequire 'ostruct'\r\n\r\nclass Signup\r\n  include Hanami::Events\r\n\r\n  def call(params)\r\n    user = OpenStruct.new(params)\r\n    broadcast('signup', user: user)\r\n  end\r\nend\r\n\r\nHanami::Events.subscribe('signup') do |event|\r\n  puts \"New signup: #{event[:user].email}\"\r\nend\r\n\r\nSignup.new.call(email: \"user@hanamirb.org\")\r\n  # => \"New signup: user@hanamirb.org\r\n```\r\n\r\n---\r\n\r\n### Useful for\r\n\r\nThis can be useful for:\r\n\r\n  * Automatic logging https://github.com/hanami/hanami/issues/484\r\n  * Move mailers to apps https://github.com/hanami/hanami/issues/648\r\n  * Async/distributed jobs\r\n\r\n#### Automatic Logging\r\n\r\nAll the Hanami frameworks can broadcast events for operations that we want to automatically log. Things like action response, rendered templates/layouts, database queries/commands. The logger can subscribe to these events and emit a new entry.\r\n\r\n#### Move mailers to apps\r\n\r\nSee https://github.com/hanami/hanami/issues/648#issuecomment-253855250\r\n\r\n#### Async/Distributed Jobs\r\n\r\nThe proposed implementation ships with a memory backend as dispatcher for the events. Which is fine for basic setups, but it has the downside of being volatile.\r\n\r\nIn the future, third-party devs can implement a backend for async/distributed mechanisms like Sidekiq or Apache Kafka.\r\n\r\n---\r\n\r\n@hanami/core-team @hanami/contributors Please review. 💚 "},"comment":{"url":"https://api.github.com/repos/hanami/utils/issues/comments/253984705","html_url":"https://github.com/hanami/utils/pull/160#issuecomment-253984705","issue_url":"https://api.github.com/repos/hanami/utils/issues/160","id":253984705,"user":{"login":"TiteiKo","id":248372,"avatar_url":"https://avatars.githubusercontent.com/u/248372?v=3","gravatar_id":"","url":"https://api.github.com/users/TiteiKo","html_url":"https://github.com/TiteiKo","followers_url":"https://api.github.com/users/TiteiKo/followers","following_url":"https://api.github.com/users/TiteiKo/following{/other_user}","gists_url":"https://api.github.com/users/TiteiKo/gists{/gist_id}","starred_url":"https://api.github.com/users/TiteiKo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/TiteiKo/subscriptions","organizations_url":"https://api.github.com/users/TiteiKo/orgs","repos_url":"https://api.github.com/users/TiteiKo/repos","events_url":"https://api.github.com/users/TiteiKo/events{/privacy}","received_events_url":"https://api.github.com/users/TiteiKo/received_events","type":"User","site_admin":false},"created_at":"2016-10-15T13:36:34Z","updated_at":"2016-10-15T13:36:34Z","body":"Just a thought here... I don't think I'm mistaken in saying that the memory backend will be process (not thread, but process) specific, and so server specific. It should be mentioned somewhere in the docs/comments, as to not take by surprise someone who would not have dig in on how it works.\r\n"}}
{"actor":{"display_login":"TiteiKo"}}