Hiếu Nguyễn

Solving Real-World Challenges with Ruby Ractor

#rubyconftw 2023

Solving Real-World Challenges with Ruby Ractor

In this talk, we explore on how we can take advantage of Ractor to improve parallel processing in some real world scenarios, such as data encryption and transaction processing. We delve into some features of Ractor, with their strength and limitation, and how to migrate thread-based or process-based functionalities using them. This talk hopefully will give the audience more insights on how they can improve their application performance.

RubyConf Taiwan 2023

00:00:28.960 Welcome! My name is Hiếu Nguyễn, and today we will talk about solving real-world challenges with Ruby Ractor. We’ll explore how we can take advantage of Ractor to improve parallel processing in scenarios such as data encryption and transaction processing. Throughout this talk, I will discuss some potential challenges and questions that people often ask about using Ractor in Ruby applications.
00:01:15.240 In recent years, we have been utilizing Ruby on Rails, particularly with the introduction of Ruby 3 and features such as the just-in-time compiler. This improvement allows us to enhance application performance significantly. Ractor's design offers several strengths and limitations, and it is essential to understand how to migrate functionalities from thread-based or process-based models to Ractor-based models. When developing with Ractor, we found various lessons to share with you, especially regarding the handling of concurrent processes.
00:03:21.360 One of the essential concepts to grasp when using Ruby Ractor is the no-shared mutable state pattern. In Ractor, each instance has its own memory, which helps prevent issues related to data consistency. This setup allows for parallel execution without the need for locking mechanisms, making operations much simpler and more efficient than traditional threaded implementations.
00:04:05.159 The traditional approach using threads involves shared memory, where even slight modifications to data can lead to inconsistencies and requires locking, which can significantly slow down the performance. On the other hand, since Ractors operate independently, they communicate by sending and receiving messages. This communication model ensures that data is not inadvertently modified, enhancing the safety and reliability of our applications.
00:04:44.280 Furthermore, it's crucial to consider the performance implications when migrating existing applications to utilize Ractor. We've seen measurable performance improvements when implementing Ractors, such as being able to process hundreds of requests simultaneously, which might have been challenging using traditional threading due to performance bottlenecks.
00:05:48.720 When dealing with user data, it's essential to handle personal information securely. In our implementation, the user data is encrypted before processing. This method ensures that sensitive information is protected, and only authorized components can access the decrypted data. While this makes encryption a costly operation in terms of processing time, utilizing Ractor has allowed us to manage these operations more effectively compared to previous implementations.
00:06:11.160 One instance we encountered involved processing encrypted user data from a banking application. Previous solutions often became bottlenecks when handling vast amounts of user data, requiring optimization for performance gains. We have transitioned to using Ractor for this purpose, allowing individual jobs to be processed concurrently. This shift has proven to be advantageous as we've observed a drastic reduction in processing time.
00:07:09.600 In terms of actual implementation, the Ractor model requires an adjustment in how we structure our classes and methods. By ensuring that memory is not shared across Ractors, we mitigate various threading issues. Moreover, while it's vital to ensure data integrity, it is just as crucial to optimize how we handle potentially mutable data within Ractor workloads.
00:07:46.200 The exciting part about Ractor technology is its inherent design for simplicity and performance. By removing the complexities of thread management, we find Ractor serves as a robust solution for building concurrent Ruby applications. This approach ultimately allows our teams to focus more on developing features rather than grappling with the intricacies of concurrency handling.
00:08:24.600 Despite its advantages, some challenges accompany the adoption of Ractor, particularly concerning instability and ongoing implementation issues. It's worth noting that the community is actively working towards iron out these issues, but this remains an area of concern for production-level applications. Understanding the limitations of Ractors is critical for developers, particularly when deciding whether to migrate existing codebases or start new projects from scratch.
00:09:14.280 Another critical aspect to consider is the communication overhead between Ractors. While sending and receiving messages between Ractors is necessary for interaction, developers must be mindful of how much data is transferred. Excessive message passing can negate some of the performance benefits offered by Ractor parallelism. As we gain more experience with Ractors, it becomes evident that adopting a thoughtful messaging and architecture design leads to optimal outcomes.
00:09:59.680 Our future goals include expanding our use of Ractors beyond the current implementations. We aim to improve error handling and incorporate mechanisms that allow for easier debug and tracing of issues arising in Ractor-based applications. While Ractors provide better performance, isolating issue tracking remains essential as we endeavor to deploy complex applications.
00:10:57.600 As far as support is concerned, there's a growing number of libraries gradually adopting Ractor. However, many developers still hesitate due to unfamiliarity with Ractor concepts, which leads to significant variability in implementation outcomes. Establishing solid documentation and use cases will undoubtedly foster wider adoption across the Ruby development community.
00:13:42.280 In conclusion, Ruby Ractor presents an innovative solution for tackling concurrent workloads in Ruby applications. Its design philosophy prioritizes simplicity and safety, enabling developers to focus on building robust features without the overhead of traditional multi-threading concerns. As the framework evolves, we can expect Ractors to play a central role in the advancement of Ruby's concurrency capabilities.
00:15:00.000 During the Q&A session, various questions arose regarding the practicalities of Ractor alongside established threading models. Some inquiries focused on the challenges developers face when transitioning and how the community is addressing these challenges moving forward. Ultimately, the consensus recognizes the potential Ractor holds, coupled with the call for continued support and iterative improvements to bolster its acceptance.
00:15:43.120 I strongly encourage anyone interested in exploring Ractor further to engage with the growing community and observe how others are integrating Ractor into their projects. With its distinct advantages, particularly in performance enhancement, Ractor stands to revolutionize how Ruby developers handle concurrency in the future.
00:16:44.480 Thank you for your time, and I look forward to any further questions you might have regarding Ruby Ractor or any challenges you've experienced in your development. Let's engage in a discussion about how we can use Ractor to optimize your applications and improve performance. As we reach the end of this session, I hope you found this talk insightful and inspiring for your future Ruby adventures!