Rework writer deadline handling.
[stompngo.git] / disconnect.go
blob875eab56d6c35e9e388964757a951d993f39d64c
1 //
2 // Copyright © 2011-2017 Guy M. Allard
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
17 package stompngo
20 Disconnect from a STOMP broker.
22 Shut down heart beats if necessary.
23 Set connection status to false to disable further actions with this
24 connection.
27 Obtain a receipt unless the client specifically indicates a receipt request
28 should be excluded. If the client actually asks for a receipt, use the
29 supplied receipt id. Otherwise generate a unique receipt id and add that
30 to the DISCONNECT headers.
32 Example:
33 h := stompngo.Headers{HK_RECEIPT, "receipt-id1"} // Ask for a receipt
34 e := c.Disconnect(h)
35 if e != nil {
36 // Do something sane ...
38 fmt.Printf("%q\n", c.DisconnectReceipt)
39 // Or:
40 h := stompngo.Headers{"noreceipt", "true"} // Ask for a receipt
41 e := c.Disconnect(h)
42 if e != nil {
43 // Do something sane ...
45 fmt.Printf("%q\n", c.DisconnectReceipt)
48 func (c *Connection) Disconnect(h Headers) error {
49 c.discLock.Lock()
50 defer c.discLock.Unlock()
52 if !c.connected {
53 return ECONBAD
55 c.log(DISCONNECT, "start", h)
56 e := checkHeaders(h, c.Protocol())
57 if e != nil {
58 return e
60 ch := h.Clone()
61 // If the caller does not want a receipt do not ask for one. Otherwise,
62 // add a receipt request if caller did not specifically ask for one. This is
63 // in the spirit of the specification, and allows reasonable resource cleanup
64 // in both the client and the message broker.
65 _, cwr := ch.Contains("noreceipt")
66 if !cwr {
67 if _, ok := ch.Contains(HK_RECEIPT); !ok {
68 ch = append(ch, HK_RECEIPT, Uuid())
72 f := Frame{DISCONNECT, ch, NULLBUFF}
74 r := make(chan error)
75 c.output <- wiredata{f, r}
76 e = <-r
77 // Drive shutdown logic
78 c.shutdown()
79 // Only set DisconnectReceipt if we sucessfully received one.
80 if !cwr && e == nil {
81 // Receipt
82 c.DisconnectReceipt = <-c.input
83 c.log(DISCONNECT, "dr", ch, c.DisconnectReceipt)
85 c.log(DISCONNECT, "ends", ch)
86 close(c.ssdc)
87 c.log(DISCONNECT, "system shutdown cannel closed")
88 return e