March 10, 2017

Growing Up Node: Lessons for Successful Platform Migration


Trevor Livingston
Trevor Livingston, principal architect at HomeAway, offers insight on how to introduce Node into companies at Node.js Interactive.

Switching from one technology to another is always going to be hard, and, despite the popularity of Node.js, it does come with its own set of complexities, and the advantages are not always apparent to management, says Trevor Livingston, principal architect at HomeAway, speaking at Node.js Interactive.

Livingston’s previous work at Paypal gives him a unique insight into how to introduce Node into companies. PayPal started out using C++ and later Java, before introducing Node. Livingston was recruited to help introduce Node and was the Node Platform Lead at PayPal, while at the same time part of the KrakenJS team. Toward the end of his tenure at PayPal, the company employed 800 Node developers, maintained 100 applications, and 1500 internal modules. The Node framework served over 400 million requests per day. All in all, quite a successful move.

But how do you get there? Livingston admits there is no magic recipe. At PayPal, the team learned as they went and counted on a lot of help, not only from a receptive management but also from the Node community. Livingston recommends leveraging the community, noting that problems you encounter have probably been encountered by others before you.

Apart from support, you are going to need a plan. The first thing you have to take into account is that re-platforming comes at a cost no matter what. Figuring out if the benefits outweigh that cost -- that is, finding the true reason you are shifting to Node -- is crucial to get started on the right foot. Livingston says it is fundamental to understand what kind of problems you are setting out to solve. It could be you want to increase productivity, allowing your developers to iterate faster; or you may be looking to scale more cheaply. Understanding the problem and aligning your goals to those of the business not only helps you plan better but also makes it easier to explain the aim of the migration to those financing the project.

Once you have a plan, Livingston recommends demonstrating success. Even small successes, such as a single application that improves the overall user experience, can help pave the way for the rest of the platform shift. Using what Livingston describes as "Build. Measure. Learn." approach, when you deploy a small application, you need to monitor how it works, including users into the process, and draw conclusions to improve the application in the next iteration.

Livingston also warns against several anti-patterns -- the first of which is entering the "Migration" mindset. Thinking in terms of "how to translate a Java class into a JavaScript class," for example, is the wrong way to go about things, because you end up with Java, or C, or what have you, but just written with a JavaScript syntax. Instead, Livingston suggests "creating isolation and building new," by breaking down tasks into small pieces and implementing each piece from the ground up using the new platform.

The next challenge is moving your project from one team to all the teams. Being consistent, says Livingston, will help with that. Despite being a fan of "wild west" development, Livingston says constraints are necessary to create reproducible success. The consistency will come from the design choices you make, making your project more configuration-based, using pre-existing frameworks. Another important factor is education. You need to ensure that engineers are trained from the outset and then mentor them. Engagement is the third element to bring teams together. To encourage engagement, Livingston recommends developing in the open, sharing code, landmarks and successes with other teams.

Beware Turn-Key Solutions

The anti-pattern to the above is turn-key solutions. There will be the temptation of wrapping everything up in a box and tying everybody to that. Doing so, however, traps you in an ecosystem that stifles innovation. Being consistent is about capabilities, not rails, says Livingston. Capabilities allow teams to move to new technologies as they become available -- not so if you are married to rigid framework.

Moving along from development to deployment, when the code is put into production, when people start using what has been built, things start to get really interesting. How do you account for performance problems or Node crashing? The first thing to look at is security. Security is the number one concern for a business, so it should be the number one concern for the developers. As npm is pretty open as to what modules get uploaded to the service, you should take into account security advisories. There are several tools for this, such as nsp and Snyk.

Performance is another area of concern. To monitor performance of your application in the real world, Livingston recommends becoming familiar with APM (application performance management) tools, such as New Relic and AppDynamics, and incorporating performance monitoring as a matter of course when testing.

The final "sticky problem" Livingston mentions is availability. Node, for all intents and purposes, is single process, and when you have uncaught exceptions, the process crashes. When the process crashes while handling a request, it will hang for the user and the state of the program becomes unknown. This requires you becomes familiar with how frameworks handle errors. However, in Livingston's experience, 99 percent of all crashes are caused by developers ignoring errors in callbacks.

The anti-pattern here is being single-minded about your approach. Unfortunately, Node is not a silver bullet that will solve all your developmental and deployment problems, and Livingston suggests a holistic approach to problem solving.

Down the line, the decisions you make today regarding design choices are going to affect you tomorrow. Livingston warns against using pure dependencies, for example, because it makes migration much harder in the future. You must also be wary of globals. He also advises against making assumptions about your upstream. If you have something like an Express middleware, and you have expectations on the upstreams, you no longer have decoupled software. As for Local Continuation Storage, for Livingston, this is definitely a no-no. He describes it as "magic" of the blackest kind.

Moving on from design choices, Livingston recommends considering ownership carefully. You must think of who is going to maintain each piece of code in the future. The same goes for support: you should focus on self-sufficiency. That said, the anti-pattern for this is hand holding, because people learn through failing. It is a good idea to establish early on that it is okay to fail and that failure is valuable educational tool.

One last thing that can help you succeed in moving your platform over to Node is being transparent with management, especially with regard to inner source. Inner source is the concept of sharing code across teams and contributing code that other teams' can use.

Management may not understand why a developer is not on the task they have been assigned 100 percent of the time. However, a developer may be improving the productivity of another team in a substantial way, and other teams may help in turn the developer's original team with their own issues. The idea is that a certain degree of inner source can help improve the productivity across the board. This concept, which is obvious in open source circles, must often be explained to the management.

For more details, watch the complete presentation below:

If you're interested in speaking at or attending Node.js Interactive North America 2017 - happening October 4-6 in Vancouver, Canada - please subscribe to the Node.js community newsletter to keep abreast of dates and deadlines.

Click Here!