Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use the systemd plugin on JRuby #3079

Merged
merged 6 commits into from Feb 24, 2023
Merged

Conversation

mohamedhafez
Copy link
Contributor

The systemd integration will fail for JRuby at

Addrinfo.unix(sock, :DGRAM).connect do |s|
, because JRuby doesn't support UNIX datagram sockets yet, and won't for a while. See jruby/jruby#6504. So turning it off here, so that JRuby users can integrate with systemd on their own if they wish without errors.

The systemd integration will fail for JRuby at https://github.com/puma/puma/blob/e3d5794a7ebe47577ced4d4dfdd6a6cc969ded01/lib/puma/sd_notify.rb#L140, because JRuby doesn't support UNIX datagram sockets yet, and won't for a while. See jruby/jruby#6504. So turning it off here, so that JRuby users can integrate with systemd on their own if they wish without errors.
@@ -59,7 +59,7 @@ def initialize(conf, launcher_args={})

@environment = conf.environment

if ENV["NOTIFY_SOCKET"]
if ENV["NOTIFY_SOCKET"] && RUBY_PLATFORM != "java"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense seeing the tests are skipped on JRuby:

skip_if :jruby

I do wonder though, can we make the skip more specific?

Similar to Puma::HAS_UNIX_SOCKET / skip_unless :unix:

HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS

(and also skip the tests based on this?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mohamedhafez Can we at least add a comment why we exclude JRuby here?

Should probably also make use of the detection Puma already has?

Suggested change
if ENV["NOTIFY_SOCKET"] && RUBY_PLATFORM != "java"
if ENV["NOTIFY_SOCKET"] && Puma.jruby?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know about Puma.jruby?, added that in (but it needs to be !Puma.jruby?). Also good call with the comment, so people know why this was needed in the future, and also I put the issue in the comment so that if anyone in the future is considering removing it they can double check if the issue was resolved easily.

@dentarg
Copy link
Member

dentarg commented Feb 12, 2023

Just to be clear, there's a use-case for running under JRuby, setting NOTIFY_SOCKET and not wanting to use the built-in functionality (because it just doesn't work? breaks/bring down your app?)

@dentarg
Copy link
Member

dentarg commented Feb 12, 2023

Sounds like a missing test case... :)

@mohamedhafez
Copy link
Contributor Author

Without this patch, it will break JRuby running under systemd when NOTIFY_SOCKET is set (i.e. when the service Type is notify). It will crash with the following error from journalctl -xe. It's a known issue in JRuby, I've filed jruby/jruby#6504 a while ago about it but the current milestone is JRuby 9.5.0.0, so over a year from now in the best case, and possibly longer.

All the constants are defined in JRuby, they just don't work correctly when talking to unix datagram sockets, so anything like Object.const_defined?(:UNIXSocket) won't work, we just have to test if it's JRuby and disable this plugin in that case I believe.

Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]: Puma::SdNotify::NotifyError: SocketError: No message available
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 notify at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/sd_notify.rb:145
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  ready at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/sd_notify.rb:53
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/plugin/systemd.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   fire at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   each at org/jruby/RubyArray.java:1988
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   fire at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:        fire_on_booted! at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:46
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:        fire_on_booted! at /var/www/vhosts/www.substitutealert.com/releases/20230212194636/lib/app_lib/puma_boot_completed.rb:8
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/single.rb:58
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/launcher.rb:189
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/cli.rb:75
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/bin/puma:10
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/bin/puma:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:            kernel_load at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli/exec.rb:58
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli/exec.rb:23
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   exec at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:486
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/command.rb:27
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:         invoke_command at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/invocation.rb:127
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:               dispatch at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor.rb:392
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:               dispatch at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:31
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/base.rb:485
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/exe/bundle:48
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:   with_friendly_errors at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/friendly_errors.rb:120
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/exe/bundle:36
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /home/web/.rvm/rubies/jruby-9.4.1.0.1/bin/bundle:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]: ... 30 levels...
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]: SocketError: No message available
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                connect at org/jruby/ext/socket/RubySocket.java:211
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:       connect_internal at /home/web/.rvm/rubies/jruby-9.4.1.0.1/lib/ruby/stdlib/socket.rb:66
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                connect at /home/web/.rvm/rubies/jruby-9.4.1.0.1/lib/ruby/stdlib/socket.rb:139
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 notify at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/sd_notify.rb:140
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  ready at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/sd_notify.rb:53
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/plugin/systemd.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   fire at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   each at org/jruby/RubyArray.java:1988
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   fire at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:17
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:        fire_on_booted! at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/events.rb:46
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:        fire_on_booted! at /var/www/vhosts/www.substitutealert.com/releases/20230212194636/lib/app_lib/puma_boot_completed.rb:8
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/single.rb:58
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/launcher.rb:189
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/lib/puma/cli.rb:75
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/puma-6.1.0-java/bin/puma:10
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/bin/puma:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:            kernel_load at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli/exec.rb:58
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli/exec.rb:23
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   exec at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:486
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                    run at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/command.rb:27
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:         invoke_command at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/invocation.rb:127
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:               dispatch at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor.rb:392
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:               dispatch at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:31
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/vendor/thor/lib/thor/base.rb:485
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                  start at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/cli.rb:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/exe/bundle:48
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:   with_friendly_errors at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/lib/bundler/friendly_errors.rb:120
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /var/www/vhosts/www.substitutealert.com/shared/bundle/jruby/3.1.0/gems/bundler-2.3.24/exe/bundle:36
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                   load at org/jruby/RubyKernel.java:1091
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]:                 <main> at /home/web/.rvm/rubies/jruby-9.4.1.0.1/bin/bundle:25
Feb 12 12:04:57 ip-172-30-0-20 rvm[353643]: ... 33 levels...
Feb 12 12:04:57 ip-172-30-0-20 systemd[1]: puma.service: Main process exited, code=exited, status=1/FAILURE

@mohamedhafez
Copy link
Contributor Author

mohamedhafez commented Feb 12, 2023

As far as a use case of why I would want run a Type: notify systemd service when JRuby can't use the systemd plugin: I'm pulling in the JNA maven library and using Java code to notify systemd the service has booted after fire_on_booted!.

i.e. I'm taking care of it on my own, and just don't want puma to crash trying to handle it in a way that doesn't work on JRuby.

@mohamedhafez
Copy link
Contributor Author

Could someone with permission label this a bug fix so that the tests will pass?

Added a comment to explain the situation, and used Puma's JRuby detection method instead of re-coding it.
@dentarg
Copy link
Member

dentarg commented Feb 12, 2023

What do you think about adding a test that runs on JRuby, that sets NOTIFY_SOCKET but ensure's the systemd plugin isn't in-use (not sure of the correct/best way to do that though)?

I'm thinking if the JRuby issue is resolved, its very easy to just remove the conditional and think everything is good, but if something fails when you do that, you may remember to remove the "skip jruby" for the systemd plugin tests.

@mohamedhafez
Copy link
Contributor Author

mohamedhafez commented Feb 12, 2023

@dentarg sounds like a good idea, but I'm not sure how to accomplish that without just making sure things don't crash when you set NOTIFY_SOCKET. That wouldn't really help in the case you are describing though, if JRuby really did fix the issue then it won't crash with or without the conditional right?

Perhaps instead in the comment I can just put "If the issue is ever fixed and you remove the && !Puma.jruby?, please remember to fix the systemd tests to run on JRuby as well". It'll be a lot of comments for a small change, but it won't hurt anything 🤷‍♀️

Open to any suggestions. Is there a way to check that a plugin isn't loaded with a test? Like can we stub it out and have it set a variable, and then check if that variable was set or something? Sorry I'm not super familiar with Ruby testing and just thinking off the top of my head

@dentarg
Copy link
Member

dentarg commented Feb 12, 2023

Is there a way to check that a plugin isn't loaded with a test?

Yeah, a bit hacky but: Puma::Plugins.instance_variable_get(:@plugins) (Puma already has bunch of tests using instance_variable_get, don't think this is much different)

@mohamedhafez
Copy link
Contributor Author

mohamedhafez commented Feb 12, 2023

Ok, so I'm thinking make a puma/test/test_jruby_skip_plugin_systemd.rb file, and having it be something like this:

require_relative "helper"
require_relative "helpers/integration"

class TestJRubySkipPluginSystemd < TestIntegration

  THREAD_LOG = TRUFFLE ? "{ 0/16 threads, 16 available, 0 backlog }" :
    "{ 0/5 threads, 5 available, 0 backlog }"

  def setup
    skip "Skipped because Systemd support is linux-only" if windows? || osx?
    skip_unless :unix
    skip_unless_signal_exist? :TERM
    skip_unless :jruby

    super

    ENV["NOTIFY_SOCKET"] = "/tmp/doesntmatter"
  end

  def test_systemd_skipped
    cli_server "test/rackup/hello.ru"
    
    assert_nil Puma::Plugins.instance_variable_get(:@plugins)["systemd"]

    stop_server
  end
end  

Does that sound about right? Or would you prefer I get it into test_plugin_systemd and then add skip_if :jruby to all the other test cases, and then remove it from setup? (I'm guessing the call in setup makes it skip all the tests, since otherwise JRuby would be running and failing on a lot of those tests)

@dentarg
Copy link
Member

dentarg commented Feb 12, 2023

The separate file seems resonable to me 👍 (didn't realise we skip jruby in the setup, in test_plugin_systemd.rb, but that makes sense)

@mohamedhafez
Copy link
Contributor Author

Looks like it worked! You can see the new test being run in the JRuby tests, but not the MRI or TruffleRuby ones. Just seems like there was some kind of failure on an unrelated test, should i just make a dummy push to try it again, or does this look good to you considering the failure has nothing to do with this, and was passing earlier?

@nateberkopec
Copy link
Member

Labelling bug because I do think this is a bug, and this way it will show up in the next version's release notes.

@mohamedhafez
Copy link
Contributor Author

renamed the test because having "skipped" in the name of the test made me think the actual test itself was skipped for a second, and i figure that could be confusing to others. This time we should get all the tests passing we'll see in a sec

@nateberkopec nateberkopec merged commit 0fd1cc5 into puma:master Feb 24, 2023
nateberkopec pushed a commit that referenced this pull request Feb 28, 2023
* Don't use the systemd plugin on JRuby

The systemd integration will fail for JRuby at https://github.com/puma/puma/blob/e3d5794a7ebe47577ced4d4dfdd6a6cc969ded01/lib/puma/sd_notify.rb#L140, because JRuby doesn't support UNIX datagram sockets yet, and won't for a while. See jruby/jruby#6504. So turning it off here, so that JRuby users can integrate with systemd on their own if they wish without errors.

* Improved skipping systemd for JRuby

Added a comment to explain the situation, and used Puma's JRuby detection method instead of re-coding it.

* test that systemd plugin isn't loaded on JRuby

* rename to test_plugin_systemd_jruby.rb, fix lint

* rename test to test_systemd_plugin_not_loaded

* make and use skip_unless :linux
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants