Heroku で Unicorn にした

Dynos and the Dyno Manager | Heroku Dev Center

Dynos are also cycled at least once per day, in addition to being restarted as needed for the overall health of the system and your app

によると、Heroku は 1 日 1 回、リスタートするみたい。

少しでも起動を早くしようと WEBRick から Unicorn にした。

Deploying Rails Applications With Unicorn | Heroku Dev Center

にある手順で入りました。

ローカルでも

$ foreman start

localhost:5000 に WEBRick より気持ち早めに起動するようになりました。

参考 & 関連

アクセスがなくても Heroku を止めない

Heroku 上に作ったサイトにアクセスすると遅い時がある。

一度アクセスすれば普通になるけど。

Heroku のリファレンスによると、

Dynos and the Dyno Manager - Dyno sleeping

Apps that have scaled the number of web dynos (dynos running the web process type) so that only a single web dyno is running, will have that web dyno sleep after one hour of inactivity.

とのこと。

Heroku を無料で使っていると Dyno は 1 個しかないから、1 時間アクセスがないとスリープするみたい。

VPS や自宅サーバなどで cron の使える環境があれば定期的に curl なりすれば簡単なんだけど、無料かつ Heroku 単体で何とかしたい。

無料の回避策として、 Easy way to prevent Heroku idling? - Stack Overflow を読むと、昔は

  • New Relic
  • Pingdom

の利用があったけど、今は New Relic をインストールしてもスリープするし、Pingdom は 1 サイト無料から 30 日間無料に変更されたため、恒久的方法にならない。

ということで、Heroku のサイトに Feed を用意し、その Feed を Feedly なり livedoor Reader に登録して、Feed を読みにきたクローラのアクセスで Heroku を Weak up させることにした。

Feed は Rails の AtomFeedHelper を参考にした。

ActionView::Helpers::AtomFeedHelper

変えたのは、クローラに 20 分おきに来てもらえるように 20 分毎に更新しているように見せていること。

app/controllers/posts_controller.rb の @posts = Post.all をこうした。

    d = DateTime.current
    m = 20
    # m = 20 なら min: 0..19->0, 20..39->20, 40..59->40
    @last_updated = d.change(min: (d.minute/m)*m)

    # Feed に出す内容も最終更新日から m 分以内のものにする
    from = @last_updated.advance(minutes: -m)
    to   = @last_updated
    @posts = Post.where(created_at: from...to).order(created_at: :desc)

そして app/views/posts/index.atom.builder の

feed.updated(@posts[0].created_at) if @posts.length > 0

feed.updated(@last_updated)

にした。これでクローラがいつ来ても 20 分おきに更新されているように見えるはず。

Posts の中身は会員登録数や、コメント数などにすれば、RSS リーダでサービス監視的なことができます。

この Feed は自分が読むだけの秘密の Feed だけど、一般公開する Feed なら Generating RSS feed in Rails 3 - Stack Overflow の config/routes.rb に書く

resources :news_items
get '/feed' => 'news_items#feed',
      :as => :feed,
      :defaults => { :format => 'atom' }

と、app/views/layouts/application.html.erb の

<%= auto_discovery_link_tag :atom, "/feed" %>
<%= auto_discovery_link_tag :rss, "/feed.rss" %>

を使うだろうからメモ。

Ruby の Hash を値でソートして、次にキーでもソート

例えば点数を管理する hash があって、キーが氏名で、値がスコア。

score = { aaaa: 1, bb: 2, ba: 2, c: 3 }

ハイスコア順で並べて、氏名も ABC 順で並べたい。

下記では氏名が並ばない。ba, bb と並んでほしいよ。

p score.sort_by {|k, v| -v}
[[:c, 3], [:bb, 2], [:ba, 2], [:aaaa, 1]]

なのでこう。

p score.sort {|a, b| a[1] == b[1] ? a[0] <=> b[0] : b[1] <=> a[1] }
[:c, 3], [:ba, 2], [:bb, 2], [:aaaa, 1]]

「スコアが同じ ? 氏名順 : スコア順」 と分かりやすいけど、いつも忘れるのでメモ。

Ruby 以外の言語でこれを実装するときも方法を探すんだよね。公式ドキュメントに用法を載せてほしいコードの一つ。

elixir 入門

麹町で開かれた elixir 勉強会の Shinjuku.ex #7 on Zusaar に参加しました。

言語マニアや日本一コミット数の多いコントリビュータという濃い面子のなか、elixir をインストールすらしていなかった自分のメモです。

elixir 基礎知識

f:id:oooooooo:20130629105745p:plain

  • 「エリクサー」と読む
  • Erlang ベースで Ruby っぽい記法
  • Erlang のランタイムが使える
  • Dave Thomas がバイブルになる本にしか付けられないタイトルの Programming Elixir を出す

インストール

Getting Started に elixir v0.9.0 を Mac, Fedora 17+, Arch Linux へインストールする方法が書かれています。 Ubuntu ないのが珍しい。

Mac のインストールならこう。

# brew install erlang  じゃ古いので Erlang R16B が必要
$ brew tap homebrew/versions
$ brew install erlang-r16
$ brew install elixir

elixir-lang/elixir からソースでインストールするにしても Erlang R16B が必要。

vim プラグイン

hello, world

まずは REPL から。iex の終了は C-c して a enter か、C-g して q enter。

$ iex
iex> greeting = "goodbye"
"goodbye"
iex> "#{greeting}, world"
"goodbye, world"
# UTF-8 標準対応
iex> "こんにちは"
"こんにちは"

ファイルの場合。

$ cat hello.exs
defmodule Hello do
  def world do
    IO.puts "hello, world"
  end
end
Hello.world
$ elixir hello.exs
hello, world

もしくは、

$ cat hello.exs
IO.puts "hello, world"
$ elixir hello.exs
hello, world

とか。

参考資料

下記は 2012 年で 0.4 ベースと古いけど、感じが掴めます。

下記はお勧め Screencasts。7/17 まで $9。2 時間。

その他勉強会で知ったこと

Mac をキーボードで操作する Shortcat

Shortcat は

を活用しまくっていたり、ウィンドウ操作に

  • Divvy
  • RightZoom
  • SizeUp
  • Slate

を使ったり、ブラウジングに

  • Keyconfig
  • Vichrome
  • Vimium
  • Vrome

を使うキーボード派にお勧めのツール。隣のエンジニアさん、あなたですよ。

何かというと Vimperator 系のヒントモードが Mac 全体で使えるんです。やべえ。

ヒントモード?はあ?という方へ。アプリのボタンにキーを割り当ててキーボードでアクセスできる、ということです。

ダウンロード

f:id:oooooooo:20130615170528p:plain

Shortcat の入手はこちら

キャッチコピーが Killing mice, one at a time.

マウスを使わないキーボードショートカットだから Shortcat。ネーミングも素晴らしい。

言語を英語にする

Shortcat を最大限に使うにはメニューを英語にする必要があります。

英語にするとはてなブログのメニューが英語になったり、 Mac の辞書をカスタマイズ しないといけなかったりと、 いろいろな副作用があるけれど、それだけの価値があります。

英語化のやり方。

  1. システム環境設定 → 言語とテキスト
  2. 「言語をドラッグして、優先する順番に並べます。」で日本語と English の順番をドラッグして変える
  3. ログアウトして、ログインすれば完了

f:id:oooooooo:20130615182240p:plain

使い方

Getting Started with Shortcat から学んだことを紹介。

Shortcat を実感するために System Preferences を開いておきます。

f:id:oooooooo:20130615180119p:plain

  • shift + command + space で Shortcat を起動
  • 「Language & Text」を選択するいくつかの方法
    • 大文字小文字を無視して「language」や「text」して enter
    • 単語の先頭である「lt」( 「Show All」なら「sa」 ) して enter
  • 「.」でアクセス一覧
    • tab や shift + tab で移動して enter
    • D や AJ などのラベルがあるので AJ を選びたければ control + aj して enter
  • マウスのあれ
    • マウスクリックは enter
    • command + マウスクリックは command + enter
    • ダブルクリックは enter を素早く 2 回
    • マウスのホバーは control を素早く 2 回 ( 芸が細かい! )
  • Tips
    • 絞り込みの色が出るまで待たないでキー入力できます。例えば Show All は常に sa なので command + enter + sa + enter と高速に一気に入力しても動きます。いろいろなユニークな省略ワードを覚えておくと効率が上がります。Desktop & Screen Saver を dss とかね。

今日学んだこと

Getting Started with Shortcat にあった TL;DR は「too long; didn’t read.」の略で「長すぎると読まれないから要約」的な意味。

ネット英語TL;DRの意味 | 秋元

Mac の辞書設定

Mac の言語を英語にしたら辞書に大辞林や英和・和英辞典がなくなった。

辞書の設定を見たら日本語系の辞書のチェックが外れていた。

あと、いろいろな設定や辞書や辞典があることを知った。

Apple Dictionary というパソコン用語辞典とか、Wikipedia はいろんな言語を選べることとか。

f:id:oooooooo:20130615183728p:plain

gem の概要をコマンドラインから調べる方法

この gem は何だろう?と思うことがしばしば。

今まで Alfred を使って The Ruby Toolbox や RubyGems を検索 していたけど、知りたい gem が何個もあると面倒。

コマンドラインからできないか調べてみた。

gem search --details --local ( gem search -dl )

gem search に --details オプションを付ければ概要を教えてくれます。

それと --local を付けるとローカルを検索するので速いです。

ちなみに --deatails と --local は -dl と省略できます。

あと gem search は部分マッチなので大量マッチすることがあります。gem search -d ^spork$ とすることもできます。 ^ や $ を付けないほうが新たな発見もあって楽しいけどね。

$ gem search -dl spork

*** LOCAL GEMS ***

spork (1.0.0rc3)
    Authors: Tim Harper, Donald Parish
    Homepage: http://github.com/sporkrb/spork
    Installed at: /home/oooooooo/.rbenv/versions/1.9.3-p429/lib/ruby/gems/1.9.1

    spork

gem specification spork description ( gem sp spork description )

で、spork は --details を spork としか教えてくれません。ひどい。 ( six も six とかしか教えてくれません )

http://rubygems.org/gems/spork では

A forking Drb spec server

とちゃんと出ているのにね。

ということで gem search --details ではなく gem specification gem description なら RubyGems と同じ情報を教えてくれます。

specification は sp と略せるけど、description は一字たりとも略せません。

$ gem sp spork description
--- A forking Drb spec server
...

余分な「---」や「...」は gem の仕様です。

summary と description

gem には specification という情報ファイルがあり、そこには summary と description があります。

gem sp spork すると spork の specification をすべて見ることができます。

$ gem sp spork
--- !ruby/object:Gem::Specification
name: spork
version: !ruby/object:Gem::Version
  version: 0.9.2
platform: ruby
authors:
- Tim Harper
- Donald Parish
autorequire:
bindir: bin
cert_chain: 
date: 2012-05-18 00:00:00.000000000 Z
dependencies: 
description: A forking Drb spec server
email:
- timcharper+spork@gmail.com
executables:
- spork
extensions: 
extra_rdoc_files:
- MIT-LICENSE
- README.rdoc
files:
- bin/spork
- MIT-LICENSE
- README.rdoc
homepage: http://github.com/timcharper/spork
licenses: 
metadata: {}
post_install_message:
rdoc_options:
- --main
- README.rdoc
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
  requirements:
  - - ! '>='
    - !ruby/object:Gem::Version
      version: '0'
required_rubygems_version: !ruby/object:Gem::Requirement
  requirements:
  - - ! '>='
    - !ruby/object:Gem::Version
      version: '0'
requirements: 
rubyforge_project: spork
rubygems_version: 2.0.3
signing_key:
specification_version: 4
summary: spork
test_files: 

gem sp spork の後ろに summary や description を指定すると、その部分だけ表示することができます。

まとめるとこんな感じ。

  • gem specification gem summary と gem search --details は summary を表示
  • gem specification gem description は description を表示

description の方が詳しそうなので gem specification gem description を alias でもして使えばよさそうですが、description を持たない gem があります。 例えば charlock_holmes とか sanitize とか treetop とか warden とかは summary だけで description を持ちません。

summary を持たない gem はないけど、spork や six のように説明になっていない summary が散見します。

geminfo

なので summary と description を同時に表示するやっつけ仕事なコマンドを .zshrc に登録しました。

function geminfo() {
  if test $# -eq 1; then
    gem spec $1 summary     | ruby -pe 'gsub(/(\-\-\-|\.\.\.\n)/, "")'
    gem spec $1 description | ruby -pe 'gsub(/(\-\-\-|\.\.\.\n)/, "")'
  else
    bundle list | awk '/\* .+ / { print $2; system("gem spec "$2" summary;gem spec "$2" description") }' | ruby -pe 'gsub(/(\-\-\-|\.\.\.\n)/, "")'
  fi
}

使い方はこんな感じ。

$ geminfo spork
 spork

 A forking Drb spec server

それと、bundle install 後のフォルダで geminfo とすると、bundle show 対象の gem のすべての説明が出ます。

GitLab で利用されている全ての gem の概要を知りたいならこうします。

$ git clone git://github.com/gitlabhq/gitlabhq.git
$ cd gitlabhq
$ bundle install
$ bundle show
$ geminfo
actionmailer
 Email composition, delivery, and receiving framework (part of Rails).

 Email on Rails. Compose, deliver, receive, and test emails using the familiar
  controller/view pattern. First-class support for multipart email and attachments.

actionpack
 Web-flow and rendering framework putting the VC in MVC (part of Rails).

 Web apps on Rails. Simple, battle-tested conventions for building and testing
  MVC web applications. Works with any Rack-compatible server.

activemodel
 A toolkit for building modeling frameworks (part of Rails).

 A toolkit for building modeling frameworks like Active Record and Active Resource.
  Rich support for attributes, callbacks, validations, observers, serialization, internationalization,
  and testing.
( 以下省略 )

余談

gem コマンドを gem help spe して調べている時に typo を発見しました。

> gem help sp
Usage: gem specification [GEMFILE] [FIELD] [options]

  Options:
    -v, --version VERSION            Specify version of gem to examine
        --platform PLATFORM          Specify the platform of gem to specification
        --[no-]prerelease            Allow prerelease versions of a gem
        --all                        Output specifications for all versions of
                                     the gem
        --ruby                       Output ruby format
        --yaml                       Output RUBY format
( 以下省略 )

「--yaml」の説明が Output YAML format ではなく Output RUBY format になっています。

typo 修正を Pull Request したところ、先日、取り込まれました。

https://github.com/rubygems/rubygems/commit/e158c1b4f2939b122d0493fef0d12c7293cd9e91

単なる typo 修正なんだけど、rubygems に commit できて嬉しいw