2014-03-13 聚會手記

上一週 || 下一週

果凍

Nginx config example for Tornado
https://gist.github.com/didip/802576

carl

Robot Framework 簡介
https://gist.github.com/bcbcarl/188891af9e6d6eb95533

IHaskell
https://index.docker.io/u/bcbcarl/ihaskell/

cowboy

可以監控網站實際使用者的流量跟效能的 JavaScript Tool,包含了 Client 與 Server
Bucky — Performance Measurement of Your App's Actual Users
http://github.hubspot.com/bucky/

yan

RFC3339
2008-09-08T22:47:31-07:00

RFC2445 (iCalendar)
20121211155343

ISO8601
2008-12-19T16:39:57.67Z

ATOM = "Y-m-d\TH:i:sP";
COOKIE = "l, d-M-y H:i:s T";
ISO8601 = "Y-m-d\TH:i:sO";
RFC822 = "D, d M y H:i:s O";
RFC850 = "l, d-M-y H:i:s T";
RFC1036 = "D, d M y H:i:s O";
RFC1123 = "D, d M Y H:i:s O";
RFC2822 = "D, d M Y H:i:s O";
RFC3339 = "Y-m-d\TH:i:sP";
RSS = "D, d M Y H:i:s O";
W3C = "Y-m-d\TH:i:sP";


速度比較
http://jsperf.com/prop-vs-ischecked/5
$el.prop('checked');
$el.is(':checked');
$el.attr("checked");
$el[0].checked;

Mat

#!/usr/bin/env bash

cmd_list=$( docker 2>&1 | grep -e "^Commands:" -A 9999 | grep -e '^    \w\+' | awk '{print $1}' )

for cmd in "" $cmd_list                                                                                                 
do
        opts=$( docker $cmd --help 2>&1 | grep -e '^  \-' | cut -d: -f1 | sed -e 's/^  //g' -e 's/, /\n/g' )
        for opt in $opts
        do
                printf "[ %15s , %s ]\n" "$cmd" "$opt"
        done
done

讀 docker.io 源碼心得:

之前無法執行成功的原因是 aufs fs 裡的目錄,不能再被 mount 成 aufs fs
( 因為我的系統是特製的,整個 / 目錄本身就是 aufs )
也基於相同的理由,若選用 aufs driver, 則要在 docker.io 裡再執行 docker.io daemon,也會有問題
( 選其他機制或許通以,但目前其他的 overlay 機制可能還沒辦法像 aufs 這麼好用 )
更改 / 的 mount 設定後,現在仍有部份問題,主要是在 umount 之前的 auplink 動作,有 warning
(應該無大礙,但 docker 原程式會作整個中斷,所以這部份要修改掉某些部份才行 )
另外, 在 i386 上執行的話,也要選擇 for i386 的 image ( 目前只有找到 3 個 )
就目前接觸的感覺,我覺得 docker.io 像是更進階好用的 chroot (LXC)
更好的是 docker.io 提出了一套 layers 的操作/管理/線上repos 機制,同時降低 images 製作的門檻。
這對想作 clean build / clean test 的人來說,有大大的幫助
舉例來說,若今天我想把某個程式 porting 到 debian 的 stable/testing/unstable , ubuntu 13.04/13.10, fedora, archlinux, suse,… 時,原本我可能要用 qemu, virtualbox, vmware, … 去作8個不同的image,
除了要弄 disk image, boot, install, config,.. 很久之外,在 build/test 的過程中,還要一直不斷的"手動"作 VM 的開/關/save/restore 的操作。
若今天用 docker.io 來作的話,只要到 https://index.docker.io/official 下載就可以用了,像是

for distro in debian ubuntu centos fedora
do 
  docker pull $distro
  docker run $distro "git clone PROJ_URL proj_dir; cd proj_dir; ./build.sh"
done

golang 如果 import 一個套件,就必須在程式裡用到。如果沒有用到,就會 compile error
這樣的好處是,強迫程式淘汰冗餘的部份,有助於 refactor & 程式收斂
壞處,就是很容易遇到 compile error, 就算不經意註解某行程式也會 error
docker 的 runtime 主要分 cilent/server 的架構來運作
client 端的呼叫主要是透過 /api/client.go 裡的函式來呼叫
可以在 CmdHelp() 找到 CLI 對應的指令列表
CLI 透過 runconfig.ParseSubcommand() 來處理 options
透過 ParseCommands() 跟 getMethod() 來對應 CLI 的指令跟處理函式
指令跟處理函式的對應關係是靠函式命名,
例如: "run" -> CmdRun(), "inspect" -> CmdInspect()
client 端的處理函式裡,再呼叫 cli.call() 跟 server 端的 API 互動
例如: cli.call("POST", "/containers/create?"+containerValues.Encode(), config, false)
server 端主要是 /api/server.go (舊名稱是 api.go) 裡的函式來呼叫
在 createRouter() 可以找到 API 對應的主表,
例如 /containers/create 會對應到 postContainersCreate() 的處理函式
server端裡的處理函式,會常看到 Job, Engine 這兩個資料物件的操作
docker 實際執行系統層的指令, 如 "/bin/echo", mount filesystem, 其實都是透過 Job 這個物件來包裝
大致上像是 var job = Engine.Job( 指令 + 參數 ) ,然後 job.Run() 執行
核心流程:
request -> /api/server.go -> 產生 Engine -> 執行 Engine -> 輸出/回傳 Engine 的結果
API 在 server 端的 invoke/response HTTP 的部份, 可以看 engine/http.go 的動作就可知道
其中 "執行 Engine" 的動作 => 會再轉成 "產生 Job -> 執行 Job -> 輸入/回傳 Job 的結果" 的底層動作
最底層是產生並,操作 Job 物件完成任務
amd64/386 的 check 其實是在 Engine 這一層.
Engine 是整個 docker 運作的核心物件。

Engine 裡的 handlers 有多個,而 handler 的來源可能是內建定義的預設函式,也可能來自 Job 物件
目前還無法確認 Engine ↔ Job 的關係是 1-1 還是 1 ↔ N

docker 的函式實作,主要是走 No exception 的風格,也就是說,整個函式有 10 個步驟,只要其中一步有 err, 就馬上叫這個函式收拾東西打包回家,並中斷整個 thread。
程式裡,用了不少 golang 裡的 defer() 語法,這個語法方便用作 fail handling

一些內建的 engine handle 可以在 builtins/builtins.go 裡找到
server 的啟動過程

docker/docker.go 裡的 main() 裡的 if *flDaemon 那一段
eng.Job("initserver") …. and Run()
eng.Job("acceptconnections").Run()
eng.Job("serveapi", flHosts.GetAll()…) … and Run()
api/server.go 裡的 ServerApi()
執行 ListenAndServe()
createRouter() 也就是建立 server 端的 API 指令與 handler 的對應表
httpSrv.Serve()
當 server 接到 request 時
查找 createRouter() 所建立的指令對應表 -> 找到對應的處理函式
執行該處理函式
有的直接執行,不用回傳
需要回傳 HTTP 的,執行完,結果用 Engine.ServHTTP() 來回傳結果
trace 過程中,需要一一去了解相關的物件結構,而要個別了解該物件的特性跟用法時,這時候可以去看該物件的 unit test 範例,就比較快能掌握住。
而最上面會有個 integration 的目錄,那裡面的 unit test 則可以看到不同的物件的合作方式
docker 的程式裡,有物件導向的設計,有 event/handler 的設計,加上中間聯動的關係是動態 register 的。
( docker 採用這樣設計的好處是,程式的功能方便作"水平擴充", 要新增功能,只要 copy-n-paste 對應的 cmd/handler 來新都就可以了 )
在不了解程式結構下,不容易像一般程式那樣用 gdb/strace/… 快速直接找到對應的 function call chain
這也是目前 docker 在 debug 上最麻煩的地方。
( 感謝 "果凍"建議的 runtime/debug, debug.PrintStack() 跟 fmt.Println() 的語法,發揮了很大的作用 )
這個 debug 上的問題,其實在底層多放一些丟出 debug 訊息程式片段就可以了。
不過雖然這道理大家都知道,但就以往經驗,大多數的程式還是不會這麼作。
why? 因為 "開發者都希望底層的函式越簡單、越乾淨越好,3行就可以簡潔搞定的程式,有誰會想在上面寫個 5 行註解說明,再弄個醜不拉幾,且重複又沒人看的 debug訊息呢?!"

https://bitbucket.org/matlinuxer2/mat-portage-overlay/src/7c6bf776c6e0a9f03c6c681dfbc5ed563a95a406/app-emulation/docker/docker-9999.ebuild?at=master
https://bitbucket.org/matlinuxer2/mat-portage-overlay/src/7c6bf776c6e0a9f03c6c681dfbc5ed563a95a406/app-emulation/docker/files/docker-for-i386.patch?at=master

philipz

http://resin.io/blog/release-docker-0-7-2-for-arm/
https://coreos.com/
http://www.serfdom.io/intro/vs-zookeeper.html
http://www.centurylinklabs.com/decentralizing-docker-how-to-use-serf-with-docker/
http://www.centurylinklabs.com/auto-loadbalancing-with-fig-haproxy-and-serf/
https://coreos.com/blog/docker-dynamic-ambassador-powered-by-etcd/
http://coreos.com/blog/cluster-level-container-orchestration/

coreos base on chromeos
etcd, 演算法比 serf 強, 可以跨網段
serf, vagrant, packer 都同一個人搞的

Yi-Ju Wu

https://www.inkfilepicker.com/

IRB - Interactive Ruby Shell

除非特別註明,本頁內容採用以下授權方式: Creative Commons Attribution-ShareAlike 3.0 License