johnfairh / RubyGateway

Embed Ruby in Swift: load Gems, run scripts, call APIs seamlessly in both directions.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

About Thread Safe

Whirlwind opened this issue · comments

I have a swift app, it will allow open many windows to work. Every window will control a directory and call the ruby and bundler, the directories will use many gems and they have different version. eg: a directory use the Gemfile:

gem "cocoapods", '1.6.0'

other directory use the Gemfile:

gem 'cocoapods', '1.7.0'

But the ruby vm is single and the ruby require will conflict, right? How to work this way?

You are right, the MRI Ruby VM is full of global state and so you cannot have more than one in a process.

If you have a requirement to run multiple versions of cocoapods for example then you may need to consider a multi-process approach for your app.

I have not investigated JRuby or other Ruby implementations: it may be that these are better suited for multi-instance efforts.

It may be better to shell out the CLI commands you want to run rather than embed using RubyGateway at all.

Could I create many VMs to handle multiple ruby environment? I don't like use the CLI.

Unfortunately no: the actual Ruby code itself (libruby.so) is implemented with many C static variables meaning it cannot support multiple VMs per process.

It sounds like you would need multiple Swift processes in your app, one main and one servant per window.

Could the fork work? The fork will create a new process.
By the way, How to call the fork function with a swift block?

posix_spawn enables the fork+exec pattern. Swift doesn't support fork-without-exec.

Sorry, I am not very understand what you said. I am new. :)

fork(2) isn't an option in Swift. You can use posix_spawn(2) to start a child process; here is a Swift wrapper (I haven't tried it).

How the Process.fork in the ruby? I mean that could I call the ruby's fork to start a new ruby vm?

If you are in a pure-ruby process then sure, give it a go. But fork() is not supported for Swift processes.

Quinn's comments in this thread may help you out: https://forums.swift.org/t/multi-process-parallelism/27154

Closing this issue now, beyond a RubyGateway discussion.