How to calculate sha1 for part of file

In one task I needed to calculate sha1 for first 1mb of my file.

Here is simple solution:

opened = File.open(path)
Digest::SHA1.hexdigest opened.read(1048576)     # 1mb.

That’s all =)

Segfault when install 1.9.3 on OSx

When I tried to install ruby 1.9.3 on my mac lion with openssl 1.0.0e I take segfault error.

And here you can take a look, how to avoid this.

 rvm remove ruby-1.9.3
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:$HOME/.rvm/bin
rvm pkg install iconv
rvm pkg install openssl
rvm install ruby-1.9.3 --with-openssl-dir=$rvm_path/usr --with-iconv-dir=$rvm_path/usr

Based on Chris Irish post http://www.christopherirish.com/2011/09/02/ruby-1-9-2-segmentation-fault-and-openssl/

Nice dynamic scope by status

STATUSES = %w(pending available sold)

STATUSES.each do |status|
class_eval "scope :#{status}, where(status: :#{status})"
end

Little notes about multistaging nginx + unicorn

I made this task for quite some time, so I can not reproduce the process in order, so I will describe just how it should looks in the end.

Why Unicorn? It was a rails app, which didn’t have mobile interface so all clients are fast. In plans it shouldn’t be really highloaded (as I can see now less than 1000 requests per day) so fast and light unicorn is best choise, I think. 

Also we should have 2 rails app running on one physical server (production and staging). So, how I made this:

/etc/nginx/nginx.conf


user www-data;
worker_processes 4;
pid /var/run/nginx.pid;

events {
	worker_connections 512;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

Two files in sites-enabled directory:

/etc/nginx/sites-enabled/staging


server {
    # We will take access to staging by that port
    listen       4321;
    server_name  plsnr.ru plsnr.com *.plsnr.ru;

    access_log  /home/user/var/www/staging/shared/logs/access.log;
    error_log   /home/user/var/www/staging/shared/logs/error.log;

    # Максимальный размер тела запроса клиента
    client_max_body_size 101M;

    location ~ /.svn/ {
        deny all;
    }

    location ~ /.git/ {
        deny all;
    }
    
    location ~ /\.ht {
        deny  all;
    }

	location / {
		root	/home/user/var/www/staging/current/public;
	
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_redirect off;

		if (!-f $request_filename) {
			proxy_pass http://127.0.0.1:3001;
			break;
		}
	}

	error_page 500 502 503 504 /500.html;
    location = /500.html {
	    root /home/user/var/www/staging/current/public;
	}
}

/etc/nginx/sites-enabled/plsnr.ru

server {
    # listen default http port
    listen       80;
    server_name  plsnr.ru plsnr.com *.plsnr.ru;

    access_log  /home/user/var/www/production/shared/logs/access.log;
    error_log   /home/user/var/www/production/shared/logs/error.log;

    # Максимальный размер тела запроса клиента
    client_max_body_size 101M;

    location ~ /.svn/ {
        deny all;
    }

    location ~ /.git/ {
        deny all;
    }
    
    location ~ /\.ht {
        deny  all;
    }

	location / {
		root	/home/user/var/www/production/current/public;
	
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_redirect off;

		if (!-f $request_filename) {
			proxy_pass http://127.0.0.1:3000;
			break;
		}
	}

	error_page 500 502 503 504 /500.html;
    location = /500.html {
	    root /home/user/var/www/production/current/public;
	}
}

We have no any specific unicorn config file and identical RAILS_APP/config/environments/production.rb and RAILS_APP/config/environments/staging.rb


Plsnr::Application.configure do
  config.cache_classes = true

  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true

  config.action_dispatch.x_sendfile_header = "X-Sendfile"

  config.serve_static_assets = false

  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.default_url_options = { :host => 'plsnr.ru' }

  config.action_mailer.delivery_method = :ses  

  config.i18n.fallbacks = true

  config.active_support.deprecation = :notify

  Paperclip.options[:command_path] = "/usr/bin"
end

It’s all about nginx+unicorn configuring. Next step is deployment. Certanly, capistrano.

RAILS_APP/config/deploy.rb


require 'bundler/capistrano'
require 'capistrano/ext/multistage'

set :stages, %w(production staging)
set :default_stage, "staging"

set :domain, "ouruser@plsnr.ru"
set :backup_dir, "/home/ouruser/var/www/production/backup"

set :use_sudo, false
set :application, "plsnr"

set :scm, :git
set :repository,  "git@github.plsnr/plsnr.git"
set :deploy_via, :remote_cache

role :web, domain
role :app, domain
role :db,  domain, :primary => true


after 'deploy:update_code', :roles => :app do
  run "ln -s #{deploy_to}/shared/public/uploads #{current_release}/public/uploads"
  backup
end

# backup db

task :backup, :roles => :db, :only => { :primary => true } do
	filename = "#{backup_dir}/#{application}.dump.#{Time.now.to_f}.sql.bz2"
	text = capture "cat #{deploy_to}/current/config/database.yml"
        yaml = YAML::load(text)

	on_rollback { run "rm #{filename}" }
	run "mysqldump -u #{yaml['production']['username']} -p #{yaml['production']['database']} | bzip2 -c > #{filename}" do |ch, stream, out|
  	ch.send_data "#{yaml['production']['password']}\n" if out =~ /^Enter password:/
	end
end

namespace :deploy do
  task :start do 
    run "cd #{deploy_to}/current && bundle exec unicorn_rails -E #{rails_env} -p #{unicorn_port} -D"
  end
  task :stop do 
    run "kill `cat #{unicorn_pid}`"
  end
  task :graceful_stop do
    run "kill -s QUIT `cat #{unicorn_pid}`"
  end
  task :reload do
    run "kill -s USR2 `cat #{unicorn_pid}`"
  end
  task :restart do
    stop
    start
  end
end

RAILS_APP/config/deploy/production.rb


set :branch, "master"
set :rails_env, "production"
set :unicorn_port, "3000"
set :deploy_to, "/home/user/var/www/production"
set :unicorn_pid, "#{deploy_to}/shared/tmp/pids/unicorn.pid"

RAILS_APP/config/deploy/staging.rb


set :branch, "staging"
set :rails_env, "staging"
set :unicorn_port, "3001"
set :deploy_to, "/home/user/var/www/staging"
set :unicorn_pid, "#{deploy_to}/shared/tmp/pids/unicorn.pid"

Thats all! If I haven’t forgotten anythink %)

So production we have on

http://plsnr.ru/

and staging on

http://plsnr.ru:4321

P.S. Yes we needed one domain name %)

P.P.S. Site name isn’t real

Good post about Unicorn (if you want to customize it) https://github.com/blog/517-unicorn

Презентация с семинара по функциональному языку программирования Haskell. Казань, 2012.

Golden hill example (задача о Золотой горе)

Script for programming task “golden hill (exercise of recursion and dynamic programming)” written on Ruby

- At the input we have txt file with integer numbers. In file N rows. In row i: i elements.

- If in row i we have number a[i,k], so in next row adjacent will be numbers: a[i+1,k] and a[i+1,k+1].

- Path starts at single number at first row and ends at last and runs through adjacent numbers (maximum paths is 2^(N-1)).

- Calculate max sum path and show it.

At the input we have file input.txt. At the output we should see max sum and sequence of indexes of elements, which made that path.

This task has been at the international competition for programming in 1994. Here is Ruby realization.

I used that formula: formula

So here you can take a look to my realization:

https://github.com/graffzon/golden_hill_exercise