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

Console still doesn't quite work with Ractors #55

Open
Forthoney opened this issue Mar 6, 2024 · 6 comments
Open

Console still doesn't quite work with Ractors #55

Forthoney opened this issue Mar 6, 2024 · 6 comments

Comments

@Forthoney
Copy link

I really appreciate the quick response with #54 , but it still doesn't seem to be fully compatible with Ractors.
I'm still running into an error with my architecture
'write': can't modify frozen IO: #<IO:<STDERR>> (FrozenError)

The full stack trace is
.../console/terminal/logger.rb:116 in call .../console/filter.rb:148 in call .../console/filger.rb:40 in block (3 levels) in []
and my architecture can be found here

@ioquatix
Copy link
Member

ioquatix commented Mar 6, 2024

Thanks, I'll take a look.

@ioquatix
Copy link
Member

ioquatix commented Mar 6, 2024

Do you have any way to reproduce the error? I couldn't figure out how to reproduce it.

@ioquatix
Copy link
Member

ioquatix commented Mar 6, 2024

I managed to make a similar reproduction:

> Ractor.make_shareable(STDERR)
=> #<IO:<STDERR>>

> Ractor.new{STDERR.puts "Hello"}

#<Thread:0x000000012b473408 run> terminated with exception (report_on_exception is true):
(irb):2:in `write': can't modify frozen IO: #<IO:<STDERR>> (FrozenError)
	from (irb):2:in `puts'
	from (irb):2:in `block in <top (required)>'
=> #<Ractor:#2 (irb):2 running>

Any time $stderr can leak into or out of a Ractor, it looks like it can become frozen and then operations may fail. I also noted at least once IO#tty? failed for the similar reason.

@ioquatix
Copy link
Member

ioquatix commented Mar 6, 2024

One thing I can suggest is don't share Console.logger instances anywhere. Only use Console.logger.info (or other log levels) OR better Console.info only. Sharing logger instances may trigger the above situation.

@Forthoney
Copy link
Author

Forthoney commented Mar 7, 2024

My guess as to why the frozen error occurs is when objects are sent over as messages between ractors, ruby implicitly freezes things that can be frozen (it even does this recursively). The IO object is probably being frozen as Console is being passed between ractors. So, this is more so a limitation with Ractor messages than with Console.

In case other people also encounter this challenge, I'll briefly explain here what I did. To work around this limitation, I made it so that there is one "logger" ractor that actually holds on to the Console::Logger. In other ractors, I modify Console::Logger method calls to instead send a message to the "logger" ractor who will then log on behalf of the sender. It's essentially a RPC between ractors. This way, the IO object is not shared between Ractors, but the worker ractors can continue on using Console like normal.

Here's the code for what I do. I just include the module everywhere where Console is used except the logger.

@ioquatix
Copy link
Member

ioquatix commented Mar 7, 2024

The Console class does this already, e.g. Console.info - so if you need to pass a logger, pass Console itself. In theory you can redirect this easily too, using an output layer. I'll try to take a look at your code if I have a moment.

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

No branches or pull requests

2 participants