Skip to content

Infinite loop caused in transport gem when reload_on_failure is true and more than 1 host is provided. #695

Closed
@estolfo

Description

@estolfo

The perform_request method will get itself into an infinite loop when reload_on_failure is set to true and more than 1 host is provided.

The issue is in the rescue block:

if @options[:reload_on_failure] and tries < connections.all.size
  logger.warn "[#{e.class}] Reloading connections (attempt #{tries} of #{connections.all.size})" if logger
  reload_connections! and retry
end

On the first try, tries is 1 and connections.all.size is greater than 1 so the if condition is met. reload_connections! will then call sniffer.hosts that then also calls the perform_request method. tries is reset at 1 when this method is called so this rescue block is reached and and the cycle continues, infinitely.

The key to getting the SystemStackError: stack level too deep error and not a timeout error is to set the sniffer_timeout high enough so that the timeout doesn't interrupt the infinite loop before the SystemStackError: stack level too deep is thrown. This is why the error was originally not able to be reproduced.

I was able to reproduce the error with the following client settings:

      {
        hosts: ['http://unavabilable:9200', 'http://unavabilable:9201'],
        reload_on_failure: true,
        sniffer_timeout: 50
      }
> client.info  
# SystemStackError: stack level too deep

Please see this issue for further history: #177

Metadata

Metadata

Assignees

No one assigned

    Labels

    8.0For 8.0 release

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions