{"action":"created","issue":{"url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/32","labels_url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/32/labels{/name}","comments_url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/32/comments","events_url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/32/events","html_url":"https://github.com/juju-solutions/charms.reactive/issues/32","id":117610044,"number":32,"title":"No decorator to run handler for every hook","user":{"login":"stub42","id":2928805,"avatar_url":"https://avatars.githubusercontent.com/u/2928805?v=3","gravatar_id":"","url":"https://api.github.com/users/stub42","html_url":"https://github.com/stub42","followers_url":"https://api.github.com/users/stub42/followers","following_url":"https://api.github.com/users/stub42/following{/other_user}","gists_url":"https://api.github.com/users/stub42/gists{/gist_id}","starred_url":"https://api.github.com/users/stub42/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stub42/subscriptions","organizations_url":"https://api.github.com/users/stub42/orgs","repos_url":"https://api.github.com/users/stub42/repos","events_url":"https://api.github.com/users/stub42/events{/privacy}","received_events_url":"https://api.github.com/users/stub42/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-11-18T15:24:22Z","updated_at":"2015-11-19T17:13:09Z","closed_at":null,"body":"There is no mechanism provided to declare that a handler should be run during the hook phase for each and every hook.\r\n\r\nThe most obvious fix would be adjusting the existing `@hook` decorator so that it always runs if no patterns are provided (and an argument never passed to the handler).\r\n\r\nIn my experience, charms should  minimize code that can only run in a specific hook to avoid race conditions. For example, consider a simple service configuration change. This will queue the config-changed hook on each unit, but if there is already a queue of hooks being processed by a unit then these hooks will see the changed configuration in the hook environment before the config-changed hook has had a chance to run. This can be fatal, with hooks crashing attempting to run code paths before the config-changed hook has set things up so they can be run successfully. Similar races can be described for leadership and relations. The simplest way of avoiding this entire class of races is to have a single, general hook instead of several specific ones tied to particular events.\r\n"},"comment":{"url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/comments/158123098","html_url":"https://github.com/juju-solutions/charms.reactive/issues/32#issuecomment-158123098","issue_url":"https://api.github.com/repos/juju-solutions/charms.reactive/issues/32","id":158123098,"user":{"login":"johnsca","id":406082,"avatar_url":"https://avatars.githubusercontent.com/u/406082?v=3","gravatar_id":"","url":"https://api.github.com/users/johnsca","html_url":"https://github.com/johnsca","followers_url":"https://api.github.com/users/johnsca/followers","following_url":"https://api.github.com/users/johnsca/following{/other_user}","gists_url":"https://api.github.com/users/johnsca/gists{/gist_id}","starred_url":"https://api.github.com/users/johnsca/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/johnsca/subscriptions","organizations_url":"https://api.github.com/users/johnsca/orgs","repos_url":"https://api.github.com/users/johnsca/repos","events_url":"https://api.github.com/users/johnsca/events{/privacy}","received_events_url":"https://api.github.com/users/johnsca/received_events","type":"User","site_admin":false},"created_at":"2015-11-19T17:13:09Z","updated_at":"2015-11-19T17:13:09Z","body":"I would argue that if you think you want a `@hook` handler that runs for every hook, you're probably thinking about the problem wrong.  That is to say, I agree with your premise that you shouldn't restrict your logic to specific hooks, but I think you're not taking it quite far enough; I think that charm layers should be avoiding the use of `@hook` as much as possible and instead relying on states to drive behavior, and if you do have a `@hook` handler, the *only* thing it should be doing is setting one or more states (with the possible exception of install, but even that in many charms should be handled by a runtime layer).  In other words, you can think of the reactive dispatch loop as the single general hook that you mentioned.\r\n\r\nFor your example, I would suggest not handling the config-changed hook explicitly at all, and instead having the state handlers do the work and drive their behavior off of the config values, whether they were just changed or not."}}