Talks

Real-Time Rails

Real-Time Rails

by Brian Cardarella

In the RailsConf 2013 presentation titled "Real-Time Rails," Brian Cardarella discusses integrating real-time functionality into Rails applications with the introduction of the Rails 4.0 Live Streaming API. The talk highlights the importance of real-time features in modern web applications and compares the advantages of using Rails with pivotal technologies such as Node.js and EventMachine. Cardarella provides a brief history of the evolution of software technologies to illustrate how complacency in established frameworks can lead to innovative opportunities for newcomers like Node.js.

Key points addressed in the talk include:
- The Evolution of Technology: A light-hearted history of how major players such as IBM, Microsoft, Java, Rails, and Node have competed and evolved.

- Real-Time Functionality: The discussion centers around how Node.js has outpaced Rails in real-time features, emphasizing the importance of handling concurrent requests effectively.

- Concurrency in Rails: By adopting web servers like Puma, Rails 4 can handle multiple requests more efficiently. Advanced Rails developers must understand threading, deadlocks, and race conditions.

- WebSockets and Server-Sent Events: Cardarella covers the implementation of WebSockets for two-way communication and Server-Sent Events (SSE) for one-way communication, demonstrating how these can be set up using Action Controller Live in Rails.

- Practical Examples: He provides demonstrations of real-time chat and drawing applications, showcasing how events are captured and processed. Moreover, libraries like TubeSock simplify WebSocket handling in Rails.

- Challenges and Future of Real-Time Rails: The presentation discusses the limitations of current infrastructure, like Heroku's support for WebSockets, and highlights the need for API advancements.

The conclusion emphasizes that as developers adopt these real-time capabilities in Rails, they will find it possible to build highly responsive applications, thereby enriching user experiences and opening the door to innovative development in future iterations of Rails. Overall, Cardarella inspires developers to explore and embrace the real-time capabilities with the evolving Rails framework.

00:00:16.480 Um, hi. My name is Brian Cardarella.
00:00:19.359 My presentation is about implementing real-time or "real-ish" time in Rails.
00:00:23.199 First, a bit of self-promotion: I'm the owner of a consultancy in Boston called Dockyard.
00:00:29.279 We primarily focus on Rails and Postgres, but we have also been working a lot with Meteor.js lately in Brazil.
00:00:34.800 Additionally, we're organizing the "WikiGood Ruby Conference" in Boston, where we are looking for speakers and attendees. This will be Boston's first Ruby Conference, taking place in October, so if you're interested in visiting the city, please check it out.
00:00:56.559 Alright, we're going to start with a brief history of popular software. This will be a somewhat inaccurate history meant to illustrate a point.
00:01:01.680 Initially, IBM dominated the landscape; they had everything and were essentially a monopoly. Then, a little company named Microsoft emerged and said, "Hey IBM, you're selling the hardware. Why not let us sell the software?" IBM thought selling software was crazy since they believed no one would buy it. Microsoft quickly proved them wrong.
00:01:24.000 Later, when Microsoft was thriving, Java emerged and proclaimed, "We're going to give away software for free." Microsoft responded, shocked that anyone would give software away for free. However, Java flourished and later produced numerous versions.
00:01:35.439 Along came Rails, showcasing the potential of using the Ruby scripting language for server-side programming. Java was skeptical, insisting that no one would buy into the idea of using a scripting language on the server.
00:01:47.520 Nevertheless, Rails became incredibly popular, gaining a following of developers who viewed it as cutting-edge technology. Finally, Node.js appeared, enabling JavaScript to run on the server, which Rails again dismissed as implausible.
00:01:55.680 Fast forward to today, and Node has proven to be highly successful as well. This brief history isn't about accuracy; its purpose is to show how technology and business can become complacent, creating opportunities for newcomers to usurp market share.
00:02:07.360 Real time is just one area where Node has outpaced Rails. There are other aspects to consider. For instance, some may argue that npm has significantly more packages than Ruby gems. However, the sheer quantity of packs doesn't necessarily translate into quality or usefulness.
00:02:20.000 Furthermore, Node has a larger developer base, largely due to JavaScript being the only language that runs in browsers, thus easing developers into server-side programming. However, the challenges faced on the server are vastly different from those encountered in the browser.
00:02:32.639 Historically, Rails was the innovation leader. However, recent developments, especially following the Merb merge, have led Rails to a point where its innovations have largely been focused on organizing applications rather than directly pushing the boundaries into new territories.
00:02:50.240 In contrast, Node has done a remarkable job of innovating. So now we must ask: can Rails scale its features effectively? To answer this, we will look at a primer on some key concepts.
00:03:06.639 I recognize that there’s a broad spectrum of expertise in this room. For more advanced developers, feel free to tune out for the next few slides, as we'll discuss sockets. While some seasoned Rails developers might not yet have experience with this topic, it's becoming increasingly significant.
00:03:18.000 For those looking to deepen their understanding, I highly recommend the book "Working with TCP Sockets" by Jesse Storimer, which provides excellent insights. The basics of sockets for WebSockets is that data sent from the client is segmented into frames, which are then broken into packets.
00:03:38.480 The packets travel through the network to the server, where they are reconstructed into frames, allowing the data to be reassembled. The real goal here is concurrency. We strive for not just real-time data transfer, but also to ensure that multiple transactions can be handled simultaneously.
00:03:52.636 Various concurrent web servers exist, such as Puma, Unicorn, and Thin. Personally, I prefer Puma for its intelligent memory management. While I can't vouch for the exact accuracy of the performance graphs, Puma is said to outperform other servers in memory handling.
00:04:06.800 In Rails 4, as Nick Gauthier quoted, "Rails 4 is now fully concurrent," meaning there’s no overarching lock on your requests when utilizing a concurrent server like Puma. This allows for handling numerous requests with a single process.
00:04:30.240 When operating with WebSockets or Server-Sent Events, becoming accustomed to threading is crucial for Ruby developers. This shift requires adopting practices that ensure thread safety and awareness of potential deadlocks and race conditions.
00:04:50.079 For instance, a simplified example of threading might result in a race condition due to concurrent operations. In more complex applications, such as a chat system, where rooms can hold only limited visitors, participants are assigned to rooms based on concurrent requests. Managing how these requests are processed is critical.
00:05:11.000 To illustrate, if I call upon members from the audience to simulate participant assignments to rooms, the timing of responses can lead to errors in room assignments. Such scenarios underscore the importance of thread safety.
00:05:25.000 To address thread safety issues, a useful approach could involve implementing a queue system to manage concurrent requests. This allows for controlled handling of requests, ensuring proper sequencing and resource management.
00:05:45.000 In the realm of a single Ruby process, you can utilize Ruby’s Mutex class for synchronizing operations. If your server setup lacks built-in functionality for handling queues, external job processors can be employed.
00:06:30.240 Within the concurrency landscape, the publish-subscribe pattern can be incredibly valuable. Popular solutions include Postgres with its `LISTEN` and `NOTIFY` commands. Additionally, Redis is known for its simplicity, while ZeroMQ presents a faster, albeit less common option.
00:06:48.639 For Rails implementations, dealing with real-time interactions often necessitates operating outside of Rails itself, creating an application server adjacent to the Rails app with either EventMachine or Celluloid. EventMachine offers plugins for WebSockets, providing streamlined functionality.
00:07:00.479 One thing to consider is how client experience may not depend on the underlying technologies as long as the applications feel real-time. Despite the challenges, many developers have utilized long polling as a satisfactory solution for real-time experiences.
00:07:30.240 Long polling works by making repeated asynchronous requests to the server, whereupon the server responds with any new data before closing the connection. Each new request essentially restarts the cycle, creating an illusion of a persistent connection.
00:07:55.760 In Rails 4, the introduction of Action Controller Live provides new capabilities for managing real-time interactions. Action Controller Live acts as a proxy object for the socket received through `response.socket`.
00:08:10.240 With Action Controller Live, developers need to adjust headers based on the response type they are delivering. During a long polling request, for example, the server can send back incremental updates generated from model history.
00:08:40.240 The capability to handle streaming responses aligns with the needs of real-time applications. However, as pointed out by Aaron Patterson, working with Action Controller Live does require familiarity with underlying systems and API calls.
00:09:05.600 Furthermore, with the advent of Rack hijacking introduced in Rack 1.5, developers can now manipulate the underlying TCP socket for more efficient event-driven programming within Rails.
00:09:25.760 WebSockets create a two-way communication channel, allowing developers to construct responsive applications. Essential functionality for discovering WebSocket interaction can be achieved using available gems that simplify the handshake processes.
00:09:55.680 As we navigate the WebSocket landscape, understanding how to construct and read handshake frames becomes crucial for managing client-server interaction effectively.
00:10:25.440 The simplicity of the WebSocket API on the client provides a straightforward interface for developers. Callbacks are triggered based on server responses, further refining the user experience.
00:10:46.560 Now, let me demonstrate some applications built upon WebSockets. For instance, we can create a simple chat system along with a collaborative drawing demo using the same underlying Rails architecture.
00:11:06.480 These demonstrations will highlight the practical application of WebSockets, showcasing how multiple users can interact within the same system in real-time.
00:11:18.160 You’ll find the source code for these examples accessible on GitHub at `github.com/Dockyard/real-time-rails`. While the code may be a bit disorganized, it serves to illustrate how to construct real-time features in Rails.
00:11:30.360 Now, we can observe a pattern emerging in real-time applications: events are captured on the client side and then communicated to the server, whereupon the server normalizes the data before broadcasting updates to all connected clients.
00:12:00.320 This leads to the potential utilization of services like Pusher, which facilitate the management of real-time interactions without requiring the implementation of complex infrastructure.
00:12:25.760 Overall, while developing these applications, you might notice how convoluted they can become without a structured approach or the proper tools in place. This is where frameworks like TubeSock can be beneficial, simplifying many websockets operations.
00:12:45.680 There still exist challenges, particularly with platforms such as Heroku, which, to the best of my knowledge, do not yet support WebSockets due to their inventory management system.
00:13:00.720 Nginx can also introduce various complications related to managing persistent connections, necessitating specific configurations to ensure reliability.
00:13:18.080 The future appears bright for real-time applications within the Rails ecosystem. Integrating modern techniques and libraries will continue to enhance the developer experience and the overall performance of applications.
00:13:35.520 If Rack hijack could be seamlessly combined with Action Controller Live, developers might enjoy enhanced workflows when deploying real-time features.
00:13:57.760 In conclusion, the ongoing development of Rails provides immense promise for building responsive, asynchronous applications that leverage real-time capabilities. As we look toward the future, I encourage everyone to keep pursuing innovation within their Rails projects.
00:14:10.640 I appreciate your attention today. Let’s continue exploring these advancements together, and remember that we are always looking for talented developers interested in furthering this exciting realm of technology.
00:14:22.440 Thank you once again for your time!