{"action":"created","issue":{"url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369","labels_url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369/labels{/name}","comments_url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369/comments","events_url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369/events","html_url":"https://github.com/Particular/NServiceBus/issues/3369","id":129349282,"number":3369,"title":"Callbacks - how?","user":{"login":"SzymonPobiega","id":163318,"avatar_url":"https://avatars.githubusercontent.com/u/163318?v=3","gravatar_id":"","url":"https://api.github.com/users/SzymonPobiega","html_url":"https://github.com/SzymonPobiega","followers_url":"https://api.github.com/users/SzymonPobiega/followers","following_url":"https://api.github.com/users/SzymonPobiega/following{/other_user}","gists_url":"https://api.github.com/users/SzymonPobiega/gists{/gist_id}","starred_url":"https://api.github.com/users/SzymonPobiega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SzymonPobiega/subscriptions","organizations_url":"https://api.github.com/users/SzymonPobiega/orgs","repos_url":"https://api.github.com/users/SzymonPobiega/repos","events_url":"https://api.github.com/users/SzymonPobiega/events{/privacy}","received_events_url":"https://api.github.com/users/SzymonPobiega/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"SzymonPobiega","id":163318,"avatar_url":"https://avatars.githubusercontent.com/u/163318?v=3","gravatar_id":"","url":"https://api.github.com/users/SzymonPobiega","html_url":"https://github.com/SzymonPobiega","followers_url":"https://api.github.com/users/SzymonPobiega/followers","following_url":"https://api.github.com/users/SzymonPobiega/following{/other_user}","gists_url":"https://api.github.com/users/SzymonPobiega/gists{/gist_id}","starred_url":"https://api.github.com/users/SzymonPobiega/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SzymonPobiega/subscriptions","organizations_url":"https://api.github.com/users/SzymonPobiega/orgs","repos_url":"https://api.github.com/users/SzymonPobiega/repos","events_url":"https://api.github.com/users/SzymonPobiega/events{/privacy}","received_events_url":"https://api.github.com/users/SzymonPobiega/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/Particular/NServiceBus/milestones/62","html_url":"https://github.com/Particular/NServiceBus/milestones/6.0.0","labels_url":"https://api.github.com/repos/Particular/NServiceBus/milestones/62/labels","id":704266,"number":62,"title":"6.0.0","description":"Setting up deployment process","creator":{"login":"SimonCropp","id":122666,"avatar_url":"https://avatars.githubusercontent.com/u/122666?v=3","gravatar_id":"","url":"https://api.github.com/users/SimonCropp","html_url":"https://github.com/SimonCropp","followers_url":"https://api.github.com/users/SimonCropp/followers","following_url":"https://api.github.com/users/SimonCropp/following{/other_user}","gists_url":"https://api.github.com/users/SimonCropp/gists{/gist_id}","starred_url":"https://api.github.com/users/SimonCropp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SimonCropp/subscriptions","organizations_url":"https://api.github.com/users/SimonCropp/orgs","repos_url":"https://api.github.com/users/SimonCropp/repos","events_url":"https://api.github.com/users/SimonCropp/events{/privacy}","received_events_url":"https://api.github.com/users/SimonCropp/received_events","type":"User","site_admin":false},"open_issues":46,"closed_issues":159,"state":"open","created_at":"2014-06-28T13:41:09Z","updated_at":"2016-01-28T10:04:17Z","due_on":null,"closed_at":null},"comments":27,"created_at":"2016-01-28T06:06:09Z","updated_at":"2016-01-28T10:29:00Z","closed_at":null,"body":"This issue is meant to discuss possible approaches to callbacks. For now I can see two alternatives but feel free to add more.\r\n\r\n## Callbacks in the transport\r\n\r\nIn this approach we implement callbacks on the transport level:\r\n * RabbitMQ uses [direct reply-to](https://www.rabbitmq.com/direct-reply-to.html)\r\n * SQL Server uses a single queue but has additional column for *callback id*. The receiver uses `WHERE CallbackID = <my_id> OR CallbackID IS NULL` when receiving. There is additional process that removes outdated callback messages if their destination endpoint instance has been decommissioned\r\n * ASB uses a spacial (possibly shared between endpoints) session queue for messages that require callbacks. Unfortunately this requires the receiving side to know about that queue (not backwards-compatible by default) -- @SeanFeldman please correct my if my thinking is wrong here\r\n * ASQ - ?\r\n * MSMQ - Works out of the box by means or `reply-to` header containing the sender's queue\r\n\r\n### Pros\r\n\r\n * We can use native transport features\r\n * Does not affect the routing in any way\r\n\r\n### Cons\r\n\r\n * Requires additional code to be written in all the transports\r\n * Requires merging back in the callbacks package because in order for transport to implement callbacks, the notion of a callback has to be part of the transport seam\r\n\r\n## Callbacks based on routing\r\n\r\nIn this approach we use following definitions:\r\n * Endpoint refers to all the deployments of the same binary package (e.g. `sales`)\r\n * Logical instance refers to all deployments that share same *instance ID* (e.g. `sales-1`)\r\n * Physical instance refers to a single deployment\r\n * *Instance ID* is provides by the host\r\n\r\nCallbacks just use the `reply-to` header. In RabbitMQ we would have to have some logical that would start two receivers if *instance ID* is not empty. The main receiver would not use the ID (taking advantage of competing consumers) and the other would be ID-specific (allowing callbacks)\r\n\r\n### Pros\r\n\r\n * Allows to send commands to specific instances. Useful if there are multiple instances (same binaries) but are not part of the cluster (they are logically distinct) e.g. physical device controllers.\r\n * No additional code in transports\r\n * `NServiceBus.Callbacks` can probably remain a separate package as there is no additional information passed in the transport seam\r\n\r\n### Cons\r\n\r\n * Requires more complex mental model of routing: even when users use broker transports, they might need to know what *instance ID* it. The assumption that it is, by default, provided by the host, makes this point slightly less important.\r\n * Generally requires more queues to be present in the underlying infrastructure (in ASP, SQL and RabbitMQ transports) - more stuff to care about."},"comment":{"url":"https://api.github.com/repos/Particular/NServiceBus/issues/comments/176112429","html_url":"https://github.com/Particular/NServiceBus/issues/3369#issuecomment-176112429","issue_url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369","id":176112429,"user":{"login":"mauroservienti","id":1325611,"avatar_url":"https://avatars.githubusercontent.com/u/1325611?v=3","gravatar_id":"","url":"https://api.github.com/users/mauroservienti","html_url":"https://github.com/mauroservienti","followers_url":"https://api.github.com/users/mauroservienti/followers","following_url":"https://api.github.com/users/mauroservienti/following{/other_user}","gists_url":"https://api.github.com/users/mauroservienti/gists{/gist_id}","starred_url":"https://api.github.com/users/mauroservienti/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mauroservienti/subscriptions","organizations_url":"https://api.github.com/users/mauroservienti/orgs","repos_url":"https://api.github.com/users/mauroservienti/repos","events_url":"https://api.github.com/users/mauroservienti/events{/privacy}","received_events_url":"https://api.github.com/users/mauroservienti/received_events","type":"User","site_admin":false},"created_at":"2016-01-28T10:29:00Z","updated_at":"2016-01-28T10:29:00Z","body":"If I recall correctly another requirement we discussed yesterday is that\nthe main queue and the callback one need to share a single pipeline for\nincoming messages. If, again I understood correctly, this should be OK out\nof the box because a receiver is the thing at he transport level that pull\nmessages from the input queue and delivers them to the pipeline.\n\nCorrect?\n\nOn Thu, 28 Jan 2016 at 10:28, Szymon Pobiega <notifications@github.com>\nwrote:\n\n> Here's a brain dump from my conversation with @johnsimons\n> <https://github.com/johnsimons>:\n> Stuff we agree on\n>\n>    - RabbitMQ (and probably SQL Server) should implement callbacks by\n>    using two queues/receivers.\n>    - One receiver would be the main queue (taking advantage of competing\n>    consumers)\n>    - The other receiver would have a random name. That random name would\n>    be generated on install time by the installer in NServiceBus.Callbacks\n>    package.\n>    - If you don't reference NServiceBus.Callbacks, there would be no\n>    additional queue/receiver\n>\n> Stuff we not yet agree on\n>\n>    - How that random name is communicated to the transport:\n>       - @johnsimons <https://github.com/johnsimons> (correct me please if\n>       I messed up): the transport should get that ID from the callbacks package,\n>       not involving the core and that random name should not be used for scale\n>       out/round-robin distribution\n>       - @szymonpobiega <https://github.com/szymonpobiega>: we should use\n>       the *instance ID* concept we have in core (under the name\n>       *discriminator*) and NServiceBus.Callbacks should hook up to the\n>       core and provide its stable-random way of generating these IDs. The same\n>       API would be used by the Azure host to provide *role id* as *instance\n>       ID*.\n>\n> Outcomes\n>\n>    - RabbitMQ is not blocked. The only thing that can change is the way\n>    the random thing is provided\n>    - SQL Server transport should be tested with the callbacks package to\n>    validate our assumptions\n>    - @szymonpobiega <https://github.com/szymonpobiega> will spike the\n>    alternative *instance ID* API\n>\n> —\n> Reply to this email directly or view it on GitHub\n> <https://github.com/Particular/NServiceBus/issues/3369#issuecomment-176081063>\n> .\n>\n-- \nMauro Servienti | Solution Architect | Particular Software\n"}}