Further Questions

I’m finally sitting down and trying to look into the questions that built up from the past week

  • Why adding the ruby gem foreman into the Gemfile is not recommended?

    This ruby gem is used for organizing apps with multiple components and uses a Procfile. The Procfile lists which processes foreman is suppose to manage. Heroku has an article that provides further details on Procfiles and the github page for foreman also has an extensive manual. What jumped out the most from the foreman manual were the flags for port and concurrency which managed how many workers would be used for each process. From the heroku article , the most basic command in the Procfile was bundle exec rails server -p $PORT but more processes can be added. From what I can find, Heroku didn’t suggest adding foreman into the Gemfile because its already added by default.

  • How does Unicorn interact with Rack Applications ?

    I found an article that clarified the features that Unicorn has. There was also another article on how they can be configured at Digitial Ocean. Both articles wrote about the advantages of using Unicorn but I didn’t start seeing how it could be implemented until I looked at the guide for the Rails Initialization Process. At the end of the guide, it mentioned that the process would be handed off to the specific server implementaion and that led me to the Unicorn::HttpServer class. I’m not sure how the process goes after it reaches this point, but I’ll read the source code more in detail to find out. I do know from the comments that a server could be run using HttpServer::run. In the future, I want to write a blog post that extends the guide to how Unicorn would handle the last line server.run wrapped_app, options, &blk.

  • What are the major differences between Unicorn, Thin , Puma and other Rack web servers ?

    This article was a great start on figuring out the differences between the servers. The answer produced even more questions though. Specifically on what is NGINX, Mongrel’s parser, Event Machine network I/O library, and the specifics of Rack middleware for HTTP requests.

  • How does concurrency and thread-safe work in a Rails?

    I started looking at stackoverflow to find out what concurrency and thread-safe means. There was also another post on what isn’t thread safe in Ruby. Rails has a specific configuration that is turned on by default and this post went into through an indepth discussion about what that configuration did. The most interesting parts was when he said that “We know that loading the framework isn’t threadsafe, so the strategy is to load it all up before any threads are ready to handle requests” and that the @allow_concurrency option turns off a Rack Middleware called Rack::Lock. Again, this opened up more questions about the difference between multi-threaded servers and multi-process servers along with the difference between eager loading and lazy loading.

      def threadsafe!
          @preload_frameworks = true
          @cache_classes      = true
          @dependency_loading = false
          @allow_concurrency  = true
          self
      end
    
  • How to configure a deployment through environment variables?

    After finding two articles about it from railsapps and tealeaf, the best ways I read to manage environment variables centers around two gems; figaro and dotenv-development. Both use a separate file, .env and application.yml respectively, that can be used to set environment variables and should not added to the public repository.

  • What are the best practices for deploying a Rails application?

    There were many articles about this and I found that the best practices revolve around where you’re deploying to and the specific requirements for your app. A common thread I found was using a tool to standardize the process like capistrano, chef, or puppet.

Even more questions

  • What is NGINX?
  • What is Mongrel’s parser?
  • What is Event Machine network I/O library and how does it work?
  • How does Rack middleware and Rack in general work with Ruby web applications?
  • What is the difference between multi-threaded servers and multi-process servers?
  • What is the difference between eager loading and lazy loading?
  • How could I use capistrano, chef or puppet ?

12 Factor Apps

I was researching the ideas behind the 12 factor app and I learned a lot about deploying an application.

  1. Codebase

    The main idea behind this factor is using a version control system and that one app corresponds to one codebase. Codebases should not share code and if it does, they should be refactored into a shared library that can be included with dependencies.

  2. Dependencies

    Manage dependencies within an app and for a Rails application, this can be done through the Gemfile with locked versions.

  3. Config

    The configuration should be separate from the code and preferrably set in the environment’s variables. For a Rails app, there’s an explicit directory where configurations can be defined but this definition does not include routes or other internal configurations. Does this mean that the configurations in the yaml files should not be stated? This article cleared up some of those things for me. Things like the secret key and database configuration can be managed from the command line or with a config/secrets.yml that’s not added to a repository. I still had more questions about managing secret keys outside of Rails with engines like Devise. I searched more and found answers in one of Devise’s issues page. I still need to do more research into this because it sounds specific to what an app is using.

  4. Backing Services

    These services include the database, messaging and cache systems. The main idea behind this is that each service should be loosely coupled with the app and that would enable a deployment to easily swap them. My only experience with this so far is through database configurations.

  5. Build, Release, Run

    This factor encourages the separation betweem the build, release, and run stages. The build stage occurs during deployment, the release stage combines the build stage with configurations, and the run stage occurs while the environment is proccessing requests. I’m still figuring out the best way to do this for a Rails app. Most of the articles I’ve read used scripts to simplify these stages.

  6. Processes

    Each process should be stateless, share nothing with each other, and persistent data should be stored in a database. Specifically, the state is transfered in requests and not stored in the web server. From my understanding, these states don’t apply to sessions which are stored in clients as cookies. This concept seems to go in line with a REST applications and helps with scaling the application.

  7. Port Binding

    The app should be self-contained and should not depend on runtime execution. It listens to requests and sends data through the port bindings. Along with processes, this one seems to be similar to a REST application and Rails can usually do this for free.

  8. Concurrency

    The application should be thread-safe or support concurrency meaning multiple processes could be added. I’m still struggling with the idea of what kind of code is thread-safe in Rails and how Rails implements concurrency. I’ve read that Rails uses concurrency by making sure that threads don’t share the same data when they’re run or lock them when they do to reduce interference but I don’t know where this happens in the framework.

  9. Disposability

    Apps should have a fast startup and graceful shutdown. The former implies that less data or processes would be needed for the application to start and the latter implies that the app won’t need a specific process every time it shuts down. Both parts make concurrent requests more effective and durable from errors. Specific implementations of this would include blocking a new request if the older one is still going or reconnecting when the connection is lost.

  10. Dev/prod parity

    This involves keeping development and production as similar as possible. This helps with continuous deployment by keeping changes small so they can be pushed to development quickly, having developers work on both stages, and keeping the tools/dependencies as similar as possible. For example, the development side should use the same type of database and the environment could be handled by a virtual machine through vagrant to make sure that everything works on the same machine.

  11. Logs

    Treating logs as an event stream enables them to be stored in a third party service instead of a specific log file. This is useful when the app is deployed to multiple places and all the logs would be handle by one service.

  12. Admin Processes

    Administration processes like migrations should be handled as a one off process and in an identical environment as production. This is usually done through deployment scripts. I’m still learning how to deploy an app effectively so this one is still a work in progress.

Further questions

  • Why adding the ruby gem foreman into the Gemfile is not recommended?
  • How does Unicorn interact with Rack Applications ?
  • What are the major differences between Unicorn, Thin , Puma and other Rack web servers ?
  • How does concurrency and thread-safe work in a Rails?
  • How to configure a deployment through environment variables?
  • What are the best practices for deploying a Rails application?

Deploying to Heroku

I’ve recently deployed an app I was working on to Heroku and the process of matching the development environment to the production environment was very interesting. Heroku itself provided an article to set up a Rails app and an additonal article to set up a unicorn server.

The two specific gems I added to the Gemfile

The rails_12factor gem enables the app to improve on two factors in the 12 factor app; treating logs as an event stream instead of writing them to a single file and serving static assets through Rails instead of a proxy server. This was my first experience with the term twelve factor app and I’m taking the time to learn as much as I can about it before writing any more on the topic.

To use the unicorn gem, I added a file to config/unicorn.rb and I used the basic configuration that heroku provided. The default web server in rails, Webrick, can only handle one request at a time so a different server is needed in production. From my understanding, Unicorn emulates a thread safe app by prioritizing fast requests over slower ones.

The biggest problem I came across was applying the database migrations to the Heroku database. Running heroku run rake db:migrate produced an error and it might have been because I started the app from an older version of Rails. The older migrations could have started conflicting. As a workaround, I switched my development database to Posgresql, ran the migrations on my computer, and pushed the schema through the command heroku pg:push <LOCAL DB> <HEROKU DB>.

Further questions I had

  • What are the practical ramifications of the 12 factors to a web developer ?
  • Why shouldn’t I add the ruby gem foreman into the Gemfile ?
  • How does Unicorn interact with Rack Applications ?
  • What are the major differences between Unicorn, Thin , Puma and other Rack web servers ?

My Favorite Ruby Gem

If I could tell myself one thing when I first started learning about Ruby and Rails, I would say use pry. There are so many tutorials that I stopped halfway through because I couldn’t debug it properly and Pry ended up helping me with most of them. In Rails, I’ve used binding.pry so much that I sometimes leave it as a comment in case I have to go through it again. The only misstep I’ve had while using it is including binding.pry directly into a for or while loop. In that case, each step usually goes through one iteration of the loop and using the finish command does the same thing.

Also, since I’ve started doing coding challenges like exercism and codewars, I’ve used Pry to explore what I can do when solving problems. What I love the most about using it is that I can create a variable with the methods I’m using, cd into it, and use the ls command to view all the methods available. I could then use the ? or show-doc commands to explore what each method can do. While learning how to use methods, I have a hard time figuring out how the object I pass changes and which methods could then be called on it. In my first iteration, I usually group methods by the type of object they become since the most common type of errors I’ve had are ArgumentError and TypeError. As an added benefit, I could try out any code I want to write in the Pry before adding it to my project. That way, I could be sure that a problem exists somewhere other than the code I’m working on.

I was introduced to both of these approaches in Rails Conference videos I’ve seen from YouTube and if either interest you, you can follow the following links below to learn more about it.

Ruby Conf 2013 - REPL driven development with Pry by Conrad Irwin

RailsConf 2014 - Debugger Driven Developement with Pry by Joel Turnbull

Setup in the Beginning

When I first started learning , the biggest hurdle I had to overcome was setting up my computer. A lot of online courses had ways to try out code in the browser but I had to learn how to create a similar set up on my own computer at some point. RailsInstaller was a good start for me. I had and still use a Windows laptop. On a recent Ruby Rogues episode, it’s creator Luis Lavena said that he wanted to help users that used Windows and I mention it because his project was a big help for me. Eventually though, I wanted to use the same tools as the tutorials I was following and include gems that weren’t available for Windows. The solution came with Vagrant. I found enough tutorials online and treehouse has a specific course for it that it was enough for me to give it a try.

There was a specific bug on VirtualBox version 4.2.12 that I encountered but that was the only big problem I had when installing it. I was also having difficulties using existing vagrant boxes that other people have pubished on github until Barry Clark sent me a link for a rails development box that finally worked.

Using vagrant forced me to become more familiar with the command line but it gave me access to tools like rvm which I appreciate now more than ever. I’ve read that a Gemfile is really all you need with a Ruby project but I kept on having so many issues with different gems that it was easier to isolate projects using gemsets instead. I think that when you’re starting to learn something, the best thing is to minimize the number of things you have to look into to isolate problems. I knew that it would have been amazing to understand what was happening between the gems, but it was better to prioritize learning ruby programming and rails configuration.

The last thing I needed to remember when I started was balancing when it was time to go deeper into the subject matter or opt for an easier solution. As a beginner, it was easy to feel like I wasn’t being productive and ultimitely feel overwhelmed by what I was getting myself in to. I needed to be my own coach as a consequence of that. I pushed myself when I was really getting behind and went easy when I knew that I was starting to become too discouraged. I think that this is something fundamental to anyone teaching themselves, they learn more about their own motivations and what can sustain them for the next sprint.

Overview of What I've Been Learning

When I first started learning about web development, I took a crash course on the basics through Treehouse courses and website articles. I googled my way through what interested me and specific parts that I didn’t understand. Once I knew what something was, I moved on to the the next part. I didn’t become an expert at it, but I knew the basic idea of what that technology did. For example, I learned that HTML was a markup language organizing the structure of the page, CSS was responsible for the design aspects, JavaScript was responsible for behavior, back-end languages structured what a server sends to the browser, and databases like Postgresql stored information that users could access at a later time.

HTML

By diving a little more into the those parts, I learned that HTML had other subsets. There are a variety of tags that defines form inputs, links, captions and more. One of the most important aspects of HTML is the domain model object because that’s how libraries like jQuery interact with the page. HTML5 has a broad definition because along with new tags that were introduced like <audio> and <video>, it also standardized connections like websockets and server-sent events. Right now, I’m still becoming familiar with what counts as HTML5 exactly.

CSS

When it comes to CSS, I found that they have pre processors like SASS and LESS that make browser/vendor prefixes easier to use and introduced libraries as mixins. They organized css into something more manageable for front-end developers. I also learned about front-end frameworks like Bootstrap, Foundation, and Bourbon. The first two introduces additional markup to the html and interacts with their library while the latter functions as an extended mixin libray. This means that instead of adding markups for the page, you identify it in the scss file so that it can be processed into css. The first two makes the framework easier to implement in the beginning but the latter makes a clearer separation between design and the DOM.

JavaScript

Javascript has been the most difficult part to learn for me. There are a variety of libraries and frameworks that you could use. The one that I’ve used the most is jQuery but I’m trying to learn one of the popular frameworks that I’ve seen mentioned so much; Angular, Ember, and Backbone. Starting with any of them sort of feels like learning two languages at once but it will start making more sense later on.

Ruby on Rails

I delved deepest into this specific back end language. Most of my time has been devoted to learning Ruby on Rails. With that said, I’m more familiar with what they offer by default; jQuery, SASS, and MySQL. I chose Ruby on Rails because I found that there were more current resources that I could use to learn on my own and it was easier for me to understand how the methods work because of the syntax. It’s easier to create a simple CRUD site with Rails and it allowed me to delve deeper into what was happening when I needed to instead of learning it all at once.

Databases

Most of what I know about databases is hidden behind ActiveRecord and Oject Relational Mapping in Rails. I know how to create migrations, include associations, and adding indexes but I haven’t had to interact with MySQL or PostgreSQL directly. I’ve been able to connect it with Rails using its associated gems and I’m still learning how to optimize Rails queries to the databases. Taking baby steps with gems like bullet has been a good start.

Conclusion

After all this, I understand that knowing what something does is very different from being able to use it. Keeping a good overview stored in the back of my mind helps me makes sense of what I’m doing though. Also, instead of using other markup languages like Haml or compilers like Coffescript, I’ve stuck with HTML and Javascript because it helps me understand what I’m creating. Once, I’m completely comfortable with both, I’ll start making the switch to increase my productivity.