Skip to content

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

Closed
Wanderfalke wants to merge 12 commits into
sj26:mainfrom
Wanderfalke:main
Closed

make it work with ruby 3.1 by upgrading thin to the latest version …#496
Wanderfalke wants to merge 12 commits into
sj26:mainfrom
Wanderfalke:main

Conversation

@Wanderfalke

Copy link
Copy Markdown

…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
Copy Markdown

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

@westonganger

Copy link
Copy Markdown
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

sj26 commented Mar 2, 2022

Copy link
Copy Markdown
Owner

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

sj26 commented Mar 2, 2022

Copy link
Copy Markdown
Owner

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

This should already be working:

image

@sj26

sj26 commented Mar 2, 2022

Copy link
Copy Markdown
Owner

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.

Comment thread lib/mail_catcher.rb
# One EventMachine loop...
EventMachine.run do
trap("INT") do
EventMachine.add_timer(0) do

Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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)

Comment thread lib/mail_catcher/web/application.rb Outdated
Comment thread lib/mail_catcher/web/application.rb Outdated
Comment thread mailcatcher.gemspec
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
Copy Markdown
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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
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
Copy Markdown
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.

@sj26 sj26 Mar 4, 2022

Copy link
Copy Markdown
Owner

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Author

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

@sj26

sj26 commented Mar 5, 2022

Copy link
Copy Markdown
Owner

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
Copy Markdown

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

sj26 commented May 27, 2022

Copy link
Copy Markdown
Owner

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

@sj26

sj26 commented Jul 4, 2022

Copy link
Copy Markdown
Owner

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

larryh commented Aug 4, 2023

Copy link
Copy Markdown

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

sj26 commented Aug 25, 2023

Copy link
Copy Markdown
Owner

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

larryh commented Aug 26, 2023

Copy link
Copy Markdown

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

sj26 commented Aug 27, 2023

Copy link
Copy Markdown
Owner

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

larryh commented Aug 28, 2023

Copy link
Copy Markdown

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