socketry / nio4r

Cross-platform asynchronous I/O primitives for scalable network clients and servers.
Other
967 stars 86 forks source link

Workaround for ARM-based macOS Ruby #260

Closed jasl closed 3 years ago

jasl commented 3 years ago

This is a workaround to force enable pure Ruby implementation on ARM-based macOS Ruby (both custom-build & system-bundled)

Ref https://github.com/socketry/nio4r/issues/259

NOTE:

Custom Ruby

jasl@bogon:~$ rbenv shell 3.0.0
jasl@bogon:~$ irb
irb(main):001:0> RUBY_PLATFORM
=> "arm64-darwin20"

System Ruby

jasl@bogon:~$ rbenv shell system
jasl@bogon:~$ irb

WARNING: This version of ruby is included in macOS for compatibility with legacy software.
In future versions of macOS the ruby runtime will not be available by
default, and may require you to install an additional package.

irb(main):001:0> RUBY_PLATFORM
=> "universal.arm64e-darwin20"

Types of Changes

Testing

jasl commented 3 years ago

@ioquatix

Do you accept a workaround like this?

BTW, I'm thinking to force use pure Ruby engine for self-build Ruby on ARM-based macOS too, because it will crash in some cases, but I'm still investigating

igor-makarov commented 3 years ago

BTW @jasl you might wanna update the PR body to explain why it's done this odd way.

jasl commented 3 years ago

BTW @jasl you might wanna update the PR body to explain why it's done this odd way.

Yeah, I updated, please help me what I'm mssing

dcvz commented 3 years ago

This change is required for custom (rbenv) installed ruby as well as the system on an an M1.

Loading nio4r_ext is failing on M1 machines but enabling pure ruby mode for M1 allows nio4r to work.

jasl commented 3 years ago

Without this PR

System Ruby, can't run test because

/Users/jasl/Workspaces/Ruby/nio4r/lib/nio.rb:12: warning: method redefined; discarding old engine
/Users/jasl/Workspaces/Ruby/nio4r/lib/nio.rb:12: warning: previous definition of engine was here

An error occurred while loading ./spec/nio/monitor_spec.rb. - Did you mean?
                    rspec ./spec/nio/selector_spec.rb

Failure/Error: require "nio4r_ext"

LoadError:
  dlopen(/Users/jasl/Workspaces/Ruby/nio4r/lib/nio4r_ext.bundle, 0x0009): missing compatible arch in /Users/jasl/Workspaces/Ruby/nio4r/lib/nio4r_ext.bundle - /Users/jasl/Workspaces/Ruby/nio4r/lib/nio4r_ext.bundle
# ./lib/nio.rb:23:in `require'
# ./lib/nio.rb:23:in `<top (required)>'
# ./spec/spec_helper.rb:6:in `require'
# ./spec/spec_helper.rb:6:in `<top (required)>'
# ./spec/nio/monitor_spec.rb:3:in `require'
# ./spec/nio/monitor_spec.rb:3:in `<top (required)>'

Custom Ruby 3.0

Failures:

  1) NIO::ByteBuffer I/O #read_from reads data into the buffer
     Failure/Error: expect(bytebuffer.read_from(peer)).to eq example_string.length

       expected: 16
            got: 0

       (compared using ==)
     # ./spec/nio/bytebuffer_spec.rb:320:in `block (4 levels) in <top (required)>'

Finished in 7.99 seconds (files took 0.83199 seconds to load)
112 examples, 1 failure, 1 pending

Failed examples:

rspec ./spec/nio/bytebuffer_spec.rb:318 # NIO::ByteBuffer I/O #read_from reads data into the buffer

Randomized with seed 52481

[Coveralls] Outside the CI environment, not sending data.
/Users/jasl/.rbenv/versions/3.0.0/bin/ruby -I/Users/jasl/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/rspec-core-3.10.1/lib:/Users/jasl/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/rspec-support-3.10.1/lib /Users/jasl/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/rspec-core-3.10.1/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb failed
jasl@bogon:~/Workspaces/Ruby/nio4r on master$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [arm64-darwin20]

With this PR

System Ruby

Finished in 7.99 seconds (files took 0.13846 seconds to load)
107 examples, 0 failures, 1 pending

Custom Ruby 3.0

Finished in 7.98 seconds (files took 0.13716 seconds to load)
112 examples, 0 failures, 2 pending
ioquatix commented 3 years ago

I would like to understand why we aren't compiling this correctly in the first place.

igor-makarov commented 3 years ago

I would also like to understand it, but it seems to affect a lot of native extensions and they don't have a clear cause or solution either.

I believe it would be best to unblock the users of Apple Silicon at the moment.