nats.py
nats.py copied to clipboard
Reconnection logic should not apply for the first connection attempt
Consider the following code:
import asyncio
import nats
async def run():
async def error_cb(e):
print(f'There was an error: {e}')
try:
nc = await nats.connect(servers='nats://localhost:4222',
error_cb=error_cb,
max_reconnect_attempts=2)
await nc.publish(subject='foo', payload='data'.encode())
await nc.flush()
await nc.drain()
except Exception as err:
print(f"{type(err)} : {err}")
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(run())
finally:
loop.close()
Having started nats-server
that requires authentication, e.g. with user/password, I get the following output:
There was an error: nats: 'Authorization Violation'
There was an error: nats: 'Authorization Violation'
There was an error: nats: 'Authorization Violation'
<class 'nats.errors.NoServersError'> : nats: no servers available for connection
that clearly shows that the client tries to connect 3 times before giving up, which is not in line with other clients. As far as I understand, the RetryOnFailedConnect
option in nats.go is false by default. So, nats.py should give up right after the first failure.
The same would happen in the Go client, there are a couple of attempts to connect to the same server and the it would return a no servers available error.
well, this is my first attempt with Go (I specialize in C++ and Python), so please let me know if I missed anything:
opts := nats.GetDefaultOptions()
opts.MaxReconnect = 3
opts.Servers = []string{"nats://localhost:4222"}
nc, err := opts.Connect()
if err != nil {
fmt.Println("ERROR: ", err)
os.Exit(1)
}
nc.Publish("foo", []byte("Hello World"))
nc.Close()
result:
ERROR: nats: Authorization Violation
Looking at the server log ( -DV
), there was only one attempt to connect.
This is not a real problem for me, because in my (restricted) environment I can always assume that a NATS server is running, and my credentials are correct, but more of a philosophical question, because I'm writing my own NATS client, and wanted to make it as consistent with other clients as possible 🙂 feel free to close this, if you have more important things on your plate.
P.S. To be honest, I'm not super happy with the golang client behaviour either 🙄 when given a pool of servers, and connecting to all of them fails, I get back an error only from the last server in the list. And seems like no callbacks are invoked in the process, so I can't know why connecting to other servers failed.