-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
working towards 1.0 #126
Comments
There is an issue with the current protocol design. It can be impossible to match a specific request with the appropriate response if many requests are made in short order. example There is no way to tell if E_INVALID is for the INDENTIFY or the SUB request. |
@dustismo first, just want to make sure we're on the same page that You point is fair though, and it's something we've debated internally for some time. We've taken the approach that errors are generally fatal. I started going through the process of making changes on the
That would clear up this specific case you're talking about where you'd like to provide useful feedback to your applications about why they couldn't connect, authenticate, or subscribe successfully. For the rest of the cases (after subscribing and messages are flowing) our reader libraries simply log these errors and continue processing... you're really only dealing with 3 commands at that point ( |
Ok, makes sense. I will keep the 'errors are fatal' mentality in mind (though, of course, more context would be good). Though I would still argue for an OK response on the IDENTIFY action. This brings me to another issue (I'm being noisy I know :) ) The client I am writing is more or less completely async, so this pattern isn't so easy:
It works more like:
so matching requests with response can be more difficult. What would make life much cleaner for this would be to have OK responses include the action. something like:
This would be esp helpful for the OK PUB response. I am currently using a semaphore to count OK response wrt to PUB commands to make sure I don't send faster then they are received (yet still maintain high throughput). This feels very brittle considering I don't know with certainty what the OK is for. (It does work, and I don't get any errant OK messages, just feels wrong) |
Let's separate consumers from producers... ConsumersI agree that ProducersRemember, commands on a single
For example, take a look at https://github.com/bitly/nsq/blob/master/examples/bench_writer/bench_writer.go - it can publish 321,000 (200 byte) messages/sec over a single connection using serialized Serializing async IO would look something like (in python, unfortunately, since I dont have experience with netty): all_messages = [...]
def pub_loop(conn):
message = all_messages.pop()
pub(conn, message)
def pub(conn, message)
callback = functools.partial(done_pub, conn=conn)
conn.send("pub", message_data, callback=callback)
def done_pub(frame_type, data, conn):
if frame_type == nsq.FRAME_TYPE_ERROR:
# log, bail, retry
return
callback = functools.partial(pub_loop, conn=conn)
ioloop.add_callback(callback) Essentially just passing around context via callbacks on the io loop. |
NSQ Protocol / Client Library NotesI thought it would be helpful to document some of the philosophy and intentions here and solicit feedback as we move closer to 1.0. Much of this is already in place but there are some subtle changes that will improve the ability to write robust and performant client libraries. This will probably form the basis for some new documentation along side the existing protocol document. The protocol design goals are as follows:
HeartbeatsApplication level heartbeats are useful for detection of slow/unresponsive/disconnected clients when TCP would prefer to continue to retry for considerable amounts of time. Think of the case like pulling a network cable, you want to control and bound these scenarios. Client libraries should be designed in such a way that they account for and respond to heartbeats automatically. Even though data is pushed to clients from The general approach should be to keep a queue of commands (could be a simple linked list), push onto the back when sending a command and pop off the front whenever a Whenever a heartbeat is encountered it should be handled automatically (possibly calling back to the client as a notification). NOTE: Heartbeats will be promoted to their own frame type, to make this easier. ConsumersConsumers can easily determine success/failure of connection, authentication, and subscription phase by:
At runtime it is possible for All other errors are considered fatal and connections are forcibly closed on the All reads should be deadlined to 2x the heartbeat interval. ProducersProducers can follow the same procedures as consumers for robust connection and authentication Producers only have two commands available, Producers should expect to receive heartbeats when those are added in #131. All reads should be deadlined to 2x the heartbeat interval. TODO
|
closing this, I've updated the issues labeled with |
Allow BackoffStrategy to be set via flag, document BackoffStrategy.SetConfig
We're looking to solidify a
1.0
release and I wanted to document some possible changes as early as possible.As mentioned in the README we intend on following the semantic versioning scheme. A
1.0
release would mean, in short:We have a slew of open issues tagged with
1.0
and if other bugs are identified in the interim they will most likely be included as well.Structurally, the biggest change will be the Go library moving into its own repo, most likely
http://github.com/bitly/go-nsq
. It will also be considered1.0
at that point. What this means for applications using this library is that import paths will change fromgithub.com/bitly/nsq/nsq
togithub.com/bitly/go-nsq
. Any other changes will be documented in the respective ChangeLog.If you have any questions/comments/suggestions for things you'd like to see in
1.0
please use this as a forum for that discussion.Thanks!
The text was updated successfully, but these errors were encountered: