Skip to content

[ZMQ] append a message sequence number to every ZMQ notification - #7762

Merged
laanwj merged 2 commits into
bitcoin:masterfrom
jonasschnelli:2016/03/zmq_seq
Apr 19, 2016
Merged

[ZMQ] append a message sequence number to every ZMQ notification#7762
laanwj merged 2 commits into
bitcoin:masterfrom
jonasschnelli:2016/03/zmq_seq

Conversation

@jonasschnelli

@jonasschnelli jonasschnelli commented Mar 29, 2016

Copy link
Copy Markdown
Contributor

Currently, ZMQ listeners cannot detect if they have missed a message.
This PR adds a sequence number to each message (each message type has its own counter).

The sequence number is the last part of the multipart zmq message to not break the API, though, we could consider breaking the API in favor of moving the sequence number to the very beginning.

Todo:

  • update release notes

@jonasschnelli
jonasschnelli force-pushed the 2016/03/zmq_seq branch 2 times, most recently from 59c4c09 to 4120ceb Compare March 29, 2016 12:50
@laanwj

laanwj commented Mar 29, 2016

Copy link
Copy Markdown
Member

Concept ACK, I like adding the sequence nr as an extra part. Also ok with using 32 bit sequence numbers.

@promag

promag commented Mar 30, 2016

Copy link
Copy Markdown
Contributor

I thought a subscriber can't miss a message.

Edit:

But it can: http://stackoverflow.com/a/15821036. So what can a subscriber do if it detects a missing message?

@jonasschnelli

Copy link
Copy Markdown
Contributor Author

@promag:
I'm not sure if I would design an listening application that fully rely on getting all notifications. With this PR, you could at least detect if you got all (also check if you got the first) notifications and if not, you could poll/sync your data over RPC.

@laanwj

laanwj commented Mar 30, 2016

Copy link
Copy Markdown
Member

I thought a subscriber can't miss a message.

The way we are using ZMQ, the sender will never block. This is sensible as we don't want to hang the application due to a slow client. But this means at some point one of the send queues will fill up and new messages will be discarded.

But it can: http://stackoverflow.com/a/15821036. So what can a subscriber do if it detects a missing message?

That's up to the application. Either stop with a fatal error, or re-start/re-sync. An event application usually does some synchronization at start-up, then starts processing incremental changes. After getting out of sync it can repeat the process. The important thing is being able to detect it and thus act on it.

@laanwj

laanwj commented Apr 14, 2016

Copy link
Copy Markdown
Member

This needs mention in doc/release-notes.md as well as doc/zmq.md (there, don't forget to specify the size and endianness of the sequence number), I think it is ready for merge otherwise.

Comment thread qa/rpc-tests/zmq_test.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for using str() here?

@jonasschnelli
jonasschnelli force-pushed the 2016/03/zmq_seq branch 2 times, most recently from c0cdcce to fefecf8 Compare April 15, 2016 13:07
@jonasschnelli

Copy link
Copy Markdown
Contributor Author

Fixed @MarcoFalke nit.
Mentioned the change in doc/release-notes.md as well as in doc/zmq.md

Comment thread qa/rpc-tests/zmq_test.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Add the b prefix, which is a noop in py2?

b"hashtx"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing!

@jonasschnelli

Copy link
Copy Markdown
Contributor Author

@MarcoFalke: fixed nits.

Comment thread src/zmq/zmqpublishnotifier.cpp Outdated

// Internal function to send multipart message
static int zmq_send_multipart(void *sock, const void* data, size_t size, ...)
static int zmq_send_multipart_keepalive(void *sock, const void* data, size_t size, ...)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the rename to _keepalive?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed it to _keepalive because it does not "close" the multipart message. All messaged are sent with ZMQ_SNDMORE and I wanted to increase the awareness of that by renaming the function.

@laanwj

laanwj commented Apr 19, 2016

Copy link
Copy Markdown
Member

Here's a slight simplification of the code - gets rid of some duplication, as well as the _keepalive change:
laanwj@fb843df

@jonasschnelli

Copy link
Copy Markdown
Contributor Author

@laanwj: Thanks. Much better. Stolen fb843df, squashed and force pushed.

@laanwj
laanwj merged commit 0b25a9f into bitcoin:master Apr 19, 2016
laanwj added a commit that referenced this pull request Apr 19, 2016
…fication

0b25a9f [ZMQ] append a message sequence number to every ZMQ notification (Jonas Schnelli)
de821d5 [ZMQ] refactor message string (Jonas Schnelli)
@dcousens

dcousens commented Apr 21, 2016

Copy link
Copy Markdown
Contributor

The way we are using ZMQ, the sender will never block. This is sensible as we don't want to hang the application due to a slow client.

Could we make that parameterizable?
In certain cases I'd rather have message reliability than having the node to be guaranteed to be running in real time.

@sipa

sipa commented Apr 21, 2016 via email

Copy link
Copy Markdown
Member

@laanwj

laanwj commented Apr 21, 2016

Copy link
Copy Markdown
Member

In certain cases I'd rather have message reliability than having the node to be guaranteed to be running in real time.

Well notifications can be lost, through zmq or otherwise, for example if bitcoind needs to be restarted, or a myriad of other circumstances not under your control. At least you can detect it now:

  • sequence number goes to 0 (and wasn't at 0xffffffff) -> bitcoind restarted
  • sequence number skips a beat -> send buffer was full

Your application needs an (application dependent) way to resync anyhow. This is better than pretending to guarantee something.

zkbot added a commit to zcash/zcash that referenced this pull request Feb 9, 2017
zkbot added a commit to zcash/zcash that referenced this pull request Feb 9, 2017
codablock added a commit to codablock/dash that referenced this pull request Dec 20, 2017
CryptoCentric added a commit to absolute-community/absolute that referenced this pull request Feb 15, 2019
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants