I am rounding out my first couple weeks as a new employee at Wealthfront and at this point have full confidence that I chose the right opportunity for my first full time position after graduation. Aside from product, overall engineering mindset and culture were my top priorities and Wealthfront has exceeded my expectations on both fronts.
While this is my first full time position, after seven internships at different tech companies I am no stranger to the ramp up process and gaining familiarity with a code base. I have been delighted by just how easy it is to find where code lives as a byproduct of the overall system architecture. The system firstly follows a service oriented architecture (SOA) with a logical separation of services that are each hosted on different machines. These services handle logical slices such as trading logic, reporting, or serving the front end. Each of the services are then broken down into queries that encase a segmented logical action. Examples include, sending a password reset email, creating a trade request, or processing a deposit. There is no monolithic app, no complex all-in-one functions, and essentially no hassle.
I would certainly not claim an intimate understanding of all of the systems, but in a matter of a few days I gained a level of comfort to navigate the code and figure out just where changes should go. The code also remains comparably clean as work is broken into relatively small slices and thus monolithic complex blocks cannot develop over time. I am able to look at a bug or feature request and quickly decipher where exactly changes need to be made by working down the logical tree of code housing. Along with that, the small segments mean that examples of similar code are easy to find and use as a template for the changes I will be making.
Identifying where code lives is great on its own, but the ability to make changes to a system I haven’t worked in before without breaking existing logic is the immediate (and likely more important) next concern. My very first change (if you would classify something so small as such) was to add my name to a list of authors in the backend system. This was a trivial enough process of adding myself to an enum so you could imagine my surprise when the build came back red after my commit. My immediate thoughts were that my environment wasn’t configured properly or that I had run across a flaky test, but the build was operating correctly. The reason it had come back with failures was that I had not updated the test checking for the number of current authors and it was now failing when it came across the new unexpected entry. It was at this point I gained a full understanding of everything I had been hearing about Wealthfront’s commitment to test coverage.
Moving on to my first real projects this extensive test coverage has come as a blessing. In one of my early projects I had to move the entirety of our email service over to a new sender I had created for upgrades. That is to say every single email and response was going through my new logic and at no point in time did I have anything but utter confidence that everything was going to work simply because the tests told me that it was. If I broke something it came out in development cycles rather than code review or deployment. This means I can focus on building and testing the new logic I am working on rather than checking and rechecking that I didn’t miss some caveat in a function call I am using.
Once the changes have been made, tested, reviewed, and shipped the daunting moment of deploying your first production code comes into play. This process normally involves testing code in a staging environment, determining what machines need the changes, removing those machines from the pool, performing the release, and then continually refreshing logs to make sure you didn’t just blow up everything. If the theme isn’t already becoming clear I’ll add a spoiler that this turned out to be as equally stress free as the previous steps. Below is an image of the continuous deployment manager we use here at Wealthfront.
In order to deploy a service you need to confirm that the automatic build upon merge is successful and then click on the shield next to the service you want to release. That’s it. If something does go wrong and error rates spike the deploy will automatically rollback and your code is removed from production. As with seemingly everything here the tool does what it is supposed to and does it very well.
Ramp up has been overall fairly painless and it is exciting to be shipping so much code in such a short period of time. Clearly there is always more to learn and I am excited to continue diving in to build a truly awesome product.