2012年5月13日 星期日

php embed or not.

雖然敝社還是在 layoff 的輪迴中, 但是總是沉浸在這樣的氣氛也不好,

5/24 有所謂的 hackday, 原本堅持不參加這種無聊節目的我, 剛好在 g+ 看到朋友討論 sketchup 有 embed ruby,

想到了 2007 年我曾經玩耍過 embed php, 那就來拿這個來玩耍一下吧.


hosted app 是 multi thread, 是所謂的 apache traffic server 的下一代, 也可以寫 plugin,

所以玩法就是把 php 用 plugin 的方式, embed 進這 hosted app 裡面,

掐頭掐尾, 把每次 request 中間, 要處理的資料丟進去 php runtime 處理,

(其實所謂的 plugin/module 的概念都差不了太多, 就是把中間某段切出來處理呀, 只是我試著改用別種語言來搞)


plugin 註冊的時候, load 進一個 php file, 裡面寫著遵守某些規範的 function,
傳什麼樣的資料進去, 離開的時候, 傳什麼樣的資料出來等規範.

然後就可以在每一次 request 之後, call php function 來幫你做事情.

想法很完美, 大概能省的 resource 也都省掉了, code 也寫好了,

基本測試也做完了, 跟差距的沒差太多, 不過一開始擔心的事情,

在第二次做 concurrent connection 的時候就發生,

由於敝社的 php 是 non thread, 被 embed 進 multi thread hosted app 中的時候,

同時間只有一個 connection, 一切都很美好,

但是只要同時有兩個 function 被 call, php runtime 一些 global variable 就會爆炸了.

而即使 php 是 thread, 這問題也是會發生, 因為 php_embed 這一個 sapi 實作上的問題,

他沒有把一些 global variable 切得很乾淨, 所以一定會爆炸.


查了一下 php mailing list, 其實 2009 年有人遇到這樣的問題, 所以某人就實作了

php_embed2, 號稱即使是 non-thread, 也一樣可以 embed 在 multi-thread hosted app 中.

測試的結果, fail.

Zend engine 跟我的 hosted app, 都會試著將 malloc/free 替換成他們自己的版本,

然後在 php runtime init 的時候, 就爆炸了, 根本不用等到 request 處理的瞬間.

所以, php embed + multi-thread hosted app FAILED.




既然都 fail 了有什麼好講?  我不管, 反正就是要 embed 個什麼東西進去,
手頭上幾個選項有 python, perl, lua.

敝社並不養雞, 所以會寫 python 的不多, perl 很多人用,
但是 default 的 perl5.8 沒有 thread, perl5.10 才有開, 但只有 32 bits binary,

意思就是我得強制我的 hosted app 也跑在 32bits, 我不要呀.


lua 則是聽過的人少, 會寫的更少, 不然會是最好的選擇,

選項都選光了, 一樣沒有好處理的, 怎麼辦? 我話都說出去了, 要參加呀.

好吧, 那 embed js 進去好了.


c++ daemon 收 request, 中間轉用 js 處理一些邏輯, 最後又用 c++ 收尾,
多棒呀.


講到 server side js, 大家一定會想到 nodejs, 但是其實並不是 embed nodejs.
因為 nodejs 目前只能寫 module 去 extend 他, 但還不接受被別人 embed,

要 embed, 請找 v8.

查了一下公司內的 package, v8 的版本有, 但是是 1.3.xxx, 現在 github 上的 v8 都已經 3.10.x 了, 也太老舊了吧.

v8 不行, 那 spidermonkey 總行了吧?

spidermonkey 有兩個版本, 1.7.0 & 1.8.5,

試了一下之後, 發現這兩個版本, 雖然 api level 是基本上相容的,
但是其實 1.8.x 整個 js runtime 似乎是用 c++ 整個重新實作過.

我不知道誰比較好, 但是看起來 1.8.x 有把一些 jit 之類的都做出來, 好像很厲害的樣子.

基本的 code 寫好, unittest 還沒做, concurrent connection 測試作過.

目前的測試, 有過 js runtime 跟沒過, 大概只差了一點點.


看起來是可以拿上場跟人較量了.