question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NATS#connect - specify socket timeout options [Feature Request]

See original GitHub issue

Introduction

The NATS.connect() method, when given an unreachable IP address, times out after the default 120s (2 minutes). However, this time period is too long for constantly changing microservices and their respective upstream NATS transporters. There should be a way for a client to specify the timeout manually as a property to the options passed to the .connect() method.

Rationale

In an environment where connection parameters are provided through a reactive KV store (etcd, Consul, etc.) the application should have the ability to know when a given Host/IP and port pair is unreachable in a specific amount of time lest incurring a downtime of no visibility for at least 2 minutes.

Consider a case where the configuration parameters have just been changed and the services are reloading; for 2 minutes, they will just hang with no output thus not giving any real telemetry data pointing to am erred configuration option.

Implementation

In order to understand the implementation, we must first look at the line which actually initializes a TCP connection:

https://github.com/nats-io/nats.js/blob/407193dbe851ac336da4c9cff1e052ffd9328bdf/lib/nats.js#L869

net.createConnection(port, host) calls socket.connect(port, host) wherein the default socket options (inter alia, timeout set to 120000) are used.

Caveat

The net module does not provide a method to set the connect timeout; the socket.setTimeout sets the time before which the socket is destroyed when no data is received or sent (basically it sets the SO_RCVTIMEO and SO_SNDTIMEO parameters).

Basic Implementation

We can abuse how .setTimeout() works and wrap the connect method as a deferred function call.

Something like this, probably:

const net = require( 'net' );

const socket = net.createConnection( port, host );
const _timeout = setTimeout( () => {
    socket.destroy();
    throw new errors.SocketTimeoutError( options.timeout );
}, options.timeout );

socket.on( 'connect', () => clearTimeout( _timeout ) );
this.stream = socket;

The idea here is that if we do not receive the connect event after options.timeout milliseconds, the function in the setTimeout() call will destroy the socket and throw an error which the client can use to understand what happened. If, however, the socket manages to connect within the specified period, we just clear the timeout thus preventing it from throwing any errors.

Please keep in mind that this is just a very basic PoC-like approach and might require some test cases to ensure cross-platform compatibility.

Conclusion

That is what I had in mind. I’d be more than happy to submit a PR for this should this feature be accepted. 😄

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
aricartcommented, Jan 20, 2020

@labsvisual - already have it ready 😃

0reactions
aricartcommented, Jan 22, 2020

@labsvisual I have published this new option, on the next release channel. To get it simply npm install nats@next.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Setting a Connect Timeout - NATS Docs
Each library has its own, language preferred way, to pass connection options. One of the most common options is a connect timeout.
Read more >
c# - How to configure socket connect timeout - Stack Overflow
I found this. Simpler than the accepted answer, and works with .NET Framework v2. Socket socket = new Socket(AddressFamily.
Read more >
nats - Go Packages
FlusherTimeout is an Option to set the write (and flush) timeout on a connection. func IgnoreAuthErrorAbort ¶ added in v1.21.0. func IgnoreAuthErrorAbort() ...
Read more >
Modules - NATS Docs
options – NATS connect options. ... TimeoutError. Return type ... fetch makes a request to JetStream to be delivered a set of messages....
Read more >
nats - npm
REQ_TIMEOUT) { console.log('Request for help timed out. ... set the encoding option on the connection. nc = nats.connect({'servers':servers, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found