Month: October 2018
Having attended several meetups and conferences, I have heard of the term “linter” used. I wasn’t sure what it was and was surprised that I had not used it before. But actually, I have but didn’t know that it was a linter.“A linter or lint refers to tools that analyze source code to flag programming errors, bugs, stylistic errors, and suspicious constructs” (A) In CS50, an Introduction to Computer Science, we used a program called “style50”, that would look for stylistic errors. Wow I was already using a linter and didn’t even know it.
How it works is when you pass code to a linter it will scan the code and give messages. The return messages could be syntax errors, structural problems like the use of undefined variables, or best practice or code style guideline violations. Whats great about is is that we can get immediate feedback on bugs that might only show their head in a specific instance, and that isn’t something we would want to release into production!
“The term “lint” was derived from the name of the undesirable bits of fiber and fluff found in sheep’s wool.”(B) Stephen Johnson created the first lint program out of need to check his own code. In my mind, I kind of compare it to the tests that we create today. The linter is a large generic test framework rather than the small tests that we write for specific apps today, but the concept is the same. Here is a quote from Stephen:
I originally wrote lint to help me debug the YACC grammar I was writing for C. I had the grammar written, but no way to test it! I could run it on the body of C code that existed, but I had no way of telling whether I had correctly “understood” the programs. So I hit on the idea of checking the consistency between function calls and definitions – Stephen Johnson (C)
What is CI/CD?
CI/CD stands for Continuous integration and continuous delivery. It is a set of principles that development teams use to build, test, and release code. A lot of companies will have this as part of their software lifecycle, so it is definitely something new developers should at least be familiar with in theory, if not practice.
“The technical goal of CI is to establish a consistent and automated way to build, package, and test applications” [A]. With consistency in the integration process in place, teams are more likely to commit code changes more frequently,
“Continuous integration is the practice of routinely integrating code changes into the main branch of a repository, and testing the changes, as early and often as possible”[B]. Waiting for changes to be uploaded can cause conflicts between builds, and finding a bug after several days of coding can lead to lost work. It’s a financially secure decision to bring and test changes earlier then let branches linger and diverge. If two developers need a function to do a certain task, and Dev1 made and tested that several days ago, while Dev2 needs that function also, Dev2 could possibly end up writing similar code that during merge time, may be discarded. Or the alternate scenario, Dev2 merge their changes but Dev1 has other functions that needed their version of the function now Dev1 needs to go back and change their subfunctions.
automates the delivery of applications to selected infrastructure environments. Most teams work with multiple environments other than the production, such as development and testing environments, and CD ensures there is an automated way to push code changes to them. CD automation then performs any necessary service calls to web servers, databases, and other services that may need to be restarted or follow other procedures when applications are deployed.
Continuous delivery is the practice “where code changes are automatically built, tested, and prepared for a release to production”[C]. It follows CI by “deploying all code changes to a testing environment and/or a production environment after the build stage”. By testing the changes before deployment, downtime in a production environment can be minimized. Also by continuously delivering changes, if any errors were passed onto production, only a minimal amount of changes can potentially be rolled back upon, since errors should rear themselves up earlier.
Continuous Delivery vs. Continuous Deployment
Why Continuous Delivery and not Continuous Deployment? “The difference between continuous delivery and continuous deployment is the presence of a manual approval to update to production. With continuous deployment, production happens automatically without explicit approval.”[E] Continuous Deployment might make sense in an environment, say Netflix or Youtube, where a small piece of downtime while troublesome, will not cause problems with the customer base. Continuous Delivery with manual checking could make more sense in a scenarios where customers are more fickle, say Amazon, where a person who would want a Garlic press right now, if unable to purchase would come to their sense and say, I would never actually use that. With Continuous Delivery, if there were a scenario that tests did not account for, it is possible manual approval might think of a new test that would catch that error.
Recently the new hot buzzword seems to be “serverless”. There is a meetup group called “Serverless NYC”, and there have been a few “Serverless” conferences. Lambda is the new tool from Amazon that gets thrown around by developers at every meetup. But what are we talking about exactly? Just to be clear, even though the name is serverless, when you eventually get to the bottom of the tootsie roll pop, there is a server there. It’s just about who controls it.
The people who are using the services provided are still running their work on someone’s server.”With a serverless architecture, you focus purely on the individual functions in your application code. Services take care of all the physical hardware, virtual machine operating system, and web server software management.” This allows the developer to focus on being a developer, and not necessarily require the extra skillset of knowing, Linux, networking, and infrastructure. Since the focus here are functions, it should probably be some smaller project, or something that can be independent of the scope of a larger project.
The benefits of a serverless architecture is no need to deploy or administer any servers, install software, or run updates. That is handled by your provider. If you need more compute you can just purchase more consumption rather than build and deploy new servers, even if just virtual machines. You don’t need to architect for availability and fault tolerance since that too is built into the architecture you are buying. Availability would refer to your service being up, while Fault Tolerance would refer to withstanding the failure of a sever.
With every upside there is a downside. Some of the downsides of serverless computing are: 1) multitenancy problems, which means that if the provider over provisions their resources and available compute is limited, it will affect your services. 2)vendor lock-in: if you design your services around the capabilities and api’s of provider A, then it makes it much harder to move to provider B. 3) security concerns – you don’t really know the status of the security of your host. You trust your provider, but for those with the need for absolute control or some regulations, they need to make sure the solution is viable for their needs.
While there are some downsides, there are many potential upsides. Serverless is here to stay and should be weighted as a viable solution for any deployment.
When I first looked up Passenger, a Gumdam-like robot icon appears. From the site itself, “Battle-hardened by some of the most demanding web apps for over a decade, Passenger is considered one of the most performant, secure and mature app servers currently available.” (1)
OK so what is it? Passenger is an open source web application server which handles HTTP requests, manages processes and resources, and enables administration, monitoring and problem diagnosis. But then question is, if I type “Rails S” why would I need passenger? Passenger doesn’t replace “rails server” in the sense of it being a test platform only. What “rails server” does is it uses an application server – such as Passenger – directly to server ruby files.
The default web application server activated when you use “rails server” is Puma. Looking at the Gemfile, you can see “gem ‘puma’, ‘~> 3.7’”. I think this is a great thing to realize, a lot of new Rails developers need to not only know about how to write code in Ruby and Rails, but also about the ecosystem that runs a web application, instead if using Heroku as a crutch. Standing up a server on a standalone box can be a great learning experience. With Linux you would use Nginx/Apache to host pages, as they are web servers. They provide the HTTP transaction handling and serve static files. However, they are not Ruby application servers and don’t run the Ruby applications by themselves directly. Nginx and Apache are used with an application server, such as Puma or Passenger. What application servers do is make it possible for Ruby apps to speak HTTP. Ruby apps (and frameworks like Rails) can’t do that by themselves. So we need the application servers so the ruby apps can talk to http. But application servers aren’t as good as Nginx and Apache at handling HTTP requests because Nginx and Apache are better at handling I/O security, HTTP concurrency management, connection timeouts, etc. This is why a good Rails Engineer will still need to know about Linux, Apache, and Nginx.
Why choose Passenger over Puma? Passenger’s strength is that is also can host Python, Node.js, and Meteor apps as well. Passenger is the best choice when you have apps developed in several languages that Passenger supports and you want to consolidate your app server stack. Puma’s strength is that it’s easy to configure and mostly “just works” out-of-the-box. I think that after getting familiar with what Puma does, its better to look at Passenger for growth cases