00:00:19.260
I would like to start with a question: how many of you have used a platform to make a donation? One, two, three... I don't see very well how many of you tipped. Fewer hands. How many of you tipped $10 or more? I want to see those hands higher. Who has the highest tip?
00:00:40.650
At some point, you tipped $5. You're the winner! I did this at our local Boston Ruby meeting, and someone donated $100. Our app had its birthday after I sent the proposal, which is why I marked the date as the 14th. My name is Braulio, but you can call me Brad if that's easier. I have been with ActBlue for six years. I didn't know ActBlue was an early adopter until I prepared this presentation.
00:01:10.860
I'm originally from Chile, in case you're curious about my accent. For those who don't know, ActBlue provides a platform that empowers people to fundraise for political candidates and campaigns. We all know we need money to win elections, but you shouldn't have to rely on the wealthy. Founded in 2004 as a nonprofit, ActBlue is independent of political organizations like the DCCC.
00:01:40.470
We help nonprofits as well. Today, all Democratic candidates for president are using ActBlue to fundraise. In fact, there is a new rule stating that to qualify for the debates, a candidate can either have 1% in three national polls or can fundraise with 65,000 unique donors.
00:02:06.660
Now, how does the contribution form look? Here’s an example featuring a nonprofit that saves animals facing extinction. Since I donated, my name is on it, and they also have my card number. It's as easy as clicking one of the red buttons, and the donation will be made. If you're a first-time visitor, you'll need to provide more information such as your name, address, and credit card number. But the concept remains the same.
00:02:31.599
ActBlue is not just about processing payments; we also help with compliance. We have a team of lawyers who handle filings with the Federal Election Commission and state and local agencies, ensuring that the person fundraising doesn't have to worry about anything. We provide tools and A/B tests to maximize the conversion rates of the forms. Statistics and reports for their campaigns are also available, and we send notifications when a contribution is made.
00:03:05.620
In the last election cycle, we processed 41 million contributions amounting to $1.6 billion, with an average contribution of $39. We helped 50,000 organizations in the last two years. Looking at the lifetime volume since the beginning, the total contributions have reached billions. It took us 12 years to raise the first billion, 2 years for the second, and just one year for the third. I also noted when I joined ActBlue in this graph, so you can see when things really picked up.
00:04:23.849
Our application is called Indigo. All the logos look the same to me, which is why I had to put the hex code for clarity. This is a piece of archaeology: the first commit in Rails! I want to prove this statement; at the bottom is the version of Rails 0.10 from 2005. You need to realize that 14 years is a long time. I bet some of you were programming in Java or .NET, and some of you might not have been programming at all. I see some young people, maybe you were in high school.
00:05:16.820
The author of this commit is Matt DeBergalis, one of the founders along with Benjamin Thomas. So, why did Matt make the first commit? We create software to address business needs. In our case, we're a nonprofit, so we refer to ourselves as an organization. However, in most cases, it will be a business. But the business landscape is not static; it constantly changes, and we must adapt.
00:06:14.270
The challenge with long-running software is that it becomes increasingly difficult to adapt due to the growing complexity and larger codebase. Therefore, our goal in this presentation is to explore how we can navigate these changes efficiently and with low costs while maintaining reliability, ensuring donations keep coming, and ensuring the security of sensitive information, like credit card data.
00:06:47.700
I have two examples related to this. Recently, we had to implement Apple Pay. We were able to do this quickly because we leveraged existing code we had for processing credit card transactions. While the two are different, the existing code was good enough for adaptation. This allowed us to keep up with our improvement schedule.
00:07:10.949
Another example is preparing for upcoming elections. We know that traffic will surge, so we need to manage it effectively. The challenges associated with long-running applications can be categorized into two groups: issues that arise from aging code and issues that arise from an increasing codebase. These challenges are not unique to Rails; they are common across all software projects.
00:08:01.360
I want to share some lessons learned from dealing with these challenges, specifically regarding technical debt. Technical debt occurs when we choose an easier solution instead of a more effective approach that would take longer to implement. If this becomes a pattern in a long-running project, it results in a significant amount of technical debt, which can create major problems.
00:08:49.930
Our approach is to treat technical debt as a feature. However, this doesn't mean that we ignore the ugly parts of the code. Addressing technical debt involves making a case for its resolution, explaining the benefits such as improved maintainability and ability to adapt to changes. This requires discussions with the rest of the organization since everyone has their priorities.
00:09:19.830
We establish both short-term and long-term plans for addressing technical debt during quieter periods, like December after elections or at the end of a quarter. I have two small stories that highlight our experience with this. One involved implementing Apple Pay, where I saw code that had complicated structures, and yet we haven’t modified it in six years because there simply hasn't been a need. The complexity of that code hasn't justified the effort.
00:10:14.520
In another case, we introduced a feature for recurring contributions based on a suggestion. Initially, we doubted its usefulness, thinking nobody would utilize it. We implemented it anyway, and it turned out to be highly popular. Later, when we added a weekly contribution option, we were skeptical again but were once again proven wrong. Thus, today, the recurring contributions feature plays a crucial role, processing about 30,000 contributions every day.
00:11:12.400
In summary, addressing technical debt should be treated as a feature rather than a problem. The distinction between technical debt being a feature was not always clear, but we’ve learned through experience.
00:11:51.600
Next, let's address obsolescence, which is not just about aging code but also includes outdated versions of gems and frameworks that are no longer maintained. The challenge is that vulnerabilities are discovered frequently, and if you don't apply patches for years, you risk exposing the application to serious issues. I understand that some might still be running Rails 3.2, and it’s crucial to stay updated.
00:12:46.200
To mitigate this, you need a robust test suite. It's imperative to have good tests when considering upgrades; skipping minor version updates can lead to major complications. The Rails guides offer excellent information, so it's essential to read them, particularly regarding version upgrades.
00:13:54.700
The Rails guides provide clear instructions for upgrading from one version to another. Engage with the release notes, as they contain critical information that might directly affect your application. Once the tests pass, it's equally important to fix any deprecation warnings, since they might not always appear on standard output.
00:14:49.780
If a new feature has been introduced into a release that resembles functionality from a gem, it is advisable to drop the gem and use the native feature. Transitioning existing features before the actual upgrade is beneficial since it minimizes issues during the upgrade process.
00:15:40.880
Be proactive in forking and fixing any gems that are no longer maintained, contributing those fixes back to the open-source community. In our experience with Ruby and Rails, upgrading the gems has presented more challenges than upgrading the frameworks, with the notable exception of transitioning from Ruby 1.8.7 to 1.9.
00:16:27.850
There are workshops dedicated to upgrading Rails; I recommend attending if you haven't done an upgrade yet. Over the years, our codebase has grown significantly, currently boasting 35,000 commits, 110,000 lines of source code, and a range of classes and modules.
00:17:11.420
Working on legacy code can be intimidating. I always say that in software development, you learn to write before you learn to read. This mentality can lead to people gravitating towards new applications rather than legacy ones. When I joined ActBlue, I encountered an application that was old but not a mess.
00:18:09.560
To maintain a healthy code base, good commit messages are vital. There are many resources online dedicated to this. I recommend finding and following best practices for writing commit messages to ensure clarity and inform future developers.
00:19:18.620
While having no comments in code can be damaging, excessive comments can also lead to confusion. It’s helpful to document complex algorithms or logic to make it easier for others who will come after you. Additionally, maintaining documentation for the data model can assist developers in understanding the project's logic.
00:20:04.020
As our team grew from just two founders to 120 people, including 34 in technical roles, communication became a significant challenge. As the team expanded, effective coordination became crucial.
00:20:59.140
To facilitate smoother communication, hiring top developers is key. While they may be more expensive, higher quality talent significantly enhances productivity. Ensuring developers feel empowered through autonomy and purpose also fosters a positive culture that encourages retention.
00:21:57.850
We conduct code reviews for all pull requests, ensuring at least one person reviews it, and for more complex changes, at least two developers. Discussions during the pull request process can lead to deeper clarity.
00:22:32.170
Regarding our code reviews, even senior developers are not exempt from having mentors, ensuring knowledge transfer within the team. Let me illustrate a point about managing complexity. I shared an example from 2015 regarding a contribution form for a nonprofit.
00:23:44.420
After a user completed a contribution form, if they abandoned the browser, the contribution would not be saved. This led to the realization that we needed to improve the form's functionality.
00:24:19.670
We decided to structure a new application to handle these processes more effectively. This new 'Form App,' built with React, allowed us to optimize the user experience significantly.
00:25:45.510
Building the Form App not only enhanced functionality but allowed us to minimize the problematic hand code in our JavaScript, resulting in more maintainable code.
00:26:40.890
In recent years, we've experienced surges in traffic during high-stakes political moments. Let me illustrate this with some examples.
00:27:26.830
The first spike was during a session in Congress in 2009 when President Obama spoke about the Affordable Care Act. The second spike occurred later that same day due to news coverage, while another large spike followed the next day.
00:28:35.900
In 2016, another event occurred when Bernie Sanders delivered a victory speech and urged supporters to contribute online. At one point, we registered over 2,650 contributions per minute.
00:29:10.520
Each surge represents valuable lessons regarding how we handle spikes in traffic. Analyzing our responsiveness to load revealed processes that coped efficiently and others that didn’t.
00:30:31.720
These spikes serve as timely reminders of the importance of preparation during key moments of increased activity to ensure that we reliably serve our contributors.
00:31:49.170
Scalability can often hinge on architectural decisions, like how many servers we have or how powerful they are. Ensuring the code can operate in parallel is essential to successfully managing a load increase.
00:32:22.880
Emphasizing asynchronous job processing, we queue slow actions, like sending emails, rather than involving the web server directly. Utilizing caching along with a Content Delivery Network (CDN) has proven beneficial as it ensures requests from different regions are handled efficiently.
00:33:09.020
Choosing the right framework and language greatly simplifies the management of legacy software. We are thankful for Ruby on Rails and the supportive community behind it.
00:34:00.330
Remember to read the commit message guidelines. They have significant value!
00:34:24.490
We have two minutes for questions. Is there anyone?
00:34:40.610
Okay, so the question is why we decided to use React instead of Angular. I wish I could answer that, but it wasn't my call. The backend is Indigo, our monolith handling contributions and processing. The main thing with scaling is preparing for momentous traffic spikes when you have prior knowledge