googleapis/google-api-ruby-client

Rails console freezes when using gmail api gem

goteusz-maszyk opened this issue · 6 comments

The problem:
Trying to start rails console when the google api gem is installed causes it to immediately freeze (not accept any input), with even no possibility to stop it other, then using task manager.

The console looks very "normal", except there is a ▽ before the first irb line.

Environment details

  • OS: Windows 11
  • Ruby version: 3.1.2p20
  • Gem name and version: google-apis-gmail_v1 0.29.0

Steps to reproduce

  1. add google-apis-gmail_v1 0.29.0 to Gemfile in Rails app
  2. start rails console

Code example

C:\Users\(hidden path)>rails c
Loading development environment (Rails 7.0.5.1)
▽irb(main):001:0> ^C # you can press CTRL+C forever and it won't do anything
irb(main):001:0>

I discovered this issue by checking all commits that changed the gemfile and adding google api gem was the impostor (probably)

I can confirm this, along with other problematic issues on Windows. I ran into this problem while using the third-party 'google_drive' gem. Thinking that it was to blame, I switched to directly using the 'google-apis-sheets_v4' gem. The problem(s) occur immediately upon running require 'google/apis/sheets_v4'.

Here is the first problem I observe: while using 'irb' as soon as you require 'google/apis/sheets_v4' then no further input or output is possible in this window. The only solution is to close the console window. This occurs whether using PowerShell, 'cmd', or even cygwin console.

Here is the second problem I observe, which is probably related. When I run my script (which used the 'google_drive' gem and thus indirectly the 'google-apis-sheets_v4' gem, I think) from a console, it works. However, when I have another Ruby script launch my script as a spawned process (using Process.spawn "start "" /d "D:\Temp" /b "P:\Code\path\to\script""), it throws Errno::EPIPE with message: "Broken pipe @ rb_io_flush_raw - ". The stack trace includes the following: ["C:/Ruby32-x64/lib/ruby/3.2.0/forwardable/impl.rb:4:in compile'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable/impl.rb:4:in _valid_method?'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:213:in _delegator_method'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:189:in def_instance_delegator'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:159:in block in def_instance_delegators'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:157:in each'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:157:in def_instance_delegators'", "C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:730:in singleton class'", "C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:712:in <module:Psych>'", "C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:234:in <top (required)>'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:148:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:148:in require'", "C:/Ruby32-x64/lib/ruby/3.2.0/yaml.rb:4:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:148:in require'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:148:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/os-1.1.4/lib/os.rb:2:in <top (required)>'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/credentials_loader.rb:31:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/default_credentials.rb:33:in <top (required)>'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/application_default.rb:31:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth.rb:30:in <top (required)>'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/google_drive-3.0.7/lib/google_drive.rb:5:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:159:in require'", "internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:159:in rescue in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:39:in require'", "P:/Code/path/to/my/script.rb:1:in `<top (required)>'"...

In this case, it seems related to the fact that it is running in a shell-less environment and thus has no STDOUT. For some reason (this is my hypothesis) one of the libraries is trying to take control of STDOUT, which causes the first problem we see in the 'irb' console, and causes the error to be thrown in a shell-less environment. (?)

Needless to say, whether it's caused by the Google API gems or another gem that they depend on, this is highly problematic behavior, preventing me from running a background service that needs to integrate with Google Sheets for automation. I have only tested on Windows 11.

Follow-up: after I changed from the 'google-drive' gem to straight-up 'google-apis-sheets_v4' I am still getting the error when running the process without a console:

Errno::EPIPE
Error message: Broken pipe @ rb_io_flush_raw -
Stack trace:
"C:/Ruby32-x64/lib/ruby/3.2.0/forwardable/impl.rb:4:in compile'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable/impl.rb:4:in _valid_method?'",
"C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:213:in _delegator_method'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:189:in def_instance_delegator'",
"C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:159:in block in def_instance_delegators'", "C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:157:in each'",
"C:/Ruby32-x64/lib/ruby/3.2.0/forwardable.rb:157:in def_instance_delegators'", "C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:730:in singleton class'",
"C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:712:in <module:Psych>'", "C:/Ruby32-x64/lib/ruby/3.2.0/psych.rb:234:in <top (required)>'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:148:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:148:in require'",
"C:/Ruby32-x64/lib/ruby/3.2.0/yaml.rb:4:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:148:in require'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:148:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/os-1.1.4/lib/os.rb:2:in <top (required)>'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'",
"C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/credentials_loader.rb:31:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/default_credentials.rb:33:in <top (required)>'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'",
"C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth/application_default.rb:31:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/googleauth-0.17.1/lib/googleauth.rb:30:in <top (required)>'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:96:in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:96:in require'",
"C:/Users/성전/.local/share/gem/ruby/3.2.0/gems/google_drive-3.0.7/lib/google_drive.rb:5:in <top (required)>'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:159:in require'",
"internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb:159:in rescue in require'", "<internal:C:/Ruby32-x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:39:in require'",
"P:/path/to/my/script.rb"...

Further follow-up, with a workaround for the second issue (not the 'irb' issue, but the Errno::EPIPE exception). I launch the script from within another script and use ' >nul 2>nul' at the end.

In one Ruby script launching another within Windows, this seems to work for me and no longer throws the exception:

pid = Process.spawn "start "" /d "C:\Temp" /b ruby "C:\path\to\my\script.rb" >nul 2>nul"
Process.detach(pid)

I don't claim this is the best or right way to do things, but it's my workaround that seems to work.

Bump? I haven't still received LITERALLY ANY support

Hi. This is on our radar and we are investigating it. Will post updates here.