GA Apprenticeship: Week One
Week one down — eleven more to go! This week has been a bit of a whirlwind, but super exciting. Wrapping my head around all of GA’s existing and upcoming products and code base has been daunting, but I’ve been able to jump into a handful of projects by pair programming with Tim Dussinger and Dustin Coates, two former apprentices. I’ve learned so much already, and I’ve broken it all down into four major areas:
1) Testing: One of my main goals during this apprenticeship was to learn TDD, and I’ve gotten a great start this week writing tests during pair programming. I had previously held off from getting started with tests until this point because I hadn’t known what to test for, but now I’m starting to get the hang of it. Basically a test should do 4 things: (1) Set up the data needed for the test, often from a pre-created “Fixture”; (2) Perform the action that triggers the behavior being tested; (3) Perform one or more “assertions” to prove that the behavior triggered in the previous step had the desired results; (4) Tear down any data structures that need to be removed before the next tests are run (although this is often done for us in Rails). Tests are usually broken into a couple categories: functional, for controllers; unit, for models; integration and performance test, which are evidently not used often; and cukes, for acceptance tests, powered by Cucumber. Speaking of which, Cucumber, Factory Girl, RSpec, and Capybara are all gems for testing that I’m going to learn more about; I’ll write a more in-depth post about them later on.
2) Git/Deployment: For the past 6 months since I’ve known what Git is, it’s been a bit of a magical, nebulous question mark in my mind. I know what it is and how it’s used, but not really how it works beyond basic commits on a single machine. Also I had no idea how it worked in practice with a team of developers. I read a great article about Git Flow, which is a paradigm for dev teams to manage software development. The basic premise is that a software code is distributed into a handful of different folders that are like separate branches, including master, develop, feature branches, release branches, and hotfixes. The master branch is where live, production code is stored. Changes are never made to this master branch; instead, code is forked off from this branch into the develop branch. Anytime a new feature needs to be created, a new feature branch is forked off of the develop branch. You are then free to work on these feature branches without any worry that your changes will conflict with other changes that might be happening at the same time. Once the feature is complete, you can fetch and merge the develop branch again into this feature branch, in order to resolve any discrepancies before you merge back into the main branch. Then you initiate a pull request, which asks someone in charge of the develop branch to integrate your feature back into the develop branch. This can happen as many times as there are new features for a given release, then the code is pushed to a release branch, where final testing is done. When it’s deemed complete, the release is deployed to the master branch.
3) Rails Stack Infrastructure: Derek explained to me how a Rails stack (or at least our Rails stack) works. Because we have multiple servers through AWS (Amazon Web Services), there needs to a be a mechanism that spreads out requests among the servers, so that a single server does not get overloaded. Here’s how this works: DNS routes a request to something called a “load balancer,” which is responsible for doing exactly what it says — balancing the load of requests amongst a distributed networks of servers. From here, the request is sent to an Amazon EC2 (Elastic Compute Cloud) box, which is a virtual machine running our software, and intercepted by Nginx, an open source web server/reverse proxy server for HTTP, IMAP, SMTP, and POP3 protocols, (replacing Apache). Nginx determines whether it can render up a static file or whether it needs to send the request to Unicorn (a Ruby gem), which allows a Rails server to run multiple processes (i.e. requests) at the same time. Unicorn allocates space on the CPU, so that the maximum number of processes can be run on a single CPU, determined by how much memory the CPU has. Once the request is handled, it is send back to client.
4) Coding Tools: One of the great things about working with REAL LIFE DEVS has been observing their native environments — their coding environments, that is. Here are some of the cool tricks I’ve learned in the past week. First, I learned about installing packages for Sublime Text, including Git, GitGutter, SidebarEnhancements, Emmet, Plain Tasks, and others that enhance the text editor experience. You do this by opening the Command Palette (CMD + SHIFT + P) and then Install Packages, and then searching for whatever package you want to install. Pry is another great gem I learned about — it lets you insert “binding.pry” at any point in your code, and when you run that code, it creates a break point, and will automatically open up the console so that you can test what data exists at any point in the execution of your code. This is like what I was doing with RubyMine, but without a clunky IDE. Another thing I want to do is upgrade from Terminal to iTerm because you can customize it with zShell, but I haven’t figured out how to do that just yet.
More to come soon…