Skip to content

Connection refused in cold_run #592

@marvinthepa

Description

@marvinthepa

Spring 2.0.2 on OpenBSD (which might be the cause of us seeing the race condition due to its slowness).

vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:26:in `initialize': Connection refused - connect(2) for /var/run/spring/103b87e8a42dc3cc7a9ec24c7d7e65f1 (Errno::ECONNREFUSED)
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:26:in `open'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:26:in `connect'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:57:in `cold_run'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:33:in `rescue in call'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/run.rb:30:in `call'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/rails.rb:24:in `call'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/lib/spring/client.rb:30:in `run'
        from vendor/bundle/ruby/2.3/gems/spring-2.0.2/bin/spring:49:in `<top (required)>'
        from vendor/bundle/ruby/2.3/bin/spring:22:in `load'
        from vendor/bundle/ruby/2.3/bin/spring:22:in `<main>'

There seems to be some race condition that the socket file already exists, but does not answer yet:

      def cold_run
        boot_server
        connect  # <- error occurs here, server "should" already be booted
        run
      end

I would guess that something like this in

until env.socket_path.exist?
would help:

        until env.socket_path.exist? && socket_ready?

with a suitable implementation of socket_ready?, e.g.

      def socket_ready?        
        begin
          socket = UNIXSocket.open(env.socket_name)
        rescue Errno::ECONNRESET, Errno::ECONNREFUSED
          return false
        ensure
          socket && socket.close
        end
        true
      end

Related: it might be helpful in cases like this (i.e. hard to reproduce) to be able to always log the output of the spring server, not only when started manually. E.g. something like

pid = Process.spawn(gem_env, env.server_command, out: File::NULL)
:

        pid     = Process.spawn(gem_env, env.server_command, out: env.log_name)

Do you want a pull request for one or both of these issues?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions