…flexibility when acknowledging messages
…tion() method. Instead, it's retrieved via the default_consumer() method.
It was possible to cancel a subscription via timeout or cancellator while in the process of receiving a message. This would cause the unsubscribe to fail, and would leave unparsed junk in the buffer. This could also cause the message to be dropped, which is bad. The solution is to detect when the unsubscribe fails and parse the new-found message like nothing happened. Unfortuntely, the CancelOk response from the unsubscribe is still somewhere in our buffer and needs to be processed or else it will break things. The logic is more complicated as a result, but should be able to handle all possible states of the buffer.
It was possible for the timeout to be hit while in the middle of parsing, causing the buffer to be in a degraded state. This is also the case when using cancellator, although in practice this is much harder to do. This change makes it so that the timeout or cancellator object only cancels a subscription if it is in the waiting state, not when parsing. This also has the added benefit of making the cancellator logic much simplier, and both checks are done with a single method call. Note that this implementation currently throws an exception if the unsubscribe was unsucessful, which can happen if the timeout was hit while the message was being delivered (network latency). This is far better than indefinitely hanging however...