Per our discussion in stompngo_examples issue #2, I'm opening an issue in the main project. The concern is on what to do with in-flight messages received after or during an unsubscribe. The current use case I've been working with involves ActiveMQ with prefetch set, but could apply to any similar interaction with a STOMP server that sends more than one MESSAGE without requiring an ACK using either ackmode client or client-individual
- connect
- sub to queue q.1 with ackmode
client and prefetch X where X is how many messages I need
- process X messages
ACK the last message (which should be cumulative with ackmode client)
- unsubscribe
- repeat 2-5 with queues q.2, q.3, etc.
The problem I'm running into is that the UNSUBSCRIBE right after the ACK seems to be causing messages to not get ACKed sometimes, and some of the later subscriptions are getting nothing at all. In examining this problem (which may or may not be related to the issue I'm submitting), I ran across the following scenario which I think needs to be at least mentioned in the documentation, if not fixed in the code somehow:
- Client subscribes to a destination, which creates a
chan MessageData with a buffer size of c.scc (default: 1)
//subscription.go
if hid { // Client specified id
c.subs[id] = make(chan MessageData, c.scc) // Assign subscription
}
- Message(s) arrive with that destination specified in the
subscription header and are picked up in the read loop here
//reader.go
if sid, ok := f.Headers.Contains("subscription"); ok {
c.subsLock.Lock()
c.subs[sid] <- d
c.subsLock.Unlock()
} else {
c.input <- d
}
- Client processes some messages or not, but there is still a message in the channel for this subscription.
- client unsubscribes, which causes the following
//unsubscribe.go
c.subsLock.Lock() defer c.subsLock.Unlock()
// ...
close(c.subs[sid])
delete(c.subs, sid)
- Before
c.subsLock.Lock() is called in the unsubscribe, another message arrives and is picked up by the reader goroutine.
It seems that this would block. The unsubscribe wouldn't be able to get the subsLock, and the reader goroutine would be blocked trying to send to the subscription channel.
Per our discussion in stompngo_examples issue #2, I'm opening an issue in the main project. The concern is on what to do with in-flight messages received after or during an unsubscribe. The current use case I've been working with involves ActiveMQ with prefetch set, but could apply to any similar interaction with a STOMP server that sends more than one
MESSAGEwithout requiring anACKusing either ackmodeclientorclient-individualclientand prefetch X where X is how many messages I needACKthe last message (which should be cumulative with ackmodeclient)The problem I'm running into is that the
UNSUBSCRIBEright after theACKseems to be causing messages to not getACKed sometimes, and some of the later subscriptions are getting nothing at all. In examining this problem (which may or may not be related to the issue I'm submitting), I ran across the following scenario which I think needs to be at least mentioned in the documentation, if not fixed in the code somehow:chan MessageDatawith a buffer size ofc.scc(default: 1)subscriptionheader and are picked up in the read loop herec.subsLock.Lock()is called in the unsubscribe, another message arrives and is picked up by the reader goroutine.It seems that this would block. The unsubscribe wouldn't be able to get the subsLock, and the reader goroutine would be blocked trying to send to the subscription channel.