What have you found for these years?

2012-01-04

睡不著的呢喃

睡著了一個多小時,因為想小便只好爬起來,然後就睡不著了。
說不大上來,總之就睡不著。或許我已經習慣接近天亮才睡了。

其實我也不知道要寫什麼。但想想反正打開編輯介面,然後把
洩出的思緒隨便打出來這樣就好了。那就這樣吧。

睡不著爬起來前在想的是,為什麼無法融入這個社會?
想到的是前幾天的事。覺得很明顯後來自己心情不大好,
只想避開那些事。後來想想,總覺得反正最後都是走向
那個結論,就算那不是終點,似乎總是至少要經過一次。
那再多想也真的是沒有意義了。

*

前幾天看到一些東西,不禁讓我很想說,看吧,我不早就說過
很多次了?不過想想說這種話其實真的沒什麼意義。唯一的意義,
或許只有表達自己的優越感而已。畢竟如果真的想要有所改善
的話,應該是不厭其煩,就算是別人再不相信,也要諄諄告誡,
不會像我覺得不是很愉快,或是覺得自己影響力很小的話,就
閉嘴不再說了。

我實在懶得多費唇舌,我既不是傳教士,也討厭爭執,更討厭
跟不信任自己的人說話。這些年來這些感覺也變得愈來愈強烈。
(或說肯定)

--
哈哈,隔壁鬧鐘響了,七點整。還好只響了幾聲,要是響個
十分鐘我應該會想打人。是說我還曾經被他鬧鐘吵醒過,是
怎樣....。那時倒是沒很著惱,畢竟我實在太容易被吵醒了,
(然後又要想起高中那件事... XD)
那時候又迷迷糊糊的,兩三下又睡著了。
--

表達自己的優越感這件事也沒什麼意義。於是還是把注意力放在
真正重要的事上吧。仔細想想,這些情緒完全是因為有部分注意力
放到人身上了。如果假使一個東西的產生,是無中生有的話,大概
就不會想在那邊說「你看吧我早就說了」,感覺可能會比較像
「我都還沒出手,他自己就修好了」這樣吧。這樣就不會因為覺得
自己的話不受重視而感到需要表達自己的優越感吧...

--
鬧鐘又響了耶。

在我在想下一段要怎麼開始時,鬧鐘響了第三次。
--

*

想想這段我想說的,其實跟上一段差不多。難怪我會想起前幾天的
那件事。總而言之,我覺得有些東西是如此可笑,卻居然還有一堆人
推崇,然後最後再看著他們走回頭路。順著路子講下去的話,大概
又會變成其實我只想表達自己的優越感而已。也罷,同樣的抱怨,
講一次就好了。

--
鬧鐘響了第四次。現在是七點十五。鬧鐘聲音其實很大,我在打字時
都聽得很清楚,不用刻意去聽。不打字時,鬧鐘聲音顯得吵鬧。
--

從另一個角度來說好了。其實看看以前的自己嘛,不也是有一些很笨的
想法,或是現在看起來是錯的東西?很多路不自己走過一次,是不能
理解的。因此那無關對錯,只是早晚的差異而已。或是說,某種運氣。
嗯,反正不能預測的東西,都丟給運氣就對了。不管是能力不足而無法
預測,或是真的太難—其實說到底都還是某種能力不足啊,丟骰子,
如果能完全模擬環境,怎麼會真的無法預測..? 好吧我不懂量子力學...

電鰻發電的感覺是什麼?(《尋找腦中幻影》)

感覺不只是當下那個感覺而已。那包含著過去的經驗與跟周遭環境互動
的感覺。這些事,不完全模擬一次,是很難傳達的。而完全模擬一次,
其實就可以說是經歷一次了。因此有些東西,不自己親自走一次,確實
是很難去理解或接受的。

用這種角度去想,就不會想表達優越感了。不過取而代之的則是一種寂寞,
一種我先走了,希望你能跟上來的一種寂寞,看著別人用三年走過你一天
就走過去的路。我個人覺得這真是莫大的寂寞。但難道放慢腳步,甚至走
回去碰頭?省省了吧,那又不是「某人」這樣嗎?世界上有多少人是如此?

嘿嘿,可也有很多人,用了一天就走過我三年走過的路。

*

眼睛覺得有點疲倦,不過我覺得我更餓,得吃點東西,然後再看運氣好不好
能不能睡。是說,我鬧鐘設十點,差不多也沒什麼時間可以睡了。

--
隔壁終於下床了嗎?厚重的腳步聲總算傳來了。如是,賴床了半小時。

在刷牙嗎?感覺聽到杯子的聲音。之前從那個方向還聽過漱口聲。

他們開始聊天了!內容聽不到。如果沒有隔音說不定聽得到吧。這隔音裝了
對面聲音還這麼清楚,總讓人覺得好像反而造成少掉聽懂內容的趣味。

不過說真的,我實在痛恨聽到他們講話。我要電扇開最大蓋掉他們的聲音了。

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 啊,
沒辦法用這個就真的等於是不能用了。

(沮喪)

理想的 server concurrency 架構

這幾天一直在想這些事,快速筆記一下...

最外面一層肯定是一個 reactor, 畢竟 server 最前端是完全 I/O bound 的東西。
接下來 application 層如果碰到 I/O bound 的東西,大概就是用 server 所選擇的
reactor 來處理這些 I/O, 並用 fiber (coroutine) yield 一下。等到資料都 buffer
好之後,再 resume 跳回來。

假設在一個 request 中,我們有 A, B, C 三個 network dependency, 就是三樣
I/O bound 的操作。其中 C depends on A and B, 則我們可以叫 reactor 幫忙處理
A 與 B, 處理完之後透過 fiber (coroutine) resume 回來,由 application 處理,
處理完之後再叫 reactor 處理 C. 其中 A, B 可以同時處理,但是 C 不行,因為這裡
C depends on A, B, 而 A B 本身互相沒有關係。

最後要回傳回去的又 depends on C 的結果,所以這個 request 中的 fiber 將會
被 resume 兩次,一次是 A+B 的結果,另一次是 C 的結果。

假設之後其實又還有個 CPU bound 的 D 操作,而 D depends on C, 則在 C
處理完 resume 回來後,接著是 spawn 一個 thread 或 process 來處理 D!
可以由 reactor 維護一個 thread pool, 要 spawn thread 時,由 reactor 來
選擇使用哪個 thread. 接著同樣,application 層的 fiber 要 yield 出去。等到
D 完全處理完後,再 resume 回去。

以上完全沒提到 ruby, 不過我是在為 ruby 思索的。這可以透過 eventmachine
來處理。eventmachine 本身就有一個 thread pool, 可以讓玩家 programmer
defer 出去。也就是說,以上全部都可以透過 eventmachine + fiber 來完成。

不過事實上,我比較想透過 cool.io 來完成。原因很簡單,我覺得 eventmachine
已經太疊床架屋,東西變得太複雜難搞了。看看我前幾天的測試:

config.ru

cool.io 可以用最直觀的作法,但是 eventmachine 卻需要 async-rack + rack-fiber_pool.
當然啦,這裡會變成這樣,最主要的原因是 rainbows 中有 CoolioFiberSpawn,
但是卻沒有 EventMachineFiberSpawn. 我不知道這有什麼特別的原因,但我覺得
這肯定是有其原因的,可日後再思考,或是直接請教 Eric.

總而言之,用 cool.io 的話,東西都可以寫得很簡單。

eventmachine 會搞成這樣,我推測有一個很大原因是,有些 async framework,
例如 async_sinatra, 是用 throw :async 的方式來達到某種 Fiber.yield...
怎麼說,如果沒有 fiber (coroutine) 的話,這可能確實是比較簡單的作法。
但這樣做的話,其實把問題變得複雜很多 :(

cool.io 是沒有 thread pool, 沒有 eventmachine 的 defer 機制,不過我覺得
這應該還好,要做的話不是那麼困難。重點是這可以是獨立的東西,我甚至做在
application 層而非 reactor 層應該都沒問題。

總而言之,目前看起來就 ruby 而言,要完成這個方式最好的方式可能是用
rainbows + CoolioFiberSpawn, 雖然在 cool.io 上,感覺還欠不少東西,
可能要慢慢補上去.... 我不確定 Tony 是否有打算繼續做下去,這點讓我有點傷腦筋。
eventmachine 的替代品並不是很多啊 :(



All texts are licensed under CC Attribution 3.0