What have you found for these years?

2012-01-01

理想的 server concurrency 架構 (2)

edit: 2012-01-01 22:47 cool.io issue #21 Fiber-aware deferred operation

早上一直被吵,結果就睡不太著了。惱怒萬分之後,把電扇開到最大,
然後再大聲開著音樂,企圖把隔壁的對話聲蓋過去。本來是有點想乾脆
就這樣爬起來算了,但我很清楚這樣我體力應該支撐不住吧... :(

好在後來下午就安靜多了,就可以一直睡下去。

住這邊隔壁再一直講話的話,說不定有一天真的會抓狂...。
看來以後我一定得住到一個很安靜的地方。

* * *

下午(晚上?)爬起來後,立刻實驗了自己睡前和睡覺中在想的 fiber+thread.
spawn 一個 thread 去做 cpu bound 運算,接著 Fiber.yield 出去,thread 算完
之後,再 resume 回來。

昨天躺在床上時,忽然想到,我應該不能從 thread 中直接 resume 回去吧?
因為如果可以這樣 resume 回去的話,就等同於 fiber 會在任意時刻被中斷了。
所以我可能需要用一個 queue...

在 thread 算完之後,最後 queue << fiber 塞到 queue 裡面,在 event loop 中
不斷去檢查這個 queue, 一旦有東西,就 pop 出來 resume.

爬起來之後,確認了 queue 的方式確實可以運作。不過要套到 cool.io 中呢?
我想可以用 Coolio::AsyncWatcher 來達成類似的事,連 queue 都不需要。

簡單的 defer 測試程式貼在 gist 上。
edit: 2012-01-01 22:47 cool.io issue #21 Fiber-aware deferred operation

概念很簡單,假設我現在要做的事情,是要從網路上抓一張圖片下來,接著
對那圖片做一些影像處理,最後再上傳到網路上。最終程式寫起來大概會像這樣:

image = Http.get 'http://example.com/'
image_new = Defer.defer{ process_image image }
Http.put 'http://example.com', :image => image_new

其中 Http.get 時會 Fiber.yield 出去等結果,得到結果後才 resume 回來。
Defer.defer 則會 spawn 一個 thread 後 Fiber.yield, 同樣算完才 resume 回來。
最後 Http.put 亦然。

以上三件事將在一個 http request 中完成,這個 http request 本身被一個巨大的
fiber 包起來,其中會 Fiber.yield 出去三次。每一次 yield 出去,則讓 web server
有機會去處理其他的 request. 而在這之間,resume 回去的時機則在 request 與
request 之間,或是另一個 request 也 yield 出去的話,都是 resume 回去的時機。

cool.io 沒有內建好用的 http client, 但很簡單可以做出一個堪用的,昨天忘記提了。
相關程式與討論可以在 cool.io issue #20 中找到。

也就是說,萬事具備,所有我想要的材料都有了!

....才怪 orz
我剛剛才想到,那 TLS/SSL 呢!?測試了一下,翻了一下,還真的不支援啊!!!!!!
是有看到 cool.io-ssl, 但是看看內容,根本全部都是空的,上次更新還是去年,不,
前年十一月啊!十三、十四個月前了!

其實還欠一個東西,就是 cool.io 的 http client 不支援 streaming payload body.
這點我可能還勉強可以接受,反正就先試試看就是了。而且說不定我自己也有機會寫出來。
但是支援 TLS/SSL? 這個我還真的不知道怎麼做了。

現在去研究..? 那也未免有點想吃飯先種稻了 orz

是說這些應該都可以在 eventmachine 中達成,但是寫起來就難看很多,
也複雜很多的感覺。跟 cool.io 相比,可以感受到 eventmachine 很多東西
用起來不是那麼方便,尤其在疊床架屋了這些年後。

可是沒有 TLS/SSL 我要怎麼搞?一堆 API 現在都要 HTTPS 啊,
沒辦法用這個就真的等於是不能用了。

(沮喪)

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0