spring icon indicating copy to clipboard operation
spring copied to clipboard

Connection refused in cold_run

Open marvinthepa opened this issue 5 years ago • 0 comments

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 https://github.com/rails/spring/blob/a9473e925e91b9d5844e10efdbb02a8c858aaed1/lib/spring/client/run.rb#L81 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 https://github.com/rails/spring/blob/a9473e925e91b9d5844e10efdbb02a8c858aaed1/lib/spring/client/run.rb#L76 :

        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?

marvinthepa avatar Jun 05 '19 15:06 marvinthepa