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!