derekcollison/nats — pull request #58 by jackytu (2013-09-30 04:38:45+00:00)
Title: FIX  NATS-Client never stop reconnecting until ran out of timers if auth failed

HI, Derek:
In our recent practice, we found that if the application not exit when nats-client auth failed (e.g cloudfounry1.0/router ), the client won't exit until eventmachine raise ‘ran out of timers’ exception (after 100000 reconnect attempt), it can be reproduced as the spec test later.

There are several points about this:
+ The client add ping timer right after connection completed;
+ When client connect to the same server, the reconnect_attempt set to 0;
+ When server close connection due to auth fail, the server always be true when can_reuse_server? , since the reconnect_attemp kept being 0 all the time, never reach to the max_reconnect_attempt;
+ And client kept adding ping timer after each reconnection completed;
+ The infinity loop finally exit after 100000 timer limit of eventmachine;

![natsfail](https://f.cloud.github.com/assets/3814418/1234640/b941b33e-2982-11e3-96e0-69427e5072ec.jpg)

I believe there are some ways to get this resoved.

1. Only add ping timer after auth is OK;
2. Not setting reconnec_attempt to 0, if the server to connect is just the same server connected before;

Spec test (auth_spec.rb):
```ruby
it 'should giveup reconnect to an authorized server without proper credentials after max attempt' do
EM.set_max_timers(100)
expect do
EM.run do
NATS.on_error do |e|
if e.kind_of? NATS::ConnectError
EM.stop
else
p "NATS problem, #{e}"
end
end
NATS.start(:uri => TEST_AUTH_SERVER_NO_CRED, :max_reconnect_attempts => 2) {
EM.add_timer(10){
EM.stop
}
}
end
end.to_not raise_error
end
```
And the test would failed as following:
```ruby
authorization should giveup reconnect to an authorized server without proper credentials after max attempt
Failure/Error: expect do
expected no Exception, got # with backtrace:
# ./lib/nats/client.rb:615:in `connection_completed'
# ./spec/auth_spec.rb:40:in `block (3 levels) in '
# ./spec/auth_spec.rb:39:in `block (2 levels) in '
# ./spec/auth_spec.rb:39:in `block (2 levels) in '
```