googleapis / ruby-spanner

Apache License 2.0
5 stars 11 forks source link

Empty string for `emulator_host:` causes runaway Ruby process #69

Closed abachman closed 11 months ago

abachman commented 1 year ago

When trying to connect to Spanner, if SPANNER_EMULATOR_HOST in the environment is set to an empty string or emulator_host: '' is passed to Google::Cloud::Spanner.new, then the Ruby process locks up hard enough to break SIGINT (ctrl-c in the shell).

I can still use ctrl-z to background the process, but I have to use kill -9 to stop it.

Environment details

It's happening both in my host system and in a docker image, so I'll note ENV for both.

The problem was first discovered in a Rails app using the activerecord-spanner-adapter gem, but since this gem is a level down and also has the bug, I'm filing the issue here.

Additionally, we see this bug regardless of the settings given in the Rails config/database.yml file. Something in this library or lower in the stack is ignoring configuration passed as arguments and attempting to connect to a blank-URI Spanner emulator host.

Steps to reproduce

  1. require 'google-cloud-spanner' in a project.
  2. Set SPANNER_EMULATOR_HOST to the empty string in the process environment or pass emulator_host: '' to Google::Cloud::Spanner.new.
  3. Try to create a new client connection / session.

Code example

There are a few ways to trigger it:

# empty_emulator_host.rb 
require 'google/cloud/spanner'

spanner = Google::Cloud::Spanner.new(project: 'loldontcare', emulator_host: '')
spanner.client 'makesno', 'difference'
$ ruby empty_emulator_host.rb
E1106 13:19:41.456743000 7999247104 dns_resolver_ares.cc:351]          no server name supplied in dns URI
E1106 13:19:41.457047000 7999247104 channel.cc:121]                    channel stack builder failed: UNKNOWN: the target uri is not valid: dns:///

Or setting SPANNER_EMULATOR_HOST to empty string in the env.

# without_emulator_host.rb 
require 'google/cloud/spanner'

spanner = Google::Cloud::Spanner.new(project: 'bogus')
spanner.client 'some', 'any'
$ SPANNER_EMULATOR_HOST= ruby without_emulator_host.rb
E1106 13:28:01.700065000 7999247104 dns_resolver_ares.cc:351]          no server name supplied in dns URI
E1106 13:28:01.700106000 7999247104 channel.cc:121]                    channel stack builder failed: UNKNOWN: the target uri is not valid: dns:///

Both cases result in the same failure.

Sob Story

This is a painful bug in my current situation, because I'm trying to write coherent developer documentation for a large legacy Rails app, but if the SPANNER_EMULATOR_HOST environment variable sneaks in with no value, it can lock up a Rails process, test suite, random script, rake task, etc. And it locks up with no stack trace and no obvious cause.

My current patch / hack is to add this to the top of an early Rails config/initializers/*.rb file:

ENV.delete('SPANNER_EMULATOR_HOST') if ENV['SPANNER_EMULATOR_HOST'] == ''

But it makes me sad :(

NivedhaSenthil commented 11 months ago

Thanks for putting in an elaborate issue.. looked at putting in a quick fix for this.