Talks
Can Time-Travel Keep You From Blowing Up The Enterprise?

Can Time-Travel Keep You From Blowing Up The Enterprise?

by David Copeland

In the video titled "Can Time-Travel Keep You From Blowing Up The Enterprise?" presented by David Copeland at RailsConf 2016, the focus is on scaling applications built on the Rails framework while avoiding common pitfalls that lead to project failure. Rather than emphasizing performance enhancements or server capabilities, Copeland delves into how to manage the complexities of scaling a codebase and a development team as project demands evolve.

Key points discussed include:

- The Scaling Dilemma: Many believe the answer to scaling applications lies in choosing between monolithic architecture and microservices. Copeland argues this is a false dichotomy, emphasizing that understanding how to avoid failures is crucial.

- Star Trek Analogy: He uses an analogy from the Star Trek: The Next Generation episode 'Cause and Effect' to illustrate how teams face repetitive challenges in scaling. Much like how the crew learns to avoid disaster, teams must learn from their iterative experiences.

- Common Failure Modes: Copeland highlights several issues that can arise, such as having more developers than the original team which leads to different opinions and complicates simpler tasks, thereby lowering team morale.

- The Monolith vs. Microservices: While the monolithic structure may initially promote rapid feature development, it becomes increasingly complicated as the team grows, leading to hidden dependencies that cause unforeseen issues.

- Managing Complexity: When undergoing change, decisions that initially seem advantageous can evolve into complications. For example, adding new requirements can create unnecessary complexity as competing teams vie for resources.

- Adapting Architecture: The necessity of understanding the architecture and ensuring it can evolve without falling into disarray is underscored. Teams should work towards a functional structure that can adapt to new demands without overcomplicating code.

- Key Takeaways: Copeland concludes with advice for developers: observe the signals of the future, embrace adaptability, and write maintainable code that allows for transformation. The importance of the "rule of three" is discussed as a method for recognizing patterns that promote architectural evolution.

Overall, the video serves as a guide for teams to navigate the challenges of scaling Rails applications thoughtfully, ensuring they learn from their experiences rather than repeating mistakes as they grow.

00:00:09.769 Alright, thank you all for coming. Can time travel keep you from blowing up the Enterprise? Hopefully, you read the abstract to this talk and know that we're going to be talking about scaling Rails.
00:00:15.450 However, we're not going to talk about making Rails do stuff faster or enabling it to handle more tasks at once, as you can simply throw hardware at that problem. Instead, we will focus on scaling a code base or a team using Rails. As we scale, we will discuss the problems we encounter in the context of growing teams and evolving projects.
00:00:30.600 Many people believe that the answer to scaling is either monolithic architecture or microservices. While we will discuss these options, I want to emphasize that this is a false dichotomy, and that's not the direction we need to take. To explore this further, we'll use a framing device based on the Star Trek: The Next Generation episode titled 'Cause and Effect.' Has anyone seen this episode? If you haven't or if you dislike Star Trek, that’s okay; I'll summarize it for you.
00:00:43.920 In this episode, the Enterprise is cruising through space looking for trouble when they encounter a spatial anomaly. As they investigate, they find themselves on a collision course with another ship. Despite their efforts, the Enterprise is unable to avoid a crash, leading to its destruction. However, when we come back from the commercial break, everything resets, and the crew lives the same day over and over again, eventually discovering ways to communicate information to avoid disaster.
00:01:03.750 Similarly, we will examine how a growing team can experience the normal challenges of scaling and make decisions that lead to the metaphorical 'blowing up' of their enterprise. The team will repeatedly face situations, learn from each iteration, and explore how to avoid these catastrophic failures. A few assumptions for our exploration include: more people will be involved in the project than just the original developers. Hence, different levels of experience and opinions about coding will emerge. Additionally, there will be increasing demands placed on the codebase. Teams will make decisions based on the assumption that certain principles are unchangeable, and when those assumptions shift, the consequences must be dealt with. These scenarios reflect common failure modes in tech projects.
00:02:33.000 For example, failure occurs when products don't meet user needs; software must serve a purpose to be considered successful. Often, simple changes become increasingly difficult to implement, leading to low morale among developers. No one enjoys working on a project that feels destined for failure, which can lead talented individuals to leave. I believe these concerns and assumptions are reasonable and applicable to many of us working in tech.
00:04:32.240 I currently work in a startup that embodies this trajectory of growth and change. My experience working on long-term projects for various organizations, including the US Marshal Service, reflects similar challenges. All projects face a common trajectory of encountering hurdles due to growth and scale. Our team has been assembled to tackle a new project, and we'll be using Rails because it simplifies many processes. Rails encourages developers to integrate everything within the app, but this monolithic structure can become unwieldy as the team expands.
00:06:24.420 In the early stages, core developers can quickly produce features with little friction. However, as more developers join the team, opinions on implementing certain functions may vary, potentially complicating matters. When teams grow, they need to work on parallel projects without overlapping their decisions. This creates hidden dependencies within the monolithic app structure, making simple changes prone to causing unexpected issues in unrelated areas.
00:07:00.620 For instance, if a team modifies the CSS for one part of the application, it may inadvertently cause problems elsewhere due to the tightly-knit nature of the codebase. As teams try to optimize performance or implement new features, the interconnectedness of code can lead to cascading failures. Codebase complexity can result in business logic becoming inextricably linked with Rails-specific practices, leading to convoluted statements that are challenging to maintain and comprehend, further complicating development.
00:09:16.000 Additionally, decisions that seem beneficial at first can quickly morph into issues. For example, if a team decides to run code after user creation, other teams may decide to layer on new requirements, leading to unnecessary complexity as different teams compete for resources and disagree on solutions. All these issues contribute to low morale among developers who feel hindered by the convoluted codebase. Ultimately, this leads to failure as the project becomes too difficult for anyone to maintain or modify.
00:10:39.000 Our team will find themselves starting over, feeling the pain of what they created. They realize they must decouple and clean up the code, aiming for a structure that allows for necessary changes without complete upheaval. Through trial and error, they experiment with various architectures – exploring microservices to avoid issues arising from a monolith – but without a clear strategy, they may find themselves in a similar situation.
00:12:54.310 Before diving into microservices, the team will need to establish groundwork to manage their architecture effectively. They’ll need to identify which services are crucial to their work and how different components will communicate with one another. Discussions on structuring their code and integration will take place as they try to anticipate future demands.
00:15:01.390 Over time, the team is likely to develop an impressive microservices architecture, using various technologies and apps to enhance their capability. However, this increases complexity and produces numerous moving parts within their system. With every decision, they must ensure that they don’t end up repeating the same old mistakes and complicating the architecture without yielding any tangible improvements.
00:18:12.670 Ultimately, the goal is to ensure the architecture evolves rather than seeking a static, predetermined structure. The team learns that they must allow their architecture to shift with the needs of their business and that adaptability is crucial. They establish guidelines and patterns they can follow to ensure continued progress toward a functional, effective architecture without being mired by complexity.
00:20:14.740 In conclusion, we learn a few key points: don't ignore the signals of the future; adapt to change without backpedaling; and write code that facilitates transformation rather than imposing rigid structures. The rule of three can be an effective technique for recognizing patterns, ultimately allowing your architecture to evolve. Avoid creating messes in your codebase, as maintaining order within complexity will lead to positive outcomes.
00:22:08.000 If what I’ve described resonates with you, feel free to reach out to me to explore opportunities within our architecture. I also have books available, both for purchase and for free if you ask insightful questions. Thank you for your attention.