mongodb + php

on 2011/12/26 - 0 Comments -

さくらインターネットの VPS に mongodb をインストールする。

・CentOS5.5にMongoDBをインストールしてみる
http://blog.madapaja.net/2010/07/centos55mongodb.html

・CentOS and Fedora Packages
http://www.mongodb.org/display/DOCS/CentOS+and+Fedora+Packages

・PHP mongodb チュートリアル
http://us2.php.net/manual/ja/mongo.tutorial.php

TED : Luis von Ahn: Massive-scale online collaboration

on 2011/12/21 - 0 Comments -



画像認証しながらデジタイズ。言語学習しながらの翻訳。すげー。

神宮・赤坂・皇居(14km)

on 2011/11/21 - 0 Comments -

ペースに気をつければ結構走れるようになってきた。
プロテインほしい。

11月:36km

Google App Engine で Datastore Read Operations あふれ

on 2011/11/20 - 0 Comments -

最近更新リストがよく死んでいた件です。

Google App Engine の Datastore Read Operations の制限回数が厳しくなったのが直接の原因で、今までの処理ロジックだとその制限にかかってしまい、毎日朝から夕方までずっとエラーを表示してました。

Datastore Read Operations の回数が半分になればよさそうだったので、キャッシュの期間を延ばして Datastore へのアクセスが半分以下になるように修正しました。

更新リストへの反映が少し遅くなりますが、これでしばらくは大丈夫なはず。

ご不便おかけしてすいませんでした。

神宮・赤坂(11km)

on 2011/11/13 - 0 Comments -

調子としてはまあまあだがキレが全くなし。
平日も1日くらい走りたい。

11月:22km

神宮・赤坂御用地(11km)

on 2011/11/07 - 0 Comments -

上半身がついてこない感じが最近顕著。要筋トレ
そろそろ 20km くらい走りたい。
11月:11km

OmniAuth + Facebook + iframe で画面遷移がおかしい件

OmniAuth を使って Facebook の認証まわりを実装した場合、:iframe => true をつけないと iframe 内でも Go to Facebook リンクの画面が表示されてしまう。

# もう Facebook にいるのですぐに認可画面を表示してほしい、という話

こんな感じで :iframe => true を追加してあげればよさげ。


config/initializers/oa-oauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook , FB_APP_ID, FB_APP_SECRET, :scope => 'status_update, publish_stream', :iframe => true
end




あと OmniAuth を使った場合、認可完了後のリダイレクト先が iframe 内のバックエンドのサーバー(僕の場合は Heroku )に直に向いてしまって、Facebook から別のサイトへ移動するという動きになってしまう。

OmniAuth.config.full_host を指定してあげればいいとかこのへんに書いてあるけど、Facebook では API の呼び出し元サイトの URL が事前登録してあるバックエンド( Heroku )の URL と一致している必要があるので、そもそも OmniAuth.config.full_host を Facebook アプリの URL にすることができないです。

# OmniAuth.config.full_host に Facebook のアプリの URL を指定すればよさそうだけど、API の呼び出しがそもそもできなくなる、という話

しょうがないので認可完了後にアプリページ全体をリロードするよう実装しました。ださいけど。


app/controller/session_controller.rb
redirect_to "http://apps.facebook.com/XXXXXXXXXXXXXX/"



Open Flash Chart II Plugin for Ruby on Rails on Heroku

on 2011/10/31 - 0 Comments -

Open Flash Chart II Plugin for Ruby on Rails

By using this plugin, you can generate beautiful charts easily on Ruby on Rails, even if it's on Heroku.

Setup:

# cd someproject
# rails plugin install git://github.com/pullmonkey/open_flash_chart.git
# cp vendor/plugins/open_flash_chart/assets/javascripts/swfobject.js public/javascripts/
# cp vendor/plugins/open_flash_chart/assets/open-flash-chart.swf public/



Wirte chart generation codes in some controller:

class TestItController < ApplicationController
  def index
    @graph = open_flash_chart_object(600,300,"/test_it/graph_code")
  end

  def graph_code
    title = Title.new("MY TITLE")
    bar = BarGlass.new
    bar.set_values([1,2,3,4,5,6,7,8,9])
    chart = OpenFlashChart.new
    chart.set_title(title)
    chart.add_element(bar)
    render :text => chart.to_s
  end
end



Write chart display codes in some view:

<script type="text/javascript" src="/javascripts/swfobject.js"></script>
<%= @graph %>



Write route setting in config/routes.rb:

match "/test_it/graph_code" => "test_it#graph_code"



Restart Server:

# rails s



Push to Heroku if it works:

# git push heroku master



All done.

神宮・赤坂御用地・皇居(11km)

on 2011/10/30 - 0 Comments

皇居をかすって帰ってくる周回コース。
このコースはいたるところに坂があって鍛えられそうです。

プロ野球やってる日は神宮は通らないほうがいいです。

10月:54km

How to generate a specific Date on Ruby

on 2011/10/29 - 0 Comments -


somocode.rb
require 'date'

# Today
Date.today

# 1st of this month
Date.new(Time.now.year, Time.now.month, 1)

# 1st of next month
Date.new(Time.now.year, Time.now.month, 1) >> 1

# 1st of last month
Date.new(Time.now.year, Time.now.month, 1) << 1

# 1 week later
Date.today + 7

# 1 week before
Date.today - 7



And you can use these Date valuables in Model 'where' phrase on Rails.


somocode.rb
models = SomeModel.where("date <= ?", Date.today)


作業効率を上げるためにすべきたった1つのこと

on 2011/10/26 - 0 Comments -

Key Repeat Rate を Max にしましょう。


Word、Excel、Emacs でカーソルの移動が速くなり、作業効率がそれだけで数%は向上するでしょう。
# ただし常に検索で瞬間移動してる人は除く

神宮・赤坂御用地(11km)

on 2011/10/25 - 0 Comments -

気持ちよく走れるようになってきた!
自転車を買ってから調子がいいです!

10月:43km

家から皇居(9km)

on 2011/10/15 - 0 Comments -

ごーさんと一緒に家から皇居。

赤坂御用地を一週するコースは皇居と同じく信号がなく、また適度に坂がありよいコースだと思った。というかむしろ空いてるし、こっちのほうがいいかも。

調子は底辺からの上向き気配。

10月:32km

no such file to load -- net/https

When I started using heroku, I got some errors and solved them by installing ext modules.

Installing libopenssl-ruby package by apt-get was one of the solutions, but I couldn't use that package because there was no available package for my ruby, version 1.9.

The error is:


# gem install heroku
# ...(installing)
# heroku
/usr/local/lib/ruby/gems/1.9.1/gems/rest-client-1.6.7/lib/restclient.rb:9:in `rescue in ': no such file to load -- net/https. Try running apt-get install libopenssl-ruby (LoadError)
 from /usr/local/lib/ruby/gems/1.9.1/gems/rest-client-1.6.7/lib/restclient.rb:5:in `'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/gems/1.9.1/gems/rest-client-1.6.7/lib/rest_client.rb:2:in `'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/gems/1.9.1/gems/heroku-2.9.0/lib/heroku/client.rb:2:in `'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/gems/1.9.1/gems/heroku-2.9.0/lib/heroku.rb:6:in `'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
 from /usr/local/lib/ruby/gems/1.9.1/gems/heroku-2.9.0/bin/heroku:6:in `'
 from /usr/local/bin/heroku:19:in `load'
 from /usr/local/bin/heroku:19:in `
' # (omg)



How I solved:

I installed two ext modules to my ruby - openssl and readline.
# I also installed libssl-dev before installing openssl because ssl.h was needed to install openssl.


# apt-get install libssl-dev
# cd /usr/local/src/ruby-1.9.2-p290/ext/openssl/
# ruby extconf.rb 
# make
# make install
# cd ../readline
# ruby extconf.rb 
# make 
# make install



All done.

VirtualBox + Ubuntu + Ruby + Rails + PostgreSQL

on 2011/10/12 - 0 Comments -

Ruby + Rails + PostgreSQL @ Ubuntu @ VirtualBox @ MacOS の環境構築のメモ。

1. VirtualBox のインストール

4.1.4 をダウンロードしてきて適当にインストール。

2. Ubuntu のインストール

11.04 をダウンロードしてきて VirtualBox に VM 新規追加・インストール。メモリとか HDD とかそのへんはデフォルトで。

3. もろもろインストール

ssh, emacs, git などなどを apt-get でインストール。

4. Ubuntu のネットワーク設定

一旦 VM をシャットダウンして、VirtualBox の設定画面から VM の NIC を増やす。Adapter 1 は NAT のままで、Adapter 2 を Host-only Adapter にする。設定したら VM を起動し、eth1 が up していることを確認。たぶん 192.168.XXX.XXX あたりが振られていて、ホスト側から疎通するはず。

5. Ruby のインストール

ruby-1.9.2-p290.tar.gz をダウンロードしてきて何も考えずいつもの3コマンドでインストール。

6. RubyGems のインストール

rubygems-1.8.10.tgz をダウンロードしてきて ruby setup.rb でインストール。

7. Rails のインストール

ちょっとつまずいたのでメモメモ。zlibc、rake をインストールしてから rails をインストールする。


# apt-get install zlibc zlib1g-dev

# cd /usr/local/src/ruby-1.9.2-p290/ext/zlib
# ruby extconf.rb
# make
# make install

# gem install rack
# gem install rails


なんか rails のインストールでメモリが swap out したので割り当てを増やして(1024MB)やり直したという。。

8. PostgreSQL のインストール

postgresql-9.0.4.tar.gz をダウンロードしてきて解凍後 INSTALL に書かれている以下の手順でインストール。途中 ./configure で readline が見つからず怒られたので readline6-dev をインストールしておきました。


# apt-get install libreadline6-dev

# ./configure
# make
# make install
# adduser postgres
# mkdir /usr/local/pgsql/data
# chown postgres /usr/local/pgsql/data
# su - postgres
# /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
# /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 &
# /usr/local/pgsql/bin/createdb test
# /usr/local/pgsql/bin/psql test


9. PostgreSQL 用アダプタのインストール

gem でインストール。簡単。


# gem install postgres-pr



これで Ruby on Rails + PostgreSQL の環境が作れたはず。おしまい。

追記 on 2011/10/15:

以下も必要っぽいです。

no such file to load -- net/https




# gem install pg -- --with-pg-dir=/usr/local/pgsql/


OAuth で Web API を提供するには

on 2011/10/10 - 0 Comments -

仕事で OAuth に詳しくならないといけなくなったので調べてみた。そのメモ。

実際に実装してみると詳しくなりそうだけど、若干めんどうなので想像だけ。以下な感じで実装すればよいと思われる。参考にしたのはOAuth の仕様書と Facebook の実装。

# 以下、仕様書の言葉に合わせて API を使う Web アプリを Client と呼びます

1. Client ID / Secret Key の実装

Web API を使う Client に ID を振り、同時に Secret Key を生成する機能を実装する。また Web API を利用するサイトの URL も登録できるようにする(リダイレクト処理の確認で使用する)。

1. 登録画面とか DB とか

とりあえず Client ID と Secret Key と Web API を利用する URL を登録できるようにしておけばよいはず。そのへんを適当に。
# Facebook でいうところの Facebook Developers みたいなやつ

2. Authorization の実装

Client が Web API 経由でユーザーにひもづく情報にアクセスすることをユーザーに許可してもらう処理を実装する。

# 例えば Facebook API を使って実装されたある Web アプリが Facebook API 経由で Facebook 上の私たちにひもづく情報、友達や写真、Feed にアクセスする場合、私たちは Web アプリが行うその動作を事前に許可するべきですし、実際許可しているはずです。つまるところそれです。

https://hogehoge.com/oauth のような URI で実装するのがよさそう。あと Client の Secret Key がバレたくないので https 使った方がいいはず。処理の流れはおそらく以下。

1. パラメータの取得

リクエストパラメータとして以下を受け取る。

・許可を与える Client ID
・処理完了時にリダイレクトする URI
・許可する Resource (必要に応じて)

2. ユーザーの認証確認

ログインしていることを確認する。もしログインしていなかったらまずログインしてもらう。ログインしてもらわないと、誰に許可を与えようとしているのかこちらで判断できないので。

3. 許可を与えようとしている Client、Resource の提示

受け取ったパラメータをもとに、許可を与えようとしている Client、Resource をユーザーに提示する。ユーザーはその表示を見て、問題がないようなら OK ボタンを押す(はず)。

なおすでに以下の処理を実施済みだったら、生成済みの Authorization Code と一緒にパラメータとして受け取っていた URI へリダイレクトする(つまりは以下の 4 を飛ばして 5 と 6 を実施する)。

4. 許可情報の保持

OK ボタンが押されてリクエストが飛んできたら、もう一回ログインを確かめて、ユーザー、許可する Client、許可する Resource のひもづけの保持する。またこの許可情報にひもづく Authorization Code を生成してこれも保持しておく。

5. リダイレクト先 URI の確認

パラメータとして受け取ったリダイレクト先の URI が事前にアプリとひも付けて登録しておいてもらった URL と一致することを確認する。Client に任意の URI へのリダイレクトを許すと色々と危ないため。

6. Client へリダイレクト

4. で生成しておいた Authorization Code と一緒に、パラメータとして受け取っていた URI へリダイレクトしてあげる(302 を返す)。

3. Access Token の実装

Web API をたたく際の Credential となるのが Access Token 。それを発行する処理を実装する。

# Access Token の仕組みを使えば Client はユーザーの認証情報(ID/Pass)なしでユーザーにひもづく情報にアクセスできる。つまりは ID/Pass が拡散せず、その分危険性が減ったり管理が煩雑にならなかったりと色々いいことがある。そこがポイント。

https://hogehoge.com/oauth/access_token のような URI で実装するのがよさげ。リクエストを受けて Access Token をレスポンスとして返す仕組み。

1. パラメータの取得

リクエストパラメータとして以下を受け取る。

・Access Token を発行したい Client ID
・その Client ID の Secret Key
・ユーザーが許可済みであることを示す Authorization Code
・処理完了時にリダイレクトする URI

2. Client の認証

Client ID と Secret Key で Client を認証する。この認証で Client が正規に登録されたものであることを確認するとともに、なりすましを防ぐ。

3. 許可状況の確認

Authorization Code が Valid なことを確認する。この確認で Client の Authorization が済んでいない Resource へのアクセスを防ぐ。

4. Access Token の生成

Authorization Code(許可された Resource)とひもづけた AccessToken を発行する。つまりはこの Access Token から許可された Resource が特定できるようになっていればよい、はず。

5. URI の確認

リダイレクトする URL が事前に登録されているものと一致することを確認する。確認が必要な理由は Authorization の時と同じ。

6. Access Token の発行

4. で生成した Access Token をレスポンスとして返す。どんなパラメータを返すべきかは仕様書の 5. Issuing an Access Token を参照。
# 参考として Facebook では Access Token と一緒に有効時間を返しています。

3. API の実装

Credential として Access Token を受け取り、指定された API を実行して結果を返す仕組みを実装する。

1. Access Token の確認

Access Token が発行済のものであること、有効時間内であることを確認する。

2. 許可状況の確認

Access Token から Authorization Code をたどり、さらにそこから許可された Resource の情報を取得し、要求されている API が実行可能かどうかを確認する。許可されていない Resource であれば 400 を返す。

4. API の実行

リクエスト、URI などで渡されたパラメータを元に API を実行する。実行した結果をレスポンスとしてユーザーに返す。
# レスポンスの形式としては XML でも JSON でもよい。ちなみに Facebook は JSON。


と、裏で他にやるべきことが色々とありますが、とりあえずこんな感じで実装しておけば OAuth 対応の Web API を公開できるはず。時間あったら実際に実装してみたいな。以上。

参考:
Facebook Developers - Authentication
The OAuth 2.0 Authorization Protocol

Head Rush Ajax

on 2011/10/09 - 0 Comments -

実は Ajax あんまりよく分かってないなぁということで読んでみた。



内容としては結局のところ Javascript による DOM の操作と非同期通信の2つがメイン。

最初に実際に Ajax アプリを作ってみて、後半で DOM の操作やリクエスト、レスポンスの形式についてブレイクダウンする感じで進む。全部読んだら Ajax の概念やキーワードは一通り押さえられるはず。ただ裏を返せば内容としては入門編なので、ちゃんと分かってちゃんとしたものを作るには他のも読んだ方がいいですね。

あと相変わらずコラムがおもしろい。ブラウザ と HTML が言い争ってたり、JSON が XML にケンカ売ってたり。ブラウザが HTML に「僕がレンダリングしてあげなきゃ君は誰にも相手されない」とか「この無知な括弧まみれ野郎め!」とののしっているのには笑った。

家から皇居(13km)

on 2011/10/08 - 0 Comments -

気温的には昼間の方がちょうどいいかも。
もうすっかり秋ですね。

10月:23km

皇居(10km)

on 2011/10/02 - 0 Comments -

後半気持ちのよいペースで走れた。
あと帰りのチャリでいかにがんばれるかが意外と重要。

10月:10km

iPhone + Facebook でアプリ作ってみました - FAUploader

on 2011/09/27 - 0 Comments -



何のおもしろみもないですが、せっかく作ったので公開します。説明は iTunes のコピペで。

FAUploader @ iTunes

This application makes it easier and faster to upload photos to your facebook albums.

How to use:

1. Select Albums ( once you choose, you can skip this step )
2. Take Photo ( or choose from library )
3. Upload

Features:

1. Easy upload to albums
You can select an album to upload and once you choose an album, you can upload photos to that album continuously.

2. Fast upload
App automatically compresses photos and it enables you to upload faster than facebook native app.

I'd be pleased to get some feedback. Thank you.

incompatible character encodings: ASCII-8BIT and UTF-8

on 2011/09/25 - 1 Comments -

Rails の View での表示の際に incompatible character encodings: ASCII-8BIT and UTF-8 でエラーする件について。

エンコーディングが違う文字列を連結しようとすると発生するそうで、layout を入れ子にしていたりすると発生するとか。解決策としては文字列のエンコーディングをすべて utf-8 にそろえればよいとのことで、以下の通り実装。

ちなみに環境は Ruby 1.9.2 と Rails 3.0.9 です。この組み合わせはクサいらしい。


lib/encoding_patch.rb
module ActiveSupport
  class SafeBuffer < String
    def concat(value)
      if value.html_safe?
        super(value.force_encoding('utf-8'))
      else
        super(ERB::Util.h(value.force_encoding('utf-8')))
      end
    end
    alias << concat
  end
end




config/environment.rb
require 'encoding_patch'



確かにこれでエラーは出なくなりました。

参考:
Ruby1.9+Rails3で"incompatible character encodings: UTF-8 and ASCII-8BIT"の対策
# application.rb じゃなくて environment.rb に書くと思った

div をリンクにする

on 2011/09/20 - 0 Comments -

div に a タグと同じ動きをさせたいことは多々ある。

1.js に以下を追加

div の中の a タグの href 属性を取得して、window をそこに遷移する処理、また hover した時に背景色を帰る処理を追加(後者は必須じゃないけど、この方がカッコイイので)。


my.js
$(function(){
     $(".aDiv").click(function(){
         window.location=$(this).find("a").attr("href");
         return false;
    });
});

$(function(){
    $(".aDiv").hover(
	function(){
	    this.style.backgroundColor = "#f9f9ff";
	},
	function(){
	    this.style.backgroundColor = "white";
	}
    );
});



2.css に以下を追加

div にマウスが重なったらカーソルの見た目をポインタにする。


my.css
.aDiv{ cursor: pointer }



3.html を書く

リンクの動きをさせる div を書く。


my.html
<div class="aDiv">
  <a href="http://some.site.url">SomeSite</a>
</div>



以上。

Ruby on Rails on Heroku + Facebook

on 2011/09/19 - 0 Comments -

Facebook が Heroku と正式に連携したので使ってみたメモ。

アナウンスおよびチュートリアル:
Facebook and Heroku: an even easier way to get started

Heroku では Rails が動くので、Rails で手軽に Facebook App が作れるようになったということですね。

1.Facebook から Heroku にアプリを追加

上のチュートリアルを読めば分かるはず。ポチポチとボタンを押すだけ。

2.Heroku で Rails でアプリを作成する

1で作られるアプリは Pure Ruby なので、自分で作った Rails アプリに入れ替える。とりあえず Facebook のことは考えず、以下の手順をもとに Heroku で Rails のアプリが動くところまで進める。

Getting Started with Heroku
Getting started with Rails 3.0 on Heroku/Cedar

* Heroku では PostgreSQL を使うので開発環境にも必要かも
* バージョンは Ruby が 1.9.2 、Rails が 3.0.9 でした

3.Facebook と連携

Rails が動くようになったら、Facebook が自動で作ってくれたものと入れ替え。
以下あたりを参考に。

Building a Facebook Application With Ruby
Getting Started with Your Facebook App on Heroku
Herokuで作るFacebookアプリ

皇居(10km)

on 2011/09/18 - 0 Comments -

久々の皇居。
秋の気配は感じられなかった。

9月:22km

家の周り(4km)

on 2011/09/17 - 0 Comments -

お墓の周辺が最近のジョギングコースです。

9月:12km

Being Geek

これからのキャリアとわりと重なる気がして読んでみました。



サブタイトルが「ギークであり続けるためのキャリア戦略」とあり、会社での立ち振る舞い方や上司との付き合い方、会社を移る時の話など、ある意味で真っ当にキャリアを形成していくために必要な Tips が満載です。また内容的にも意外と一般的なものが多く、ギークでなくても気付かされる点は多々あると思いました。

個人的に印象に残ったのは23章の「ナード」ハンドブックのところで、特に「ナード」を理解するというセクションでは自分のことをありのまま書かれているような気がしてかなりドキッとしました。恥ずかしいので知り合いの方は読まないでください。笑

筆者の経験をもとに実用的なノウハウがユーモアを交えて書いてあり、自分のなかにスッと入ってきます。定期的に読み返したい本の1つです。

補足:ギークについては以下参照のこと。
http://ja.wikipedia.org/wiki/ギーク

大規模サービス技術入門

on 2011/09/16 - 0 Comments -

nifty で「ココログ」を作り、はてなで「はてなブックマーク」を作り CTO をやっていた伊藤さんの本。これから僕も大規模サービスやるので今更ながら読んでみました。



自分なりにざっくりと内容をまとめると、以下でしょうか。

1.ユーザー・情報が膨大となった時、単にスケールするだけはでなく、仕組み自体を変えないといけない

2.その時考えるべきは、キャッシュ、データ構造、アルゴリズムの3つ

せっかくなので簡単にこの2つについて書きます。


1.ユーザー・情報が膨大となった時、単にスケールするだけはでなく、仕組み自体を変えないといけない

データベースについての話が一番おもしろかったのでここで取り上げます。

ご存知の通りデータベースには様々な情報を格納することができますが、様々な制限から無限に情報を格納できるわけではなくて、必ず限界があります。扱う情報が膨大となり、その限界を超えてしまうことは容易に想像できます。その時どうするかという話です。

現状よくやられる対応として、情報を分割して複数のデータベースに分けて格納するというものがあります。例えば 100 しか入らないデータベースに 10,000 を入れたければ、情報を 100 ずつ 100 個に分割して、100 のデータベースに分けて格納する感じです。当然分割には規則があり、欲しい情報がどのデータベースにあるかは分かるようになっています。

発想としてはわりと単純ですが、データベースを複数台用意するコスト、複数台から目的の情報を持ったデータベースを選択するコストがわりと小さいので、現状とても現実的な方法と言えます。

# しかしながらやっぱりそれ面倒くさいよってことで、次世代のデータストアとしてその辺よしなにやってくれる Cassandra などが注目されているようです。(補足1)


2.その時考えるべきは、キャッシュ、データ構造、アルゴリズムの3つ

キャッシュ、データ構造、アルゴリズムと書きましたが、結局のところ、データへのアクセス速度をできる限り上げて、計算量をできる限り減らそうということです。

キャッシュが重要というのは、メモリからの読み出し速度がハードディスクと比べて  10 万から 100 万倍速いためです。ほしい情報ができるだけメモリから読み出せれば、それだけでかなり高速化できるということです。僕も昔これで 3h の処理が ~10s になりました。使いそうな情報はできるだけメモリに乗せちゃいましょう。

memcached とかまさにこの仕組みで、キャッシュからの読み出しで高速に動作し、大量のリクエストをさばきます。Facebook, Twitter も使っているやらいないやら。(補足2)

データ構造とアルゴリズムですが、n^2 のオーダーには気をつけましょう、インデックス張りましょうというよくある話です。基本的な事項ですが無視すると大変なことになるのでとても重要ですね。

最後に

大規模サービスとかその辺の話はノウハウベースの色が強くて、正直やってみないと分からないと思ってましたが、この本を読んで大分イメージが湧きました。また大規模なサービスに関係ない人もキャッシュの話は一般論としてとても大切だと思うので読んでおいて損はないかと思いました。

以上。
# あーなんかすげー長くなってしまった。。

補足1:
Cassandra実践入門―Twitter,Facebookが採用するNoSQLシステム
TwitterとDiggがNoSQLの「Cassandra」を選ぶ理由

補足2(ちょい古い):
Twitterの大規模システム運用技術、あるいはクジラの腹の中(後編)
Facebookが大規模スケーラビリティへの挑戦で学んだこと(後編)


Facebook 認証で期限切れ accessToken が取得される件

on 2011/09/13 - 2 Comments -

iOS での Facebook 連携の際 accessToken がうまく取得できない問題がありました。

1.事象

認証の際に期限切れの accessToken が取得される。

もう少し詳しく書くと、FBAppAuth という Safari で Facebook のページを開かずに API から直接リクエストを出す方式で認証する場合に発生しました。なぜか3日前に期限の切れた accessToken が取得されるという謎。。

2.回避策

以下の通り Facebook.m を編集して、強制的に Safari での認証方式をとるようにしました。

(認証が必要な時には Safari がアクティブになり、認証後にディアクティブになるという動作になります。)


Facebook.m
- (void)authorize:(NSArray *)permissions
       localAppId:(NSString *)localAppId {
  self.localAppId = localAppId;
  self.permissions = permissions;

//    [self authorizeWithFBAppAuth:YES safariAuth:YES];
    [self authorizeWithFBAppAuth:NO safariAuth:YES];
}



なお通常は FBAppAuth が YES となっていて、アプリをインストールした iPhone が対応していれば(*)FBAppAuth を使って認証を行うようになっています。

* バージョンが 3.4.1 以上の Facebook App がインストールされている場合だそうです

3.補足

Facebook との連携では isSessionValid で Session が有効か判断しますが、判断基準は結局のところ、Facebook インスタンス内に保持している「期限切れ時刻」と「現在時刻」の比較でした。
# accessToken が nil じゃないか、なども確認していますが


Facebook.m

- (BOOL)isSessionValid {
  return (self.accessToken != nil && self.expirationDate != nil
           && NSOrderedDescending == [self.expirationDate compare:[NSDate date]]);

}



感覚的には isSessionValid は accessToken が期限切れでなく、ちゃんと使えることを担保してくれていてほしいのですが、実はそんなことはありませんでした、ということになります。

またここで注目するべきは、「期限切れ時刻」があと何秒間 accessToken が有効かという情報をもとにクライアント側で計算されたものということです。厳密には accessToken と結びついてはいません。

具体的には accessToken 取得時に一緒に受け取る expires_in という秒数を、accessToken 取得時の時刻に足したものが「期限切れ時刻」になっています。

ソースを見ると早いですが、expires_in を引数にした dateWithTimeIntervalSinceNow: で現在時刻からの時刻を取得しています。


Facebook.m
- (BOOL)handleOpenURL:(NSURL *)url {
...
NSString *expTime = [params valueForKey:@"expires_in"];
NSDate *expirationDate = [NSDate distantFuture];
if (expTime != nil) {
  int expVal = [expTime intValue];
  if (expVal != 0) {
    expirationDate = [NSDate dateWithTimeIntervalSinceNow:expVal];
  }
}
...



なので、isSessionValid が YES だったとしても、accessToken の期限が切れていないことは必ずしも保証されません。
# Facebook 側ではちゃんと返す実装になっていると思いますが。

実際、今回の事象では「期限切れ時刻」的には OK である accessToken を http://developers.facebook.com/tools/explorer/ で確認してみると、以下のメッセージが表示されてエラーとなりました。


OAuthException: Error validating access token: Session has expired at unix time xxx. The current unix time is yyy.



原因はまだちゃんと分かっていませんが、以前取得した accessToken と全く同じものを取得しているようなので、なんとなくキャッシュされてるんじゃないか、もしくは全く同じリクエストが飛んでいるんじゃないかと思ってます。Facebook.m か FBRequest.m あたりをちゃんと見たら分かりそうです。

と長々書きましたが、とりあえず FBAppAuth を NO にして、SafariAuth をYES にしておけば、Safari で問題なく認証してくれるので、取り急ぎこの期限切れの accessToken が取得される問題は回避できるようです。

以上。

家周辺(4km)

on 2011/09/11 - 0 Comments -

体が信じられないくらい重かった。
寝起きだったからと信じたい。

9月:8km

家周辺(4km)

on 2011/09/04 - 0 Comments -

引っ越してから初。
コース開拓をもくろみつつ軽くジョグ。

9月:4km

大森周辺(7km)

on 2011/07/24 - 0 Comments -

夕方は涼しくて走りやすいね。

7月:37km

大森周辺(7km)

on 2011/07/23 - 0 Comments -

何かの隣をすれすれに走るとスピード感じられてよい。

7月:30km

大森周辺(5km)

on 2011/07/10 - 2 Comments -

暑過ぎたがひからびなかった。
しかしこの季節、夕方走ってからの、夕暮れ時のビールが最高過ぎる。

7月:23km

大森周辺(7km)

on 2011/07/06 - 0 Comments -

スピードが全く出ないので、ひたすらフォームを意識。

7月:17km

皇居(10km)

on 2011/07/02 - 0 Comments -

中学高校の夏の部活を思い出す暑さでした。

7月:10km

フェイスブック 若き天才の野望

on 2011/06/05 - 0 Comments -

Facebook 創設者 CEO のマーク・ザッカーバーグを始め、
その周辺の当事者たちに直接取材して書かれたリアルな一冊。

基本的に時系列のストーリー調で書かれているのでとても読みやすく、
ポイントになる出来事については深い洞察・当事者の心境がうまく描写されていて、
Facebook を中心として Web を取り巻く環境がどう変遷してきたかを理解するにも
とてもよい本だと思いました。

また個人的に特に印象に残ったのは以下な感じです。

・シリコンバレーでのスタートアップ企業の雰囲気
・Facebook もといマーク・ザッカーバーグの理念・思想
・Google など既存の広告収益モデルとの比較とその優位性

個人的には「ウェブ進化論」に続くヒットでした。(結構古いね。。

ウェブ進化論 本当の大変化はこれから始まる (ちくま新書)

ちなみに映画「ソーシャル・ネットワーク」はかなり脚色というかほぼフィクションですが、
事前に見ておくと読みながら映像がフラッシュバックしたりして雰囲気がより伝わります。
おすすめ。

大井埠頭(7km)

on 2011/05/08 - 0 Comments -

軽めにさらりと。

夕暮れが水辺に移り込む様子がとてもきれいでした。

5月:52km

東京マラソン後半っぽいコース(30km)

on 2011/05/05 - 0 Comments -

遠足的な感じで走りました。

銀座、汐留、レインボーブリッジ、お台場、有明、築地、浅草、銀座、な感じ。
なんだかんだで5時間くらい走ってました。

色々まわれて楽しかったですし、
LSD としても文句なしの内容でした。

5月:45km

特攻野郎Aチーム THE MOVIE

on 2011/05/04 - 0 Comments -

キャッチコピーは『デカいこと、ヤローぜ』、『一人でも最強。チームなら無敵』。

アクション系なので気軽に楽しめますね。

個人的には B.A. の愛すべきキャラが好き。
非暴力に改心した時には笑ったw

戦車で落ちていくシーンあたりが個人的にはクライマックス。
その後はなんかしりすぼみな感じ。

マイライフ・アズ・ア・ドッグ

on 2011/05/03 - 0 Comments -

TSUTAYA でフィーチャーされていたので、という単純な理由でチョイス。

「スプートニクに乗って、宇宙に飛ばされたライカ犬のことを思えば、僕の不幸なんてちっぽけなモノだ。」
そんなある意味達観した考えを持つ少年の物語。

少々のユーモアを交えながらわりと淡々と月日を描いている感じだけど、
少年のまっすぐな思いと成長がじんわりと伝わってくる。
自分たちにもこんな時代があったかね。
あと大人は自分勝手だと思っていたことを思い出した。

最後みんな笑ってるのがいいですね。

皇居(15km)

皇居3周。

22'00, 21,40, 22'40

意外と走れている?

以下課題。

・スピードを上げると軸がぶれる。
・バネがない。ひと蹴りの推進力がへぼい。

筋トレ&瞬発系トレーニングも必要ですね。
腹筋背筋再開必要?

5月:15km

皇居(15km)

on 2011/04/30 - 0 Comments -

前回に続き15km。

22'50、22'30、23'50

まぁこんなもん。
明日も走るよ!

4月:44km

皇居(15km)

on 2011/04/24 - 0 Comments -

足がつったがなんとか3周した。
この調子で GW は強化週間としよう。

4月:29km

前へ! 前へ! 前へ!

1人の大学生がバングラディッシュで起こした奇跡。

彼の熱意というか、ひたすらに前へ進まんとする姿勢にはもちろん、
あきらめていた彼らの意識を変え、人生をも変えていく過程にただただ感動。

本気とはまさにこういうことを言うのでしょう。
しかも本気のなかの本気。
ちょっとだけ本気を分けてもらった気がする。

TED - スティーヴン・カウリー:未来エネルギーの核融合

on 2011/04/10 - 0 Comments -

原発に関連して核融合について。

2030年代には実現っていうのが、
何を根拠に言っているのかが気になるところ。
死ぬまでにはお目にかかりたいものです。

TED -「ゼロへのイノベーション」ビル=ゲイツ、エネルギーについて語る。

on 2011/04/09 - 0 Comments -

最近の原発に関する議論に関連して。

エネルギー問題は思っているより深刻だと思う。
温暖化の問題もあり期限が決まっているとすると、
現実的に考えて折り合いをつけることになるのかもしれない。

大森周辺(7km)

いつもの通り埋め立て地を走っていたのですが、
ふと津波来たら逃げるとこないじゃん、って思いました。

4月:14km

Head First Rails

Web サイトを効率よく作る事のできる Ruby on Rails の本。

分類するとすれば技術書ではありますが、一般的な味気ない文字の羅列ではなく、
様々な登場人物がいたり、絵やコメントが多数あったりと、ストーリーがあって楽しめる内容。

内容的にも基本から簡単な応用までを分かりやすく解説していると思う。
大体こんなものかくらいを知りたいのであれば、まさにぴったりの本ですね。

大森周辺(7km)

on 2011/04/02 - 0 Comments -

春の陽気のなか。
気持ちよかったです。

しかし自分のなかで速く走る事が目標でなくなりつつあることに気が付いた。
これはまずい。

4月:7km

皇居(10km)

on 2011/03/19 - 0 Comments -

春の空気を満喫。
そろそろコンスタントに走っていこう。

3月:10km

Tourist

とにかくおしゃれ。

舞台となったヴェネツィアもそう、
あまりにエレガントなアンジェリーナ・ジョリーもそう、
イケてない旅行者役だけどイケちゃってるジョニー・デップもそう。

クライマックスでの帰結がとても美しいです。
個人的には大満足でした。

cron の設定で注意するべき3つのこと

on 2011/03/18 - 0 Comments -

先日立てた地震のサイトはさくらインターネットを使ってるんだけど、
cron の設定がうまくいかず情報の更新が相当いけてないことになっていた。。

よくよく調べてみると以下が原因でした。

1:PATH の設定が不正
2:LANG の設定が不正
3:パスが不正

1は要は cron が実行する時の環境変数 PATH が自分で実行する際の PATH と違う。
ちなみに cron が持ってる PATH は /usr/bin:/bin のみでした。
/usr/local/bin とかないです。

実行するスクリプトの先頭に以下な感じで書きましょう。


export PATH=/usr/local/bin:/usr/local/java/bin:${PATH}


2はこれを設定していないと日本語の処理で不具合が生じます。
今回の場合は正規表現で日本語を引っ掛けていたのですがそれが機能していませんでした。

ということでスクリプトの先頭に以下を追記。


export LANG=ja_JP.UTF-8



3はスクリプト内で参照しているパスを絶対パスで書きましょうという話。
それかスクリプトの先頭で cd で所定のパスに移動するか、どちらか。

この3つを確認したところちゃんと動くようになりました。
結局どれも基本的なことでした。。

あとさくらインターネットでは普通に cron を設定するとエラー出力が見れないので、
確認したい場合は以下な感じで標準エラーをどこかに吐いてやるとよさげ。


/home/hoge/cron.sh 2> /home/hoge/err.log



ご参考までに。

地震の発生件数まとめサイト(その2)

on 2011/03/16 - 0 Comments -

最近50件の地震について最近のものほど赤い色でのプロットする図を追加してみた。

http://masayuki0812.com/eq/

広い範囲で地震が続いている。
まだまだ予断を許しません。

今は節電して、募金して、ダイエットするのみ。

地震の発生件数まとめサイト

on 2011/03/13 - 0 Comments -

地震の発生件数のまとめサイト作ってみた。
これで落ち着いてきたかどうかが分かりやすくなるはず。

http://masayuki0812.com/eq/

落ち着いてきたかと思ったけど、まだまだ余震は続いていますね。
被災された方の無事をただただ祈るばかりです。

タイ1人旅(7日目)

on 2011/02/25 - 0 Comments -

ついに最終日。

流れている時間はゆっくりなのに、
過ぎていく時間はあっという間。
なんてこった。

いつも通り7時に起床。
朝日と鳥のさえずり、そして心地よい目覚め。

お昼過ぎには出発しなければいけないのだけど、
先日のツーリングが気持ち良過ぎたので、
最後にもう一度原チャでふらふらすることに。

さくらさんで原チャを借りて、アオナンビーチ方面へ向けて出発〜


※ 楽しそうと思ってしまった

何も考えず、気の赴くままに。








※ 死んだように寝てるとはまさにこのこと。しかし最後まで動かなかったらほんとに死んでたかも。

気がついたら3時間くらいふらふらしてた。

チェックアウトの時間なので宿に戻る。
しかし、おばちゃんは用があったらしく、誰もいない。。
とりあえずメモ書きを残してセルフチェックアウト。
お世話になりましたと一言いいたかったなぁ。

飛行機にはまだまだ時間があったのでおみやげを見て回ることに。
お目当ては「原始人の木彫り」だったんだけど、売ってない。


※ これがほしかったです。多くの人にたぶん分かってもらえないと思いますが。

仏像とか像はいっぱいあるんだけどね。結局見つけられず。残念。
あきらめてクラビ川のほとりで出発まで時間をつぶすことに。


※ 夜になると屋台でにぎわいます

しばらくぼーっとしていると、遠くで手を振っている人たちが。
どんどん近づいてくる。どうやら自分に手を振っているらしい。

目の前まで来た。来るもの拒まず。こんにちは。

話してみるとマレーシアの大学生で、大学の課題で旅人にインタビューしているらしい。
そしてなんと自分もインタビューされることになりました。そういうことか。

主に聞かれた事は

・今何してる人ですか?

 → 学生ですか?と最初に聞かれました。一応社会人です。

・タイを選んだ理由はなんですか?

 → 比較的近い、気候がよい、物価が安い、ご飯がおいしい、をあげました。
  マレーシアもいいですよ!とおすすめされた。今度行ってみます。

・(サバイブするために)どんなものを持ってきましたか?

 → ライターとかナイフとか持っていますか?って聞かれました。
   すいません、そこまでチャレンジングな旅してないです。。
   iPhone とお金があればなんとかなるよ、と答えました。

・この旅で何を学びましたか?

 → 全くなじみのない環境に身をおくことの大切さ。
   いろんな感覚が研ぎすまされるし、日常では得ることができない気付きを得ることができる。
   やっぱり外に出てみないと分からないことはあります。
   身を以て知るというか、中にいては本当の意味でのそういうのは無理。


覚えているのはそんなくらいか。
わりと雑談ベースで楽しかったなぁ。ちなみに話したのは、

・やっとアジアンに会えたよ!

 → 確かにクラビは欧米人だらけ。顔をしかめていたので嫌悪感あり?
   どうもなかなかインタビューに応じてもらえないっぽい。がんばれ。

・あなた英語うまいわね

 → 自分レベルでそう言われるところをみると、やはり日本人は英語しゃべれないイメージですね。
   ちなみに彼らはペラペラというかネイティブでした。まぁ公用語だったらそうですよね。
   ただタイじゃ英語が通じない><って言ってて、そこの気持ちは共有できたw

・今度東京に行くよ

 → GW あたりに行くと言っていたが、この状況だとたぶん中止かね。
   連絡くれれば案内しますよ、と伝えておいた。

・Facebook

 → 連絡先の話になったらアカウント持ってる?って聞かれた。
   この場面もう何回目だろう。やはり海外の人にとってはもう常識なんですね。
   アカウントだけでも作っておく価値あるかもね。


時間も時間になってきたので、さようなら。
若さなのか国民性なのかとてもエネルギッシュで、自分もがんばらねばと切に思いました。
この旅を振り返るきっかけももらえたし、感謝です。ありがとう。

空港へ向かう時間。
バイタクで空港へ。15分くらい。

チェックインも問題なく、しばらくロビーで待って、いざバンコクへ。


※ AirAsia でした。不満は特になく。安いし、おすすめ。バンコクまで 1.5 時間。

バンコクに到着。

そこそこ時間があったのでご飯を食べに市街へ。
ショッピングセンター地下のフードコートへ。


※ とろとろのお肉が乗ったやつ。180円くらい。


※ タイスキ的な。250円くらいだったっけ?

何度も言うけど、ご飯がめっちゃうまい!

ご飯食べた後は適当にふらふらして、空港へ戻る。
あとはいつも通り日本へ向けてテイクオフ。

こんな感じでタイ一人旅は終わりましたとさ。

タイ1人旅(6日目)

on 2011/02/24 - 0 Comments -

タイ旅行6日目。

この日は予約していたツアーでピピ島へ。
朝7時くらいに起きて、宿の前で8時のお迎えを待つ。

ちょっと時間過ぎたくらいで、タイ人のおにーちゃん登場。
チケット的なものを渡して車へ乗り込む。

BGM はバリバリのタイポップ!
独特のリズム感と音色で結構いい感じかも。
朝からテンション上がりました。

20分くらいでアオナンビーチについて船を待つ。
ここで待ってろ言われて待ってたけど、すごい人。
みんなピピ島行くの...?


※ これには乗りたくないと思ってみてた...

しばらくしたらビーチに誘導される。
そこからわりと小型のクルーザーで出発。

メンバーはガイド数人とテンション高めの韓国人たちと日本のおっちゃんとおねえさんコンビ。
なかなかスゴい組み合わせ。よろしく!

ツアー的にはピピ島の周辺でシュノーケリングしたり、
ビーチに上陸して散策したりという感じ。

マヤ・ベイというビーチが最高にきれいでした。
The Beach の舞台にもなったビーチ。
確かに映画の中と一緒ですばらしい景色だった。


※ 断崖がいい味出してる


※ しかし右を向けば観光客でいっぱい。興ざめ...


※ 海ももちろんきれいだけど、やっぱりこの断崖が好きだな

そんな感じで何カ所か回って、ご飯食べて、帰港。

途中海ツバメの巣の洞窟についてガイドさんと話した。
解説によると、警備員は銃を持ってて、不用意に入ると殺されるよって言ってた。
# 正確には They can kill you って言ってた
can ってどういうこと?許可してんの誰?そもそもあの洞窟誰のもの?とか質問攻めにしたところ、
洞窟は政府のもので、一番高いお金を払った人にツバメの巣を取ることが許可されるとのこと。
侵入者にそこまで許可されてないけど、警察に賄賂を渡せばなかったことになるらしい。
そういう社会もあるよねー。


※ 実際何人か侵入を試みてそんなことになっているらしい。そして中はかなり広いらしい。

アオナンビーチに戻ってきた。
車で宿まで送ってもらう。

まだまだ夕ご飯まで時間があったので、
町をふらついてみた。


※ 町の中心にある市場。夜になると結構にぎわう。


※ 果物とか野菜とかが多かったです。


※ みんなバイクで来るんですよね。バイタクがかなりポピュラー。

通称”原始人交差点”。


※ 木彫りとか買おうとしたけど、意外とフューチャーされてなかった。なんで?

まだまだ時間があったのでタイマッサージへ。
実は日焼けが酷過ぎたので、アロエベラ?オプションで沈静化を試みた。

アロエベラ自体はスゴくよく効いたのだけど、
日焼けが痛過ぎてマッサージはほとんどやってもらいませんでした。無念。

そして店員のおばちゃんが妙に日本語うまいと思ったら昔日本に住んでたとのこと。
どこに住んでたん?って聞いたらなんと新潟だった!同郷!
今日本寒いでしょう?雪降った?とか聞かれ、そこはもう日本でした。

その後さくらさんにツアーの報告して、夜ご飯へ。
屋台村的なのがあったので、そこで食べることにしました。


※ カレー的なやつ


※ ソフトシェルクラブの炒めたやつ(なんかヤバそうな風味がしたような...)


※ トムヤンクン。辛いというよりすっぱかった。

ここの店員のお兄ちゃんのテキパキと堂々とした働きぶりに感銘を受ける。
アジアやっぱりエネルギーが違う。こちらまで元気になる。
日本にはこのエネルギーはない。まぁ文化の違いか。

二次会は生演奏やってるお客さんのいないオープンカフェに入る。
ビール飲みながらボーッと聞いてみた。Let it be が十八番らしい。
ギャラリーは他の店員とその友達。演奏が終わるとみんなで拍手。和んだ。

よい時間になったので、宿に戻って就寝。
明日はいよいよ帰国の途につきます。

タイ1人旅(5日目)

on 2011/02/23 - 0 Comments -

朝、空が明るくなるとともに起床。

町はまだ活動を始めていなくて、いたって静か。
通りを挟んで向こう側の家では朝ご飯の準備をしている。

クラビには多くの観光客が滞在しているけど、地元の暮らしも確かにそこにある。
変に観光地化されておらず、そんなところがとても魅力的。

チョロチョロの水シャワーを浴びて1日がスタート。

この日は原チャを借りてちょっと遠出することにした。
温泉&プール@ジャングルが目的地。
移動距離はざっと100kmは超えそう。

準備を整え、いざ出発。

宿を出ると、すぐ近くの「さくらツアー」さんの前でおねえさんが掃除をしている。
ツアーについても聞きたかったので、ちょっと声をかけてみる。
ちなみにこのさくらツアーさんは日本人が経営しているので日本語た通じます。

※さくらツアーさん
http://sakurakrabitour.hotels.officelive.com/default.aspx#NEW

聞いたところツアーは明日であれば全然OK、原チャもここで借りれますよ、ということでした。

とりあえずピピ島へ行くツアーを予約してみた。すっごいきれいですよ、とのこと。
あと原チャもここで借りることに。ガソリン空っぽだからまずガソリンいれてくれとのこと。

原チャをゲットし、早速出発といきたいとことだが、実は原チャに乗ったことないので試し乗り。
エンジンどうやってかけるんだっけ?とか、アクセルはどれで、ブレーキはどれだ?とかやってたら、おねえさんが教えてくれた。
久しぶりかな?忘れちゃうよね。って言われたけど、すいません、初めて乗ります!

大体覚えたところで出発。

走ってみると結構スムーズ。わりと簡単なのね。
ガソリンを入れて、それっぽい方向へ向けて走る。

清々しい空気の中、気ままに目的地を目指す。
この旅で最高の癒しの瞬間だったかも。気持ち良すぎ。


○ 午前中は涼しくて最高に気持ちいいですよ

大きめの道路に出て1時間くらい走ると、1つ目の目的地に到着。
ジャングルの中に天然の温泉があります。


○ あたり一帯にモワァっとした空気が漂っていた

200M 遊歩道を歩くと到着です。


○ 人が入るのにちょうどいい形にえぐれておりました。

天然の露天風呂とはまさにこのことですね。
湯加減もぬるめでとても気持ちよかったです。

観光客が大量に押し寄せてきたので10分で退散。次へ。

次はジャングルにある天然のプールです。
温泉からとても近いところにあります。


○ 国立公園?らしく、入り口で入園料を払いました。

こんな感じのところを10分くらい歩くと、こんな感じの池がありました。



水面の独特な水色が周りのジャングルな雰囲気と相まって、とても幻想的な空間でした。
エメラルドプール、クリスタルプールと呼ばれるだけあります。一度は行くべき。

水温も適度で、深さも胸までくらい。
みんなぷかぷか浮いたり、飛び込んだ入り、思い思いに楽しんでいました。

自分は反対側まで泳いで、しばらくぷかぷか。
特に何をするわけでもないこの瞬間に相当な癒しを感じました。

お腹も空いたところで移動開始。
タウン方面へ向けて来た道を戻る。




○ 温泉とプールの近くはとてものどかな道なりでした

次はタイガーケイブテンプル。
ここは昔お坊さんが修行したところで、
修行中にケイブに虎が入って来たが無事だった、というのが名の由来のようです。


○ お坊さんとタイガー。タイガーかわいい。

しかしこの寺院、山の頂上にありまして、階段を1300段上る必要があります。
これ相当しんどくて、一緒に上り始めた人たちはみんな途中で下りてしまいました。


○ クラビタウン方面


○ 厳かな空気が流れておりました


○ お坊さん方もいらっしゃってました


○ ここでも発見!しかし気を取られて大仏撮るの忘れた。

お坊さん達と一緒にしばし物思いにふけった後、下界へ。
1300段の階段を下る。途中ですれ違う人、みんなゼーハーいってる。がんばれ!

次はアオナンビーチと呼ばれるクラビで有名なビーチへ。
ちょっと距離があるのでちょっとしたツーリング。


○ 奇岩と呼ばれるこんな岩が至る所にあった。幻想的。

ぼーっと運転しているとどうも道に迷ったらしい。
プーケット190kmとか標識に書いてある。ここどこ?

とりあえず来た道を戻るんだけど、車体が妙にグラグラ。
この感覚はチャリンコでも味わったことがある。そう、パンクです。
道に迷った挙げ句にパンクとはなかなか面白くなってきたね。

後ろタイヤがペチャンコ。
走れんことはないけど、ちょっと危ないね。

そういえばさっきガソスタ見かけたな、ということでそこへ。
タイヤを指差してみると分かってくれたみたい。ボディーランゲージすら必要なかった。

どうも近くに修理屋さんがあるらしく、そこへ行けと。
通りに出てみたら50m先くらいだった。近い。
ガソスタの店員さんと一緒にその家へ向かう。

行ってみると小さい子供が2人でテレビ見てますが。。

ガソスタの店員さんがお父さんどこ?的なことを聞いていると、#たぶんね
裏からお父さんが超笑顔で出てきた。いい人そう..

バイクを見せたら分かってくれたみたいで、すぐに修理開始。


○ 見た目で不安にはなりましたが、仕事はまさにプロでした。


○ おっちゃん、がんばれ!

アツアツになったタイヤに苦戦しながらも15分くらいで完了。
意外とすんなり直るものなんですね。

料金の150バーツ(500円くらい)を払い、お礼を言って出発。
別れ際に笑顔で手を振ってくれたおっちゃん。最高!

しばらく来た道を戻り、曲がるべき交差点を見つけ右折。
これでアオナンビーチへ行けるはず。

10分くらい走るとビーチへ到着。


○ 夕暮れ時。お散歩している人が多かった。

マリンスポーツの類いが禁止されているだけあって静か。
観光客向けの商売もアグレッシブじゃないし、なんか落ち着いた雰囲気。

ちょっとゆっくりして、帰路へ。
ビーチ沿いの道を通ることに。


○ ビーチ沿いはのんびりした印象。タクシーやお店の客引きがいないからでしょうか。


○ 繁華街の地域もある。しかしやっぱりのんびりだなぁ。


○ すっかり暗くなってしまいました。

こんな感じでさくらツアーさんに戻って原チャを返却。
おかえりなさいと言ってくれたのがなんだか妙にうれしかった。
それにしても結構走りましたね、とおねえさん。確かに。

原チャでこんな走るやつはあんまりいないと言っていたが、
クラビにはそれだけの価値はあると思います。
特にタウンからアオナンビーチ方面へ抜ける道は
奇岩の間を縫って走る感じで迫力があり、ツーリングにはもってこい。

その後夕ご飯へ。
おねえさんが市場のマサマンカレーがおいしいよと行っていたので行ってみることに。
イスラム系のお店。タイ系とはまた違った料理が並んでいる。

おっちゃんにマサマンカレー!と言うと分かってくれたようです。
料理的には大根と鶏肉のカレーですね。そしてちょっと甘みがある。
タイ料理とはまた違ったテイストで、うーん、美味。

さくっと食べ終わったものの、お腹が全然満たされないので2軒目へ。
ビールとトムヤンクンとエビの唐辛子炒めを注文。
唐辛子炒めが相当辛くて汗だくになったが、味としては美味。
タイではどこにいってもご飯がうまいなぁ。そして安い。

その後はさらりとホテルに戻り、水シャワー浴びて就寝。
深夜、招かざるルームメイトに起こされはしたものの、朝までぐっすり眠れましたとさ。

※ ちなみにルームメイトは、僕を起こした後ベッドの下の自分の寝床へカサカサと消えていきましたとさ...