00:00:06
Today, I want to talk about a new concurrency model for Ruby 3. This presentation is being delivered in English, but if you have any difficulties, I have prepared Japanese scripts for you. You can read them if you prefer.
00:00:36
First, let's visit the RubyKaigi schedule page, which showcases many concurrency talks. This indicates that concurrency is a significant topic of discussion, as we have at least two parallel sessions.
00:01:00
People are discussing concurrency mainly because of performance. They want to run Ruby programs in parallel to improve performance. Currently, Ruby cannot run threads in parallel, which raises the question of how we can achieve this.
00:01:36
In today's talk, I will explain why thread programming is difficult, why we need a new abstraction for Ruby, and I will introduce the new idea called "Guild" for Ruby 3.
00:02:02
I am currently living in Tokyo and am a developer focusing on internal features. I am an employee at Salesforce and will discuss the difficulties of multi-threaded programming.
00:02:38
How many people here attended the previous session? I see many hands. I believe you understand why thread programming is challenging.
00:03:02
Before discussing the challenges, I want to show some historical context regarding programming language evolution. There is a trade-off between performance and safety. We want to create faster programs while also ensuring they are safe and easy to use.
00:03:55
In some cases, performance and safety are at odds. I'm sorry for not being a Ruby programmer but a C programmer, so I'll use C as an example. In C programming, we need to use pointers to manipulate strings, allowing significant control, leading to very fast operations.
00:04:46
However, the ease of generating bugs and causing unexpected behaviors is a disadvantage of pointers. Ruby, in contrast, uses a well-managed string class that is easier to use but may be slower because we cannot control everything.
00:05:01
Ruby's garbage collector simplifies memory management, so we don't need to worry about object lifetimes. However, we cannot control garbage collection with fine granularity. Thus, Ruby opts for safety and ease of programming.
00:05:55
The maturity of Ruby's design allows for easier programming, as current computers are fast enough that small overheads in programming are acceptable. But issues arise when programming with threads due to the difficulty of sharing mutable state.
00:06:45
For example, it is challenging to make correct and fast concurrent programs due to race conditions and the phenomenon of non-deterministic behaviors. This makes it hard to reproduce issues and leads to bugs.
00:07:28
Consider a traditional bank transfer program. This illustrates how concurrency introduces complexities due to data problems and bugs, expressing the need for proper locking mechanisms to avoid issues.
00:08:03
However, using locks introduces its challenges, as complicated locking can lead to unpredictable results in concurrent programming.
00:08:31
Let’s consider a simple example in Ruby where a thread attempts to concatenate arrays. The result will depend on the execution flows of those threads, making it hard for developers to anticipate the outcome.
00:09:00
We can face exceptions due to concurrent modifications, indicating that managing shared mutable objects safely is incredibly tricky. Even seemingly straightforward operations can lead to race conditions.
00:09:38
Thus, debugging becomes tough due to non-deterministic behaviors in multi-threaded programs, which are hard to reproduce with small test data but become apparent under large-scale operations.
00:10:20
By the way, all concurrent operations in Ruby are thread-safe due to the Global Interpreter Lock (GIL). This means Ruby does not allow true parallelism, which helps prevent certain types of concurrency issues.
00:11:01
However, relying on GIL alone may not improve performance when dealing with concurrent workloads. For effective concurrency, we should look at alternatives or new abstractions.
00:11:47
In my proposal, 'Guild' introduces a new concurrency model for Ruby 3, preventing shared mutable objects without any restrictions to lower the risks associated with concurrency.
00:12:38
I drew inspiration from other programming languages like C, which has pipes to manage inter-process communication. By prohibiting mutable objects, we can introduce immutability into Ruby.
00:13:15
The Guild model allows programmers to leverage immutable communication between threads, which inherently reduces the risks of concurrency, making programming easier and safer.
00:14:02
We also introduce a guild channel object that manages communication risk-free since sharing mutable objects is not permitted. This encourages safer programming practices.
00:14:48
In Ruby 3, the 'Guild' will streamline concurrency. It allows threads to belong to specific guilds, ensuring that mutable objects cannot span across multiple threads. This fundamentally changes how concurrency is handled.
00:15:25
If done correctly, Guild can accommodate many threads organized into groups, allowing better management of concurrency without locks usually required in current paradigms.
00:16:10
With Guild, performance becomes manageable. We won't have the unpredictable behaviors typically associated with multi-threading. It shelters immutable objects in guilds while effectively transferring ownership.
00:16:55
The focus on Guild is to ensure that communication occurs via immutability to maintain simplicity while providing necessary performance.
00:17:41
To wrap it up, I propose that we embrace this new concurrency model for Ruby 3, making Ruby not only better suited for multi-threading but easier to understand.
00:18:27
Finally, I hope to explore and implement these ideas further and look forward to discussing the potential for enhancing Ruby's concurrency capabilities.
00:19:05
Thank you for your attention. I am happy to answer any questions.
00:20:22
Yes, all messages can be received via channels. We should also explore matching mechanisms for specific types of messages.
00:20:53
Guild maintains a degree of compatibility with Ruby 2 by allowing threads. Libraries may still use threads, and our goal is to help minimize any potential issues.
00:21:53
The example with the array concatenation in the Guild model illustrates how to avoid mutable shared objects and showcase how difficult concurrency can be.
00:22:32
The efficiency of the move operation is critical for performance, and improvements can be made on it to accommodate faster operations without risking safety.
00:23:10
We need to ensure that mutability is properly managed to keep efficiency while ensuring that we don't encounter issues caused by improper use of mutable state.
00:23:44
In conclusion, many aspects should be taken into account, especially with global variables and classes, as they affect how we implement the Guild model.
00:24:20
Thank you for your valuable questions, and I look to refine and enhance these concepts further.