生涯未熟

プログラミングをちょこちょこと。

Golang Weekly #167

Profiler labels in Go · Go, the unwritten parts

Go 1.9の新機能としてProfiler Labelsが追加されます。

CPUプロファイラの収集データにラベルを追加することが出来るようになり、
例えば一般的なWebサーバにgoroutineでハンドラが分割された /user/top が存在する場合、
それぞれのgoroutineに対して /user /top のラベルを貼っておけば、pprofのREPLから tags を実行することで各々のCPUプロファイラ結果が見れるようになります。便利!

この辺りを記事書いている方が少ないので、改めて別記事として書こうと思います。

GitHub - tidwall/shiny: Alternative server framework for Go using I/O multiplexing

Goの新しいWAFなんですが、一番特徴的なのがI/O多重化の際にnetパッケージを用いず、直接epoll / kqueueを呼んでいるところですね。

作者のtidwall氏が挙げている特徴は以下の4つ。

  • 1つのエントリポイントと4つのイベント関数のみのシンプルなAPI
  • メモリ使用量が少ない
  • 非常に高速なシングルスレッドサポート
  • netパッケージでイベントをシミュレートすることによって、epoll / kqueueのないOSをサポート

今後どうなるか見守りたいWAFになりそうですね。

Golang Internals Part 2: Nice benefits of named return values

条件分岐によって、初期化されたオブジェクトを返すような処理の際には名前付き結果パラメータを使おうぜというお話。
ちょっとの違いで、コンパイラの生成コードがここまでスッキリするとは驚きですね。

また、deferで呼び出す関数内で名前付き結果パラメータを参照することが出来るので、

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i := incrInt(1)
    fmt.Println(strconv.Itoa(i)) // print 2
}

func incrInt(i int) (result int) {
    defer func() { result++ }()
    return i
}

といった面白いコードが書けたりします。

ちょっと少ないですが、今回はここまで。

Golang Weekly #166

Golang Weeklyを読むのが最近の楽しみなしょっさんです。

Golang Weeklyは一週間ごとにメールでGo関連のブログ記事をまとめて送ってくれるサービスになります。

Golang Weekly

f:id:syossan:20170704001739p:plain

で、自分のメモがてらにオッと思った記事とかを毎週まとめていこうと思います。

For Range Semantics

for rangeの挙動に関する記事です。

Mixing Semanticsの箇所はうっかりハマりやすいところなので、気を付けたいところ。

Leveraging interfaces in golang - Part 1 - P3 Programmer

json.Unmarshalを使う際に、UnmarshalJSONを使ったら良い感じに出来たよという記事。

僕も最近UnmarshalJSONを使って良い感じに問題が解決出来たので、物凄く共感。

Stencil - Simple code templating for Go

メソッドの引数の型に合わせてキャストし、その後関数を呼び出すってのが面倒なので型に合わせてジェネレートしちゃうのはどうか?という提言とその実装に関する記事です。

確かに面白い考え方だが、「そこまでする必要あるのだろうか・・・?🤔」と思ってしまう。

goman - the missing man pages for Go binaries · Applied Go

これはビビッと来たツール。

manコマンドのように、Golangで作成されたコマンドツールのREADMEを表示するツールになります。
Usageなど使い方がREADMEに細かく書いてあるようなコマンドには使えそうですね!

という感じで簡単に気になったGolang Weeklyの記事を今後も紹介できたらなーと思います。

リモートサーバーのhbaseをクライアントから叩けるようにする

日本語での情報が無かったのでメモ代わりに書く。

リモートサーバーで構築したhbaseに対して、JavaなりGoなり何らかで作ったクライアントからテーブル操作等々できるようにする。

やることは至って簡単で、 hbase-site.xml にPropertyを追加するだけ。

<property>
    <name>hbase.zookeeper.dns.nameserver</name>
    <value>[サーバーのIP、もしくはドメイン]</value>
</property>

これで、設定した値に繋ぎに行けばOK。

Golangで雑にメモリ状況を見る

pprof使うほどでもないよなってなったので、こんな感じで雑に。

var mem runtime.MemStats
runtime.ReadMemStats(&mem)
fmt.Printf("Alloc [%v] \t HeapAlloc [%v] \n", mem.Alloc, mem.HeapAlloc)

UnmarshalJSONを使ってJSONをシュッと変換する

渡ってきたJSONをUnmarshalしようと、こんな感じのコードを書きました。

package main

import (
    json "encoding/json"
    "fmt"
)

type User struct {
    Name []byte `json:name`
}

func main() {
    var j = `{ "name": "Ken" }`

    var u User
    json.Unmarshal([]byte(j), &u)
    fmt.Println(string(u.Name))
}

上手いことNameに値が入ってくるのかなと思ったら何も入ってこない・・・

なので、UnmarshalJSONを使ってシュッとやってみました。

package main

import (
    json "encoding/json"
    "fmt"
)

type User struct {
    Name []byte `json:name`
}

func (u *User) UnmarshalJSON(data []byte) (err error) {
    var value map[string]string
    json.Unmarshal(data, &value)
    u.Name = []byte(value["name"])
    return nil
}

func main() {
    var j = `{ "name": "Ken" }`

    var u User
    json.Unmarshal([]byte(j), &u)
    fmt.Println(string(u.Name))
}

これで表示されました。 Unmarshal時のタイミングで何かかませたい場合はUnmarshalJSONをぶっこめばいいという感じですね。他にも色々使えそう。