Monday, November 30, 2015

Bash yourself on a schedule!

To run terminal tasks on a schedule, you have to use something called the “crontab.” It is a file that you edit to include the bash code to run and the times and days to run it.

There are some interesting rules/best practices around editing the crontab.

To start, you have to create a crontab by entering crontab -e. Open and edit it in your favorite editor and save.

If you already have a crontab file that you want to edit, you actually shouldn’t. Rather, get a “copy” of your crontab file by doing crontab -l > new_crontab_copy. Then open the new_crontab_copy in your editor, edit and save.

For either of the above options, “install” your crontab file by giving it to crontab:
crontab my-crontab

(This post won’t be giving any advice on actually writing cron jobs - for that you can check out this Crontab quick reference.)

Monday, November 23, 2015

count vs size on ActiveRecord select queries

I stumbled on this bit of weirdness when using the SQL query User.select(:id, :name, :email).count. It threw a PG::UndefinedFunction error. Using User.select(:id, :name, :email).size worked instead.

Out of curiosity, I did some digging. According the the ActiveRecord docs,
not all valid select expressions are valid count expressions. The
specifics differ between databases. In invalid cases, an error from
the database is thrown.
I also stumbled on an issue on rails Github issues page about this, and a very helpful comment from rafaelfranca explained that I can also use count(:all).

Monday, November 16, 2015

Ctrl-Alt-Del for Linux

Back in my Ubuntu days, I had some issues with my computer locking up, and I didn’t know Linux well enough to break free. Once I found out about this trick, I was able to unlock 90% of the time.

The easiest way for me to remember was “BUSIER” spelled backwards.
  1. Hold down the Alt and SysRq (Print Screen) keys
  2. Type, the following, pausing one second between each - “R”, “E”, “I”, “S”, “U”, and “B”
Follow the link if you want to know exactly what all these key presses are doing.

Magic SysRq Key | Wikipedia

Monday, November 9, 2015

Intro to SSH for relative newbies

I have an app running on an Amazon EC2 instance, and it requires an SSH key to access it. Previously, I had to access it by navigating to the folder containing my private key pem file, then running ssh -p 2222 -i private_key.pem -A ubuntu@www.example.com.

Let’s break this down a bit.
  • -p 2222 - the port that my server runs on
  • -i private_key.pem - use an Identity File (SSH key) and specify the name
  • -A - use ForwardAgent to allow my public keys to pass through to the AWS server (important if I want to be able to access Github or some other service while SSH-ed into the server)
  • ubuntu@www.example.com - username (ubuntu) and server HostName (www.example.com)
This is all fine and dandy, but it’s a pain to remember. So, my next step to simplify this was setting up a terminal alias in ~/.bash_aliases

alias my-server-ssh="cd ~ && ssh -p 2222 -i private_key.pem -A ubuntu@www.example.com"

This lets me simply run my-server-ssh from whatever directory I’m in on the terminal and automatically login to my server. However, once I have a couple more servers to juggle, it starts to get troublesome keeping track of these things. It’s also problematic if I want to use a tool like Capistrano for deployment.

Here’s where setting up the ~/.ssh/config file comes in handy. I opened this file in my text editor, and entered this info:

Host my-server
    HostName www.example.com
    Port 2222
    User ubuntu
    IdentityFile "~/.ssh/private_key.pem"
    ForwardAgent yes

Once I save, I can now use my computer’s built in SSH manager to access my server by running the command ssh my-server. Then, in a tool like Capistrano, I can plug this line into my config file:

server 'my-server', roles: %w{app web}

It will read my ~/.ssh/config file, find the configuration for host my-server and SSH in.



Big ups to Nerderati for the helpful explanation on SSH config.

Monday, November 2, 2015

Object overload! Careful of instantiating objects in Ruby

Wowzers, I just tackled a major memory issue in an app I’ve been developing, and it was nearly all due to rampant over-instantiation of ActiveRecord objects.

Here’s the TL;DR: Use SQL queries whenever possible to grab info from the database, rather than using Ruby code.

Now for the longer version. First, I knew I had a memory issue because my server was crashing and it was showing up the logs saying that memory could not be allocated. But I had to find out what the issue was first.

Oink to the rescue. It’s a handy little Ruby gem that will log how much memory and how many ActiveRecord objects are instantiated for each request.

I installed Oink, ran through a few requests that seemed kinda slow, and lo and behold, I found the problem: One of my requests was generating 1500 objects!

Here’s what was happening. I was looping through an array of IDs, and for each one I was calling

account.users.order(:id).select{ |user| user.id == id }.first

Don’t laugh. I have a baby at home, I was sleep deprived, I don’t know why I did it this way. But yes, this is instantiating all User objects in an account, and it’s doing it every single time it iterates through the loop. Hence, 1500 objects instantiated per request.

This was easily solved by a simple find_by_id with the id from the array.

That took me down to only one instance of each User object, which is still not fantastic. So, I ended up using one of my favorite ARel methods, pluck, to get just the attributes of the users that I need without actually creating the User objects.

That’s the ticket! From 1500 User objects to 0, this should significantly help with speed and memory usage. I ended up combing through the rest of the app and finding a few other spots where object instantiation was a bit out of control, though not nearly as bad as that one.

It became a kind of game - and in the end, I’d say I won.

Thanks to Engine Yard for the great tips. Lots more in their linked post.