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

make it work with ruby 3.1 by upgrading thin to the latest version … #496

Closed
wants to merge 12 commits into from
Closed

Conversation

Wanderfalke
Copy link

…and replacing skinny with faye-websocket.

also allow mailcatcher process to be stopped with SIGINT / CTRL+C

…and replacing skinny with faye-websocket

+ allow mailcatcher process to be stopped with SIGINT
@Vincent14
Copy link

Hi @sj26 or @tagliala @westonganger could you have a look please? <3

@westonganger
Copy link
Contributor

Unfortunately I am not a maintainer of this project. I think I reached out before. But if more maintainership help is needed I am willing.

@sj26
Copy link
Owner

sj26 commented Mar 2, 2022

Thanks for the contribution! But there is already a conflicting stategy for upgrading thin and websockets etc over here:
#467

The blocker is testing, including adding more feature spec coverage. That blocker still exists on this branch. If you're keen to contribute, looking at the surface area of mailcatcher and adding feature specs would be a great contribution.

@sj26
Copy link
Owner

sj26 commented Mar 2, 2022

allow mailcatcher process to be stopped with SIGINT / CTRL+C

This should already be working:

image

@sj26
Copy link
Owner

sj26 commented Mar 2, 2022

Reading this again, it's a pretty small intervention so might be easier to land. I'll do a review and maybe we can land it.

@@ -178,6 +178,12 @@ def run! options=nil

# One EventMachine loop...
EventMachine.run do
trap("INT") do
EventMachine.add_timer(0) do
Copy link
Owner

Choose a reason for hiding this comment

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

I think EventMachine should already be quitting cleanly. But, if not, I think for this line you want:

Suggested change
EventMachine.add_timer(0) do
EventMachine.next_tick do

Copy link
Author

Choose a reason for hiding this comment

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

You're right. The magic was to pass signals: false to thin.

Copy link
Owner

Choose a reason for hiding this comment

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

But now thin doesn't exit cleanly?

Sorry, by "EventMachine should already be quitting cleanly" I meant that thin's signal handler is enough to shut down the reactor including draining thin's connections cleanly. Did that break? Is that why you made this change initially?

Copy link
Owner

Choose a reason for hiding this comment

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

Ctrl+C now does this for me:

 ▲ ~/Developer/mailcatcher bundle exec mailcatcher --foreground                                                                               Wanderfalke-main 9m ● ⬡
Starting MailCatcher v0.8.1
==> smtp://127.0.0.1:1025
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:208: warning: previous definition of BUFSIZE was here
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:504: warning: previous definition of Socket was here
==> http://127.0.0.1:1080
^CTraceback (most recent call last):
	20: from /opt/rbenv/versions/2.7.5/bin/bundle:23:in `<main>'
	19: from /opt/rbenv/versions/2.7.5/bin/bundle:23:in `load'
	18: from /opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.1.4/libexec/bundle:34:in `<top (required)>'
	17: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/friendly_errors.rb:123:in `with_friendly_errors'
	16: from /opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/bundler-2.1.4/libexec/bundle:46:in `block in <top (required)>'
	15: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli.rb:24:in `start'
	14: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
	13: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli.rb:30:in `dispatch'
	12: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
	11: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	10: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
	 9: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli.rb:476:in `exec'
	 8: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli/exec.rb:28:in `run'
	 7: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli/exec.rb:63:in `kernel_load'
	 6: from /opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/bundler/cli/exec.rb:63:in `load'
	 5: from /opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/bin/mailcatcher:23:in `<top (required)>'
	 4: from /opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/bin/mailcatcher:23:in `load'
	 3: from /Users/sj26/Developer/mailcatcher/bin/mailcatcher:6:in `<top (required)>'
	 2: from /Users/sj26/Developer/mailcatcher/lib/mail_catcher.rb:180:in `run!'
	 1: from /opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.0.9.1/lib/eventmachine.rb:193:in `run'
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/eventmachine-1.0.9.1/lib/eventmachine.rb:193:in `run_machine': Interrupt

Copy link
Author

Choose a reason for hiding this comment

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

My initial motivation for this was the fact, that for me on MacOS 12.1 (Intel) CTRL+C / SIGINT did nothing and mailcatcher process can only be stopped with SIGKILL.
Passing "signals: false" to thin makes SIGINT work, but as you state above also prints stacktrace. Explicitely trapping INT signal in the eventmachine loop makes it exit cleanly.
BTW, your suggestion to use "EventMachine.next_tick" leads to following error: eventmachine.rb:1117:in "synchronize": can't be called from trap context (ThreadError)

s.add_dependency "thin", "~> 1.5.0"
s.add_dependency "skinny", "~> 0.2.3"
s.add_dependency "thin", "~> 1.8.0"
s.add_dependency "net-smtp", "~> 0.3.0"
Copy link
Owner

Choose a reason for hiding this comment

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

Why was net-smtp added here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

As already mentioned by @tagliala, as of Ruby 3.1, net-smtp was moved to bundled gems.

Copy link
Owner

Choose a reason for hiding this comment

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

Ah, I see. Thanks.

Copy link
Owner

@sj26 sj26 Mar 4, 2022

Choose a reason for hiding this comment

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

This now spits a lot of warnings during startup for me on Ruby 2.7.5:

$ bundle exec mailcatcher --foreground
Starting MailCatcher v0.8.1
==> smtp://127.0.0.1:1025
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:208: warning: previous definition of BUFSIZE was here
/opt/rbenv/versions/2.7.5/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket
/opt/rbenv/versions/2.7.5/lib/ruby/gems/2.7.0/gems/net-protocol-0.1.2/lib/net/protocol.rb:504: warning: previous definition of Socket was here

If it's loading stdlib and the gem, that might cause issues? How does one avoid this double loading on older rubies?

Copy link
Author

Choose a reason for hiding this comment

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

Tried ruby 2.7.5 and I'm getting same warnings. Not sure how to avoid that yet, will keep looking for a solution.

Copy link
Author

Choose a reason for hiding this comment

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

Following this issue: ruby/net-imap#16 , adding net-http as dependency solves "already initialized constant" issues with net-protocol.

@Wanderfalke
Copy link
Author

@sj26 Thank you for taking time to review my PR. I addressed your comments. Please have another look when you can.

@sj26
Copy link
Owner

sj26 commented Mar 5, 2022

I've added a spec on main which tests that mailcatcher exits cleanly on interrupt, and rebasing this branch to include that spec causes a failure:

  1) Quit quits cleanly on Ctrl+C
     Failure/Error: expect(status).to be_exited
       expected `#<Process::Status: pid 56232 SIGINT (signal 2)>.exited?` to be truthy, got false
     # ./spec/quit_spec.rb:41:in `block (2 levels) in <top (required)>'

@Wanderfalke Wanderfalke closed this May 8, 2022
@shaneshort
Copy link

any particular reason this wasn't merged? I'm currently unable to install this on ruby 3.x and I suspect this PR would help.

@sj26
Copy link
Owner

sj26 commented May 27, 2022

There is a failing spec rebased on main, and not enough testing generally to be sure it hasn't broken anything.

@sj26
Copy link
Owner

sj26 commented Jul 4, 2022

Hi folks! Thanks for this work here, especially @Wanderfalke.

Ruby 3.1 support and a switch to faye-websocket are available in 0.9.0.beta1. I've love some folks to test. You can install the latest pre-release with:

gem install --pre mailcatcher

I think there are still some quirks. I don't think the websockets send the quit message before shut down. But that's not critical.

I'm keen to upgrade Thin, too, but I'd like to bed in the switch to faye, first. Beyond that I'll see if we can complete the switch to the async gems (#467).

@sj26 sj26 mentioned this pull request Jan 25, 2023
@larryh
Copy link

larryh commented Aug 4, 2023

I know this is marked as Closed (so hopefully I'm not wasting my time typing this), but I wanted to give the maintainers and anyone else who has this problem some feedback...

I'm using Rails 3.1.0, and when I installed and tried to run mailcatcher 0.9.0 this is what I got:

Unable to load the EventMachine C extension; To use the pure-ruby reactor, require 'em/pure_ruby'
:85:in `require': libssl.so.1.1: cannot open shared object file: No such file or directory - /home/larry/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/eventmachine-1.0.9.1/lib/rubyeventmachine.so (LoadError)
        from :85:in `require'
        from /home/larry/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/eventmachine-1.0.9.1/lib/eventmachine.rb:8:in `'
        from :85:in `require'
        from :85:in `require'
        from /home/larry/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/mailcatcher-0.8.1/lib/mail_catcher.rb:7:in `'
        from :85:in `require'
 

So I ran the following two commands:

gem uninstall mailcatcher
gem install --pre mailcatcher

And it worked like a charm, specifically:

larry@system76-pc:~/RubymineProjects/BackEnd$ mailcatcher
Starting MailCatcher v0.9.1.beta1
==> smtp://127.0.0.1:1025
==> http://127.0.0.1:1080
*** MailCatcher runs as a daemon by default. Go to the web interface to quit.

Thanks for the great gem!

@sj26
Copy link
Owner

sj26 commented Aug 25, 2023

Sorry @larryh, that's very weird!

That sounds like a problem within eventmachine. Perhaps it linked to an older version of openssl? Are you using homebrew? Or another system package manager? It might have upgraded shared libraries beneath your feet.

Reinstalling the gems usually fixes it up for me:

gem pristine eventmachine
# or
gem pristine --all

@larryh
Copy link

larryh commented Aug 26, 2023

Hi,
Thanks for the constant feedback - I know you must be busy and it is much appreciated.

A "gem list" command tells me I have Eventmachine 1.2.7, which I believe is the latest version.(From 5 years ago!) It's not in my (Rails project) Gemfile or even Gemfile.lock. Also, I don't think I ever intentionally installed it, so maybe it just comes along for the ride when I install Mailcatcher.

Also, I'm not on a Mac, so no homebrew. (I'm on Ubuntu)

I'll just continue to refresh the page to see new emails.

Thanks again,
Larry

@sj26
Copy link
Owner

sj26 commented Aug 27, 2023

Heh, Homebrew runs on Linux these days.

But even apt may have bumped your libssl. And apt isn't aware of rubygems, so wouldn't cause dependent gems to be recompiled.

I'd recommend a gem pristine --all just to be safe :-)

@larryh
Copy link

larryh commented Aug 28, 2023

Thanks for the tip. I did a "gem pristine eventmachine" but that didn't do anything; I still have to refresh the page to see the email.

I don't want to try the "all" command because I'm gun-shy of potential unintended consequences. Oftentimes (or at least sometimes) issuing commands that sweeping can result in spending hours just trying to get back to where you were, i.e. "when things worked."

I'll just stick with refreshing the page when I need to.

Thanks for all of your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants