[研討會心得]Golang Taipei Gathering #12 etcd in IoT /go generate

前言: 本來還在思考要不要參加,但是剛好gtg slack上面有人願意把票讓出來.就趕快來聽聽.此次的相關資料在這裡. 研討會筆記: [POGA]Go Generate, trick to write Ruby 適合拿來寫 DSL Stirng/HASH Anywhere lack of “syntax eror” GO sort 不支援int64 sort, 其實只是多寫成4 lines :). 參考這篇 Because it’s four lines of code: type int64arr []int64 func (a int64arr) Len() int { return len(a) } func (a int64arr) Swap(i, j int} { a[i], a[j] = a[j], a[i] } func (a int64arr) Less(i, j int) bool { return a[i] < a[j] } Float64 is the more common float, int is the more common it, so both have predefined versions of this. self-refererencial function struct tag using reflect is slow, don’t use it in DSL. go generate 僅僅是regex來替換而非parser “go get” don’t run “go generate” for you slide: http://www.slideshare.net/poga/gtg12 與講者額外的談話: struct tag 可能會發生問題.. 由於json tag 是會被go compiler skip,但是極有可能會發生一些錯誤 tag 內名稱寫錯而永遠讀不到json的內容 不小心把一些語法寫在雙影號外面.(e.g. omit…) 寫錯不會造成整筆資料都是空的,而是某個欄位會變成空的.這就比較麻煩. 關於go generate 使用實例: 把他當成shell script 自我檢查,比如slide裡面的auto error [HAWK]miicasa etcd for IoT What is IoT? 物聯網 - 蒐集狀態機 透過簡單的 AND OR NOT的來控制....
繼續閱讀

[Java][Golang][Python][程式設計週記].. 2015第一週.. 20150109

前言: 主要紀錄一些網路上查到的東西,實作上應該會有更多文章出現…. 筆記 [Java] 關於一切有趣的Java資源 RDBMS & PostgreSQL(1): 淺談資料庫 本身跟Java沒有太大關係,不過內容挺有趣的,尤其講到數據的成本 XDDD 其他篇相關文章如下: RDBMS & PostgreSQL(2):跟 MySQL 說再見, 加入 PostgreSQL 吧 針對這份簡報內容的一些討論 操作員在凌晨四點被叫醒 關於DB Cassandra 處理的一些事件與大量資料處理 [Golang] 一些有趣的Golang 資源 Hyperfox 一個可以當proxy與了解本地端HTTP/HTTPS內容的工具 No Effing Clue: Compiler 2 Part 1: Introduction to Apprentice Compiler Design 本篇是講解一些compiler設計上的概念. No Effing Clue: Compiler Part 10: Compiling to C 針對透過Go來寫Compiler的概念. HTTP狀態碼 跟Go無關,主要是記錄一下要怎麼做martini response用的 BoltDB: Low-level key-value DB 與etcd不太一樣的是,他只是單單有資料庫.而沒有JSON輸出. Why Go’s Closure Can Be Dangerous 主要是講解,GO的closure牽扯到GC(Garbage collection)所以使用全域變數要小心造成記憶體浪費(直到結束前都不會減少). Dropbox: Open Sourcing Our Go Libraries 其實是去年的舊聞,不過github可以在這裡找 [SQLBuilder] 在slack討論中有提到Sqlbuilder,也就是可以透過簡單的function去產生複雜(或簡單)的sql語法來操作資料庫 某大大寫的sqlbuilder 這邊有dropxob提供的sqlbuilder 不過總括的寫起來,其實sqlbuilder還是只能幫助到一些簡單的轉譯,就rails migration上面有人建議從code generation 下手會比較好. 這裏有關於Golang使用者還沒打算使用ORM的文章 此外,比較沒有看過NoSQL 有Query Builder,只有看到node.js有類似的query engine 衍伸閱讀: Golang ORMs:A survey of the current state of Golang ORM MongoDB: SQL to MongoDB Mapping Chart Go and Postgres:Go, Martini and Postgres Tutorial - Part 1 A little trick to statically link C to Golang with cgo 一些小技巧如何在Go上面連接C,使用的是cgo An NES emulator written in Go 超酷.. 用Go寫任天堂模擬器 Experimental KVM-based VMM, written in Go 虛擬機器的監視器(Virtual Machine Monitor),根據上面的講解,會比docker所使用的container更有優點. 延伸閱讀MSFT: 雲端運算: 虛擬化類別 Github:A replacement...
繼續閱讀

[Golang]關於martini架構的更深一步了解

前言: 最近開始深究Go的webframework martini.慢慢開始會寫更多的東西出來. 筆記: 以下敘述的方式,會根據我想要達成的目標依序紀錄一下: [JSON] 解決martini JSON的資料解析(parse) 不論是Martini或是 http.Request原本基本都會是使用JSON.Unmarshall來處理. 這裏需要注意的是,跟當初在處理mongodb的資料一樣.變數的名稱不可以全部是小寫,但是json資料名稱需要全部都是小寫. 如果不小心把變數名稱全部打成小寫,會無法正確的Unmarshall資料. type Response2 struct { Page int `json:"page"` Fruits []string `json:"fruits"` } str := `{"page": 1, "fruits": ["apple", "peach"]}` res := &Response2{} json.Unmarshal([]byte(str), &res) fmt.Println(res) fmt.Println(res.Fruits[0]) [martini-render] 關於martini 顯示json的顯示部份.原本encoding/json能處理大部分的事情.但是要能完整顯示http status code 與json內容的話.我還是選擇了martini-contrib/render render.JSON(400, map[string]interface{}{"result": "success"}) [Martini map]接下來問題是,如何在各個martini handler中,去傳遞你要的變數或是如何把資料庫加入. 原本是應該要直接使用martini.Use(DB()) 然後再去接 DB 的起始martini.handler即可.參考這裡 但是想要做成可變動的資料庫格式(in-mem DB, mongodb 共存) 所以還是直接丟整個變數比較好.類似作法參考 var db SomeDB{} //將變數透過martini 傳到各個handler m.Map(&db) ... //新增一個變數參數就可以使用 func someHandler(params martini.Params, r render.Render, db *SomeDB) { .... } 相關文章: Go Doc: Init function Init是負責每個檔案的起始function,會比main()更早啟動.但是各個檔案的Init並沒有一定順序. 根據這份文件提到,他在整個程式中的順序會是: 變數起始 Import Init Go :Methods on structs Build a RESTful API with Martini Learning Go with Martini - Working with MongoDB Simple App with Go, Martini, Gorp and MySQL
繼續閱讀

[Java][Heroku][程式設計週記] 新年快樂...來寫code吧.. Go-martini跟 Java Srping Boot

前言: 新年新希望…. 繼續寫程式啊…. 之後要把Go Web Server逐漸到真的能使用的部分. 筆記: [Golang][Heroku] 將buildpack upgrate到Go1.4 最近的需求,將Go拿出來重新的翻了一下.除了之前發現沒有更新到Go1.4之外.也發現原來之前透過martini寫出的REST server並不完全是JSON的格式.於是最近開始把Go-herokuo-server翻了一下. 以下紀錄如何將你的heroku更新到1.4 重新跑godep 記得將godep目錄下的檔案全部一併更新上去 或是可以參考kr/heroku-buildpack-go [Golang]關於Json資料的Get/Post處理 發現martini原先雖然有做REST API但是並沒有針對JSON資料來處理.而要處理JSON的資料其實在Go裡面還是有一些地方要處理. 幾個值得注意的地方如下: 從網頁抓來的資料可以由http.Request.Form或是http.request.Body抓來處理. Request.Form 資料可以從 curl -X POST -d “DATA” “http://address” Request.Body 資料不僅僅可以抓 curl的資料,也可以抓取http.NewRequest(“POST”, url, bytes.NewBuffer(jsonStr))來的資料. 抓取來的資料都可以透過map interface來接,再慢慢去處理. 如果JSON資料比較複雜類似 { A:a1 B:[ { B1: b1, B2:b2}]} 就透過以下邏輯來解決 先透過第一層map拿到B內容 [ { B1: b1, B2:b2}] 透過 array interface拿到 { B1: b1, B2:b2},記住內縙 ary[0] 再透過map接過來繼續解出其他的內容. 參考資料: 傳送JSON POST資料方式 透過Request.Body抓取資料 Golang Example的JSON 這邊有關於Request.Body部分的處理方式 以下把部分程式碼擷取出來: //資料來源 //curl -X POST -d "{ \"name\"" : \"that\", \"num\": \"3\"}ttp://localhost:5000/fruits" // 透過Request.Form的資料 r.ParseForm() var dat map[string]interface{} for key, _ := range r.Form { fmt.Println("r.form") fmt.Printf("key = ") fmt.Println(key) err := json.Unmarshal([]byte(key), &dat) if err != nil { fmt.Println(err.Error()) } } for key, value := range dat { fmt.Println("Key:", key, "Value:", value) } // 透過Request.Body再把Json資料Unmarshall body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Println("read error") } fmt.Println(body) fmt.Println(reflect.TypeOf(body)) fmt.Println(string(body)) var dat map[string]interface{} err = json.Unmarshal(body, &dat) if err != nil {...
繼續閱讀

[UNIX][python][Golang][程式設計週記] 20141231

前言: 接下的時間可能會比較忙碌,盡量也會多花一點時間玩Go… 筆記: [Golang] 關於一些實用的鏈結 如何優雅的處理伺服器遇到SIGNAL問題時候重啟: Graceful server restart with Go 關於Go 1.4 關於測試的新功能: My reason to be excited for Go 1.4 關於Golan許多工具的介紹: An incomplete list of Go tools Go for the paranoid network programmer: 挺多講解許多網路工程師應該會用到關於Go的部分 Go Everyday: 一個連續寫了三個多月Go的工程師把他的心得整理一下,裡面也包含他常用的工具 My Thoughts on Martini: 一篇專門討論一些Go上面Martini缺點的網頁,當然主要也是推廣自家好用的web framework negroni [Docker] 這個禮拜Docker.Taipei 有辦年末小聚.雖然沒辦法參加把相關文件收集一下: Carl Su: Docker 發展近況簡報釋出,內容涵蓋 Machine, Swarm 和 Compose。 用docker開出desktop環境:DOCKER DESKTOP: YOUR DESKTOP OVER SSH RUNNING INSIDE OF A DOCKER CONTAINER Docker.Taipei 年末小聚,現場錄影 zerotier: 可以將docker服務串接在一起 Docker Infra 架構簡介與實例: 可以做到cluster與分流的架構 [Python] 一些網路上看到的有用文章 [Python] IPython簡單使用技巧速記 透過Facebook傳送訊息 via Python 根據作者的說明如下: 可以做到 Graph API 無法做到的事,例如傳訊息至朋友或群組,也可以上傳照片,還可以接收訊息.所以可以用 Facebot 來寫一些通知功能,甚至是和你聊天的機器人. [Google]透過經緯度顯示Google Map 經過這一篇stackoverflow問答可以查到詳細方式 http://maps.google.com/maps?z=12&t=m&q=loc:38.9419+-78.3020 z is the zoom level (1-20) t is the map type (“m” map, “k” satellite, “h” hybrid, “p” terrain, “e” GoogleEarth) q is the search query, if it is prefixed by loc: then google assumes it is a lat lon separated by a +
繼續閱讀

[Golang]關於Slice在Append的一些發現

前言: 當初主要是RUST在官網上提出他們可以避免掉std:vector.push_back造成的referene 問題. 於是我也很好奇,究竟Golang會怎麼樣處理這樣的問題. 也由於Go本身把vector拿掉,我們就用Slice來試試看. 筆記: Slice 本身的結構包含資料本身,長度(len)與容量(cap),根據Slice Internal Document裡面提到的.而且操作slice的append的時候,會根據你目前的容量(cap)來決定是否要重新分配記憶體位置. 比起std::vector好的是,如果記憶體重新分配了,原先參照的參數不會得到空的記憶體位置,而會變成是複製的內容. 但是要注意的是,參照的變數就不會跟著變動了. 這聽起來就是比較安全一點,不過程式不會造成pointer to null並不代表比較好,因為在這種狀況下.所參照的數值已經被修改,你可能會遇到更不能預測的問題. 所以比較優雅的方式,還是事先要保留足夠的資料.避免append造成的資料重新建立. 奇怪的狀況,cap增長的大小根據compiler的不同 我本來是很清楚這樣的狀況,直到我把我以下的程式跑在本地端(Mac/Win)還有遠端的Golang Playground發現結果不一樣了. 是的! 靚過第一次slice append之後,cap(slice)增長的數值竟然不一樣?? (Playground是2,本地端是1) 一樣的狀況.類似的操作在c++ std::vector 就沒看到 (Win/Mac/Coliru online compiler) 增加過後的的cap都維持為”1”. 這裏有參考的C++程式碼. 於是我在Stackoverflow詢問了這樣的問題,也引起了一些人的注意,幫我把問題發到了Golang上面.雖然沒有辦法說服大家把這樣類似的問題放入spec或是warning,但是真的提醒大家,真正在使用slice的時候,必須像使用std::vector一樣的小心.最好的方式是不要參照,如果真的要參照的話,也建議使用保留的slice大小來避免記憶體重新的分配所造成的參照失效. 以下是完整的Golang 測試程式碼 package main import "fmt" func main() { var a []int var b []int fmt.Printf("a len=%d, cap=%d \n", len(a), cap(a)) a = append(a, 0) b = append(b, 0) p := &a[0] fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p = %d \n", a[0], &a[0], len(a), cap(a), *p) a[0] = 2 fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p = %d \n", a[0], &a[0], len(a), cap(a), *p) /* a[0] = 0, p = 0 a[0] = 2, p = 2 */ var c []int var d []int fmt.Printf("c len=%d, cap=%d \n", len(c), cap(c)) c = append(c, 0) d = append(d, 0) p2 := &c[0] fmt.Printf("a[0] = %d pointer=%d, len=%d, cap=%d, p2 = %d \n", c[0], &c[0], len(c), cap(c), *p2) c...
繼續閱讀