27 3 / 2013

Monitoring memory usage on long-running scripts

There is a simple way to monitor memory usage on long-running scripts. You can just create new thread which will output current memory usage to console in short time intervals:

Thread.new do
  while true do
    memory = `ps -o rss -p #{Process::pid}`.chomp.split("\n").last.strip.to_i
    puts "Memory: #{memory/1024} MB"
    sleep 0.25
  end
end

Tags:

Permalink

20 3 / 2013

More readable specs with dynamic date methods

Often times, in my specs, i use variables like jan_01 to represent dates. It makes my specs much more readable. For example:

date = SequentialDate.new(jan_01)
expect(date.next).to eq(jan_02)

I used to create these variables by hand, but there is much easier way to do it by utilising pure awesomeness of ruby. Just define following module in your support rspec dir:

require 'date'
module Support
  module DateHelpers
    def method_missing(name, *args, &block)
      begin
        Date.parse(name.to_s)
      rescue ArgumentError
        super
      end
    end
  end
end

And require it in rspec config file:

RSpec.configure do |config|
  config.include Support::DateHelpers
end

The beauty of it is that it wil parse whatever Date.parse is able to handle. Some examples are:

  • jan_01
  • jan_1st
  • jan_01_2013
  • _3rd_feb_2013
  • _01_JAN_2013
  • february_14th_2013

13 3 / 2013

Super fast way of launching postgres console for rails apps

Database console can be run with bundle exec rails dbconsole command. However, this operation performs relatively slow (due to bundler and deps).

We can make it much faster with simple ruby script:

#!/usr/bin/env ruby

require 'yaml'
require 'fileutils'

database_config = YAML.load_file(Dir.pwd + '/config/database.yml')['development'];
database_name = database_config['database']

exec('psql', "-d#{database_name}")

Just save the script somewhere in your $PATH and give it u+x permission.

I like to place scripts like these in my ~/dev/bin folder (included in $PATH). I gave this one db name, so the only thing i need to do to fire up postgres console is to type db. Simple and extremely fast.

08 3 / 2013

Optimizing postgresql query for DISTINCT values

If you want to get DISTINCT values from large tables (and by large I mean hundreds of thousands of rows), it is painfully slow.

Simple query like this: SELECT DISTINCT(day) FROM reports can take a lot of time to be processed.

Here is how you can improve its speed dramatically using postgres recursive functionality:

WITH RECURSIVE t(n) AS (
    SELECT MIN(day) FROM reports
  UNION
    SELECT (SELECT day FROM reports WHERE day > n ORDER BY day LIMIT 1)
    FROM t WHERE n IS NOT NULL
)
SELECT n FROM t;

I’ve tested it against 50 million rows with 365 distinct values for day, and it executed in 8ms, opposed to 15.7 seconds for SELECT DISTINCT query.

There are only two prerequisites:

  • you need index column you want to get distincts from.
  • you have postgres 8.4+

For more info, check out the postgresql docs on the topic: http://www.postgresql.org/docs/9.1/static/queries-with.html

29 12 / 2012

Rails consecutive migrations acting weird

If you’re using models in your database migrations, its good practice to define dummy active record clases for them:

class SomeMigration < ActiveRecord::Migration
  class User < ActiveRecord::Base
    reset_column_information
  end
  # ...
end

If you have many migrations to run and model definition changes over time (which is likely to happen), you need to call reset_column_information in order to “reload” the model on beginning of every migration.

14 12 / 2012

Showing git branch in fish shell prompt

Put following code at the end of ~/.config/fish/config.fish. It will also highlight in red if branch is dirty.

set fish_git_dirty_color red
set fish_git_not_dirty_color green

function parse_git_branch
  set -l branch (git branch 2> /dev/null | grep -e '\* ' | sed 's/^..\(.*\)/\1/')
  set -l git_diff (git diff)

  if test -n "$git_diff"
    echo (set_color $fish_git_dirty_color)$branch(set_color normal)
  else
    echo (set_color $fish_git_not_dirty_color)$branch(set_color normal)
  end
end

function fish_prompt
  if test -d .git
    printf '%s@%s %s%s%s:%s> ' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) (parse_git_branch)
  else
    printf '%s@%s %s%s%s> ' (whoami) (hostname|cut -d . -f 1) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal)
  end
end

30 10 / 2012

"42 is a nice number that you can take home and introduce to your family"

Douglas Adams

27 10 / 2012

Attachinary v1.2.0 released

Changelog

  • Drag and drop support (on supported browsers)
  • Selecting multiple files (on supported browsers)
  • Upload progress indicator (prepended on submit button)
  • Rake task for fetching assets (rake attachinary:fetch_fileupload)
  • Ability to assing image urls (e.g. user.avatar_url = 'http://..')
  • Ability to assign IO objects (e.g. user.avatar = File.open(...))
  • No-JS support

05 10 / 2012

How to validate Array fields in Mongoid

Define custom ArrayValidator in app/validators/array_validator.rb:

class ArrayValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, values)
    [values].flatten.each do |value|
      options.each do |key, args|
        validator_options = { attributes: attribute }
        validator_options.merge!(args) if args.is_a?(Hash)

        validator_class_name = "#{key.to_s.camelize}Validator"
        validator_class = begin
          validator_class_name.constantize
        rescue NameError
          "ActiveModel::Validations::#{validator_class_name}".constantize
        end

        validator = validator_class.new(validator_options)
        validator.validate_each(record, attribute, value)
      end
    end
  end
end

You can use it like this in your models:

class User
  include Mongoid::Document
  field :tags, Array

  validates :tags, array: { presence: true, inclusion: { in: %w{ ruby rails } }
end

It will validate each element from the array against every validator specified within array hash.

10 9 / 2012