-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Control PUBACK/PUBREC transmission #53
Comments
Hi @MattBrittan, thanks for the write-up! I put some more thought on this and I realized that there might be another way as well. I'd like to propose it so that we The idea is to buffer the acknowledgments so that order wouldn't matter for the final user (the client would ensure the Here's how I thought it could work:
Optionally the client can automatically acknowledge all packets unless it's configured to expect manual I think this is the approach that I like the most because:
See quick implementation here. This should cover all QoSs:
Concerns:
In regards to sending customised type UserProp struct {
Key string
Value string
}
func (c *Client) Ack(pb *packets.Publish, userProps ...UserProp) error {
// merge userProps with other properties set by the client
...
} Of course it would work if we just want to add user properties. I don't think there is another use case though? 🤔 |
Should this issue be closed since #52 was merged in? Sorry for the basic question. |
I suspect you meant to link PR #57 (Manual acknowledgments) which does appear to provide the functionality I was looking for so I'll close this off. I'm not currently using this library myself (need persistence so use the v3 library) and had not had a chance to look at the solution (this is complicated by the MQTT v5 requirement that ACKS be sent in order which does improve ordering guarantees, in very limited situations, but also limits the usefulness of this kind of technique). |
I would like a way to:
PUBACK
/PUBREC
from being sent if something goes wrong whilst the message is being processed in my code (e.g. a service used to persist the message fails).PUBACK
/PUBREC
so that data can be committed to storage in batches with all relevant messages being acknowledged when the batch has been successfully processed.PUBACK
(adding user properties or similar as discussed in issue How about adding hook for PUBXXX messages #40; this only goes part way towards delivering on that request). This would also enable the use of reason codes such asTopic Name invalid
.This issue comes out of a discussion on PR #52; that PR ensures that the message router is called in message order and that the relevant
PUBACK
/PUBREC
is returned in order and delays the sending of thePUBACK
/PUBREC
until the router returns. The discussion was getting fairly long and is really separate from the PR so I felt it best to open a new issue to allow discussion on this point (it's something others may be interested in).Relevant issues raised in the V3 Client:
The solution I'd like
Add an additional parameter to
Router.Route(*packets.Publish)
;Router.Route(*packets.Publish, func Ack(io.WriterTo) err)
. TheAck
function will send the default acknowledgment (ifWriterTo
is nil) or use the passed in customWriterTo
. If theAck
function is not called then noPUBACK
/PUBREC
will be sent (and the broker would resend the message at some point). Note that at QOS0 theACK
function would not do anything.The benefits of this solution are:
Router
interface so obvious that action is needed (some of the other options could lead to the behaviour being hidden). The default router could be changed to callAck(nil)
which would mean that most users would not notice the change.Publish
packet remains simple and pass by value is not an issue (a mutex may be needed so using a wrapper around the publish packet might create issues for users who copy the struct).Alternatives considered
PUBACK
/PUBREC
sent in order but message handlers called as go routine so order not guaranteed.PUBACK
/PUBREC
sent regardless of any issues encountered whilst handling the message (leading to potential data loss).PUBACK
/PUBREC
sent in order and creates a way to avoid sending them (close the connection before returning from the handler. However:func (c *Client) Ack(pb *packets.Publish) error
that users can call. This could be workable but I'm concerned about what will happen when the client disconnects/reconnects (meaning there is a newClient
); it would be easy for users to introduce bugs into their code. There is also a potential issue if the function is called twice for the samepackets.Publish
(as the MID may have been reallocated to another message).PUBLISH
in aPublishWithAck
which providesfunc (p *PublishWithAck) Ack(io.WriterTo) err
(as per the preferred option above). The downsides of this is that it may be a confusing change for users and complicates the struct passed in (we would probably need a mutex which would prevent pass by value).Additional context
@alsm asked paho-dev@eclipse.org mailing list and @icraggs (Eclipse Paho project lead) responded:
The text was updated successfully, but these errors were encountered: