{"action":"created","issue":{"url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369","repository_url":"https://api.github.com/repos/Particular/NServiceBus","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":[{"url":"https://api.github.com/repos/Particular/NServiceBus/labels/Tag:%20Core%20v6","name":"Tag: Core v6","color":"ffff00"}],"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":45,"closed_issues":160,"state":"open","created_at":"2014-06-28T13:41:09Z","updated_at":"2016-02-02T13:18:35Z","due_on":null,"closed_at":null},"comments":77,"created_at":"2016-01-28T06:06:09Z","updated_at":"2016-02-03T04:27:14Z","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/178999131","html_url":"https://github.com/Particular/NServiceBus/issues/3369#issuecomment-178999131","issue_url":"https://api.github.com/repos/Particular/NServiceBus/issues/3369","id":178999131,"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},"created_at":"2016-02-03T04:27:14Z","updated_at":"2016-02-03T04:27:14Z","body":"When it comes to V5 -> V6 wire compat I thin it is. \r\n\r\nA V5 endpoint with callbacks enabled (SQL or RabbitMQ) will send a message to the shared queue adding a header like `NServiceBus.RabbitMQ.CallbackQueue`. V6 needs to use it instead of `reply-to` when the message intent is `reply`. That 'hack' can be implemented either on transport level or on core level, not sure which place is better."}}