NSQ automatically removes a message from the queue after sending it to a consumer. And automatically re-queues the message if there is no response from the consumer after a set timeout.
And yes, depending on which programming language client you are using you have to send 'finish'.
Here are the docs for Golang
https://pkg.go.dev/github.com/nsqio/go-nsq#Finish
But because of the way NSQ is designed you have to re-queue a message from your app if the intended action was not successful.
Here is an excerpt from their website
NSQ guarantees that a message will be delivered at least once, though duplicate messages are possible. Consumers should expect this and de-dupe or perform idempotent operations.
This guarantee is enforced as part of the protocol and works as follows (assume the client has successfully connected and subscribed to a topic):
- client indicates they are ready to receive messages
- NSQ sends a message and temporarily stores the data locally (in the event of re-queue or timeout)
- client replies FIN (finish) or REQ (re-queue) indicating success or failure respectively. If client does not reply NSQ will timeout after
a configurable duration and automatically re-queue the message)
You can read more here: https://nsq.io/overview/design.html
Hope my answer helps you.