1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["19851"],{42958(e,n,c){c.r(n),c.d(n,{metadata:()=>i,default:()=>d,frontMatter:()=>o,contentTitle:()=>a,toc:()=>l,assets:()=>r});var i=JSON.parse('{"id":"consumer-cancel","title":"Consumer Cancel Notification","description":"\x3c!--","source":"@site/versioned_docs/version-4.1/consumer-cancel.md","sourceDirName":".","slug":"/consumer-cancel","permalink":"/docs/4.1/consumer-cancel","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.1/consumer-cancel.md","tags":[],"version":"4.1","frontMatter":{"title":"Consumer Cancel Notification"},"sidebar":"docsSidebar","previous":{"title":"Consumers","permalink":"/docs/4.1/consumers"},"next":{"title":"Consumer Prefetch","permalink":"/docs/4.1/consumer-prefetch"}}'),t=c(74848),s=c(28453);let o={title:"Consumer Cancel Notification"},a="Consumer Cancel Notification",r={},l=[{value:"Overview",id:"overview",level:2},{value:"Consumer Cancellation and Replicated Queues",id:"replication",level:3}];function h(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"consumer-cancel-notification",children:"Consumer Cancel Notification"})}),"\n",(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsxs)(n.p,{children:["When a channel is consuming from a queue, there are various\nreasons which could cause the consumption to stop. One of\nthese is obviously if the client issues a\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," on the same channel, which will\ncause the consumer to be cancelled and the server replies\nwith a ",(0,t.jsx)(n.code,{children:"basic.cancel-ok"}),". Other events, such as\nthe queue being deleted, or in a clustered scenario, the\nnode on which the queue is located failing, will cause the\nconsumption to be cancelled, but the client channel will not\nbe informed, which is frequently unhelpful."]}),"\n",(0,t.jsxs)(n.p,{children:["To solve this, we have introduced an extension in which the\nbroker will send to the client a ",(0,t.jsx)(n.code,{children:"basic.cancel"}),"\nin the case of such unexpected consumer cancellations. This\nis not sent in the case of the broker receiving a\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," from the client. AMQP 0-9-1\nclients don't by default expect to receive\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," methods from the broker\nasynchronously, and so in order to enable this behaviour,\nthe client must present a ",(0,t.jsx)(n.code,{children:"capabilities"})," table in\nits ",(0,t.jsx)(n.code,{children:"client-properties"})," in which there is a key\n",(0,t.jsx)(n.code,{children:"consumer_cancel_notify"})," and a boolean value\n",(0,t.jsx)(n.code,{children:"true"}),". See the ",(0,t.jsx)(n.a,{href:"./connections#capabilities",children:"section on capabilities"})," for details."]}),"\n",(0,t.jsxs)(n.p,{children:["Our supported clients present this capability by default to\nthe broker and thus will be sent the asynchronous\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," method by the broker, which they\npresent to the consumer callback. For example, in our Java\nclient, the ",(0,t.jsx)(n.code,{children:"Consumer"})," interface has a\n",(0,t.jsx)(n.code,{children:"handleCancel"})," callback, which can be overridden\nby sub-classing the ",(0,t.jsx)(n.code,{children:"DefaultConsumer"})," class:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"channel.queueDeclare(queue, false, true, false, null);\nConsumer consumer = new DefaultConsumer(channel) {\n @Override\n public void handleCancel(String consumerTag) throws IOException {\n // consumer has been cancelled unexpectedly\n }\n};\nchannel.basicConsume(queue, consumer);\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It is not an error for the client to issue a\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," for a consumer which has been\nunexpectedly cancelled (e.g. due to queue deleti
1on). By\ndefinition, there is a race possible between a client\nissuing a ",(0,t.jsx)(n.code,{children:"basic.cancel"}),", and the broker sending\nout the asynchronous notification. In such cases, the broker\ndoes not error when it receives the\n",(0,t.jsx)(n.code,{children:"basic.cancel"})," and replies with a\n",(0,t.jsx)(n.code,{children:"basic.cancel-ok"})," as normal."]}),"\n",(0,t.jsx)(n.h3,{id:"replication",children:"Consumer Cancellation and Replicated Queues"}),"\n",(0,t.jsx)(n.p,{children:"Clients supporting consumer cancel notification will always be\ninformed when a queue is deleted or becomes\nunavailable. Consumers may request that they should be cancelled\nwhen the leader of a replicated queue changes."})]})}function d(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453(e,n,c){c.d(n,{R:()=>o,x:()=>a});var i=c(96540);let t={},s=i.createContext(t);function o(e){let n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.