星期五, 4月 29, 2011

用 memcached 實做 mutex lock

本來想在 CPAN 裡面找 Paxos,不過連個影子都沒有 XD

後來放棄 distributed lock,透過 memcachedadd 所提供的 atomic 特性提供很簡單的 mutex,方法在「A simple distributed lock with memcached」有提到,不過這篇文章的標題所提到的 distributed lock 並不太正確,只是普通的 lock...

先暫時這樣,繼續往下寫...

星期四, 4月 28, 2011

公司內部的 AWS 交流分享

下午公司內 jnlin 在介紹 AWS 給技術部門同事:



結果講到 S3 的時候發現某個 bucket name 居然沒被註冊掉 XDDD



Anyway...

星期二, 4月 26, 2011

AWS 台北的聚會...

本文轉自「AWS 台北的聚會…」。

AWS 亞太區的窗口要來台灣,本來是計畫找城邦集團內的人一起聊聊,後來跟 jnlin 提議,直接拉到社群層面辦,讓更多人跳下去用... (而且「前幾天的事情」大家應該會想要找人聊聊?XD)

飲料的部份由敝公司 PIXNET 準備,歡迎來交流。註冊的資訊在:「Amazon Web Service 台北開發者聚會」。

星期日, 4月 24, 2011

在 Coro 內應該用 join 而非 condvar,除非有特別的理由...

AnyEvent 提供的 condvar 當然是沒問題,不過用 Coro 的 join 會更適合。

用法像是這樣:
my @coros;
push @coros, async {
    # ...
};

foreach (@coros) {
    $_->join;
}
這樣可以避免 async 內發生錯誤時沒有更新 condvar 而造成停住...

星期四, 4月 21, 2011

用 Zerigo 的 GeoDNS 服務

之前是自己用 Net::DNS 寫一個,針對來詢問 domain 的 DNS server IP address 查詢地區,然後依照地區決定傳回值,但畢竟自己維護起來總是有個人事成本在,所以一直在看有沒有價錢合理的 solution 可以用。

退伍後在奇怪的地方看到 Zerigo 有推出 GeoDNS 的服務 (還蠻新的,今年二月才推出),價錢還算合理,以功能看起來應該沒問題,就丟給 jnlin 去測試,然後丟合約給法務單位審。剛剛 jnlin 丟出一篇文章稍微提一下:「Zerigo 的 GeoDNS 服務…」。

像是放靜態資料的 s.pixfs.net 就已經丟上去,以台灣查詢的話,傳回的結果會是台灣固網的 server:

;; ANSWER SECTION:
s.pixfs.net. 7009 IN CNAME s.pixfs.net.geo.pixdns.tw.
s.pixfs.net.geo.pixdns.tw. 86210 IN A 60.199.247.98


Linode 的機器查,會指到 CDNetworks 的 CDN 伺服器:

;; ANSWER SECTION:
s.pixfs.net.geo.pixdns.tw. 86400 IN CNAME s.pixfs.net.cdngc.net.
s.pixfs.net.cdngc.net. 30 IN A 66.114.54.30
s.pixfs.net.cdngc.net. 30 IN A 66.114.54.35


據 jnlin 講,美國還可以拆三個區域設定,如果是這樣的話還可以租一堆 Linode 機器來跑 cache server,有機會再來研究看看...

用 AnyEvent、Coro 與 Net::Amazon::S3,同步抓取 S3 的資料...

這幾天用 AWS S3 用的不亦樂乎,為了加快程式執行速度,發現需要不少「撇步」解決,寫下來讓之後接手的人比較容易上手...

首先是 Net::Amazon::S3,用法沒什麼問題,寫成某個 module 的 function:(這邊不太處理發生錯誤的情況,請自己 eval{} 下去處理...)
sub get {
    my $self = shift;

    # S3 的 filename
    my $key = shift;

    my $bucket = $self->s3->new(
        aws_access_key_id => 'xxx',
        aws_secret_access_key => 'xxx',
        retry => 1,
        timeout => 10, # 預設 timeout 30 秒
    );

    my $r = $bucket->get_key($key);

    return $r->{value};
}
接下來用 Coroasync{} 開平行處理:
use Coro;
sub {
    foreach my $key (@allKeys) {
        async {
            my $data = $self->get($key);

            # 這邊是對 $data 處理的 code
        };
    };
}
但你有時候會需要等所有的 async{} 都跑完再處理剩下的事情,這時候就要拿 AnyEvent 的 condvar:
use AnyEvent;
use Coro;
sub {
    my $cv = AnyEvent->condvar;
    $cv->begin;
    foreach my $key (@allKeys) {
        $cv->begin;
        async {
            my $data = $self->get($key);

            # 這邊是對 $data 處理的 code

            $cv->end;
        };
    };
    $cv->end;
    $cv->recv;
}
然後,你會發現打 AWS S3 打太兇時會傳回 500 給你,所以要用 Coro::Semaphore 限制連線數量,並且用 Perl 5.10 之後才有的語法來協助程式管理變數:
use 5.010;
use AnyEvent;
use Coro;
use Coro::Semaphore;
sub {
    state $sema;
    if (!defined $sema) {
        # 如果還沒建立的話開 semaphore,數量定為 32
        $sema = Coro::Semaphore->new(32);
    }

    my $cv = AnyEvent->condvar;
    $cv->begin;
    foreach my $key (@allKeys) {
        $cv->begin;
        async {
            $sema->down;
            my $data = $self->get($key);
            $sema->up;

            # 這邊是對 $data 處理的 code

            $cv->end;
        };
    };
    $cv->end;
    $cv->recv;
}
其實就是現有的東西套一套而已,不過真的還蠻好寫的... 包一包就能正常運作 :o

星期二, 4月 19, 2011

用 AWS SES 寄註冊認證信

因為 yahoo.com.tw 與 hinet.net 都有機制阻擋信件,於是就 jnlin 計畫把認證信丟到 SES 寄,包括 SPFDKIM 慢慢把 quota 養起來...

每千封 USD$0.1,也就是萬封就 USD$1,這還不計頻寬費用。以認證信來說還算 okay,如果要拿來寄 bulk mail 的話就太傷本了... (本來也不是拿來這樣搞的)

星期日, 4月 17, 2011

Perl 透過 Thrift 存取 Cassandra 0.7.x 的資料...

感謝「Accessing Cassandra 0.7.0 from Perl」這篇的作者,不只敘述要如何做,還提供了 sample code,實際操練一次後就知道要怎麼做了。

我另外在「Perl 上的 Cassandra 0.7.4...」有我抄過來練習的 source code,實際操練後發現 Thrift 產生出來的 API 很有 Java 的味道,如果要讓 Perl 社群用的習慣得再包一次...

不管怎樣總算是搞定了 zzzz

星期五, 4月 15, 2011

在 Ubuntu 下建立自己的 python environment

Perl 方法類似,只是要找一下要用哪些軟體做,以及做的細節... 這邊提到的方法沒辦法跨版本 (因為大多數的檔案還是 ln -s 到系統的 python)。

先裝 pip,系統會順便把 virtualenv 裝進去:
apt-get install pip
順便裝 python-dev,因為編某些程式時可能會用到:
apt-get install python-dev
接著就可以產生環境:
virtualenv --no-site-packages python2
然後自己把 .bashrc 內的路徑指過去:(.cshrc 也是類似的方法)
export PATH="/home/gslin/python2/bin:${PATH}"
接下來就可以在裡面用 pip 裝東西:
pip install pycassa
雖然沒辦法裝 2.7,但目前 Ubuntu 10.10 提供的 2.6.6 也還算堪用,方法暫時找到這樣...

ticket...

雖然說總是會有一兩張 ticket 是這樣,但當完兵回來看到十四個月的 feature ticket 沒有動還是決的很無奈... XD

星期四, 4月 14, 2011

把 eval() 包起來,放到 global scope

YUI Compressor 壓縮時發現在 local scope 裡面用 eval() 會造成 YUI Compressor 保留變數名稱。

找了一下資料找到解法 (然後很多投影片都一再的提出「eval is evil」XD),用另外一個 function 把 eval 包起來,丟到 global sope 裡面。像是這樣:
// It's global...
function myEval(c) { return eval(c); }

(function(){
    // Now it's local...
    myEval('...');
})();
當然,這個方法會讓 code 沒辦法看到 function scope 內的資料...

幾個 PSGI 實做...

測的幾個都是 miyagawa 寫的,依照 PSGI/Plack 網站上的順序說明。

Starman,是一套 prefork 的實做,所以適合用在沒辦法被 event-based library 控制的 blocking operation。以 miyagawa 測出來的數據來看,這也是三套裡面最快的。

Twiggy,是一套 AnyEvent 的實做,程式裡如果要用到 blocking i/o 就得想辦法讓 AnyEvent 管理。由於是 event-based,很省記憶體。

Corona,是一套 Coro 的實做,由於 Coro 也可以跟 AnyEvent 配合,這套彈性比 Twiggy 高,但效能就低了一些。

目前是用 Corona (因為 OAuth 那塊需要 Coro::LWP 幫助),要再觀察看看了...

星期三, 4月 13, 2011

用 OAuth 1.0 當作 API service 的 Protocol

最近都在惡搞...

如標題所說的,方法也很簡單,讓 apikey == accesskey (同理,apikey_secret == accesskey_secret),然後針對這些 API key 設定 IP limit,以及這些 API key 可以帶一個 sudo 參數,變身成其他使用者。

如此一來,既有 OAuth 1.0 的 library 可以直接拿來用,不用自己再設計一堆 protocol...

Ubuntu 上裝 s3cmd 1.0.0

Ubuntu 10.10 內建的是 0.9.9.91:「s3cmd (0.9.9.91-1ubuntu1)」,本來想找 ppa,後來發現官方有提供 Debian & Ubuntu repository:「Debian / Ubuntu repository for s3cmd」,直接到 repository 裡面抓 .deb 下來裝...

星期二, 4月 12, 2011

總算是拿到電腦了...

等了三個禮拜總算是來了... 附張灌 Ubuntu 的照片:

HTTP GET 的長度限制

微軟自己就有寫了:「Maximum URL length is 2,083 characters in Internet Explorer」,而 Firefox 從 1.5b 的時候就有人提沒遇到問題 (有人測過 30000bytes:「What's the Maximum URL length in Firefox」)。

想要用 GET 傳資料就比較辛苦點...

星期日, 4月 10, 2011

把一些靜態網站丟到 AWS S3 上...

最近在整理一些自己 hosting 成本很昂貴的站台,像是無名搬家 move.pixnet.tw 這種全靜態,而且平常也不會動內容的站台。

但這種站台因為牽扯到 uptime 的問題 (要避免連到無名的 blog 時不會讀不到 css,而造成看不到搬家訊息),所以在自家的伺服器上架設要放到 F5 上,後端還要有兩台以上的機器確保穩定性,其實維護成本還不少...

丟到 AWS S3 使用 website 功能之後,就不用管太多 (參考「Amazon S3 adds new features for hosting static websites」,加上 S3 本身有 Monthly 99.9% 的 SLA (通常更高),丟上去之後相當舒服...

Some settings of Plack/PSGI + FastCGI/FCGI + nginx...

If you found your Plack/PSGI application doesn't work in FastCGI (FCGI) mode, You might need to check the settings of nginx, to add extra environment to tell application correct path:
include fastcgi_params;
fastcgi_param   SCRIPT_NAME     "";
fastcgi_param   PATH_INFO       $uri;
It would be nice if you have better solution :-)

星期五, 4月 08, 2011

jQuery.getJSON 跨網域時 (JSONP),IE 沒辦法取得資料...

這個問題在很久前就有遇到,之前的解法是在 server side 加上 P3P header 解決 (這是 PIXNET 的 apache 預設會送出的 header 之一),但這方法遇到 server side 不是自己管就掛了...

jnlin 說從「$.getJSON('http://www.example.com/', callback_cb);」改用「$.getJSON('http://www.example.com/?callback=?', callback_cb);」就可以解決 IE 上面沒辦法取得 JSONP 資料的問題,測了一下的確解決了問題...

翻了一下 Google 發現這個問題還蠻亂的,被討論過很多次...

星期三, 4月 06, 2011

PIXNET 的 API 是支援 JSONP 與 HTTPS 的...

官方文件上沒寫,算是某種 undocument function 吧,不過我跟內部討論的共識是「應該要支援」,所以就做下去了...

除了 format=jsonp 以外,另外帶 callback=FUNCTION_NAME 的參數即可。P3P header 有設定,IE 也應該都沒問題。

以換燈泡老闆的帳號為範例:「https://emma.pixnet.cc/users/far?format=jsonp&callback=testFunction」。

在 apt 下升級單一套件

其實方法還蠻簡單的,就是直接下指令重裝即可:
apt-get install php5-cgi
如果要整個系統升級,用老方法即可:
apt-get upgrade
或是:
apt-get dist-upgrade