生涯未熟

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

Golang Weekly #169

Toward Go 2 - The Go Blog

来ましたGo2!

1年後にリリース予定のGo 1.12から徐々に後方互換性のある機能をリリースしていき、1.20から後方互換性のない機能をGo2.0に入れ、1.20から2.0に移行しやすくしたいという流れになるみたいです。
他にもGoの開発プロセスについての解説もあるので、一読の価値ありです。

この記事は和訳されたものもありますので、英語が苦手な方はこちらを読んでみてください。

www.ymotongpoo.com

Strace in 60 lines of Go – Hacker Noon

LinuxのstraceコマンドをGoで実装してみた、という記事。

60行で実装できるものなのかと驚き。syscall packageはなかなか使うことがないので、使用例としてとても参考になる。

GitHub - 360EntSecGroup-Skylar/goreporter: A Golang tool that does static analysis, unit testing, code review and generate code quality report.

Goの静的解析・ユニットテスト・コードレビュー・コード品質チェックを一括で行い、結果をHTML形式で出力してくれるツール。
コードグラフなども出してくれて、なかなかに便利。

こちらに出力例があるので気になる方はチェック!

http://fiisio.me/pages/goreporter-report.html

Docker => Moby: Go Dependencies

DockerからMobyに名前が変更された結果、開発環境が動かなくなったよ事案。

元々は go get のみを使って開発をしていたようなのだが、

  • gvt を使う
  • GOPATHを各プロジェクト毎に設定する
  • /vendor を使わずに、 /src でベンダリングするようにMakefileを書く

で対処したという内容。

しかし、ここまで複雑なことをする必要が果たしてあるのだろうか・・・?🤔

dotGo

フランスで11月にGoConferenceが開催される模様。
Go関連でよく見る人達が登壇してますね!行きたい!

Go Reliability and Durability at Dropbox

DropboxでのGoの使用例、新しくジョインしたエンジニアへのアプローチなどなどが書いてあります。
最初は、Rate LimitingとThrottlingのツールをGoで作り、そこから社内にGoが広まっていったという。

sirupsen/logrusのユーザー名変更問題について

皆さんはGoでプログラミングする際にloggerは何を使ってるでしょうか?
様々なloggerがありますが、その中でも sirupsen/logrus を使っている方は多いと思います。

ただ、このlogrusに大きな問題が起こりました。
それはsirupsen氏がGithubのユーザー名をSirupsenからsirupsenにリネームしたことが発端でした。

一体何が起こったのか?

「ユーザー名のリネームくらい良いじゃない」と思われるかもしれませんが、これがlogrusを使ってる側からするとなかなか面倒な話になります。

例えば、glideやdepなどのパッケージマネージャを使っている場合には、一度 Sirupsen/logrus で保存されてしまったキャッシュをわざわざ削除し、 surupsen/logrus で新たにvendorにインストールし直さなれけばならないのです。

また、使用しているパッケージでの依存パッケージが Sirupsen/logrus となっている場合、これまたややこしい話になるのでglideでは以下のように対処したりします。

- package: github.com/sirupsen/logrus
  version: master
- package: github.com/Sirupsen/logrus
  repo: https://github.com/sirupsen/logrus.git
  version: master

Sirupsen/logrus でのVCSエンドポイントを sirupsen/logrus としてあげる形ですね。

こういった問題が起こったため、glideやdepなどのパッケージマネージャ・logrusで「Sirupsenがsirupsenになったせいでなんか動かなくなった!」的なIssueが乱立しました。

以下はその一部。

github.com

github.com

github.com

というわけで

いちユーザーとしては「何故ユーザー名変えたし・・・」という感想です。
先ほどの"Rename back to Sirupsen/logrus"のIssueでSirupsen氏が何故ユーザー名を変更したのか?について説明しているので、気になる方は是非読んでみてください。

個人的にこの問題が起こってzapとかに乗り換えた人が少なくないのかなと思ったり

Golang Weekly #168

GitHub - d4l3k/go-pry: An interactive REPL for Go that allows you to drop into your code at any point.

Goでのpry実装。
Rubyを書いていた時にbinding.pryを多用していたので、こちらも使っていきたい。

Benchmarking Go programs, part 2 - Tit Petric

Goにおける再帰処理、sync.Mutexでのdefer、sleepにおけるベンチマーキング。

  • 再帰処理は参照を用いることにより約30%の高速化
  • sync.MutexではdeferによるUnlockを行なう場合、メモリ確保を行なうので遅くなる、手動でやろう (ただし、Go1.9でdeferの最適化がなされているため、そんなに気にしなくてもいいかも)
  • 多くのgoroutine上でtime.sleepを実行すると、Go Schedulerの負荷が高くなりCPU使用率がえらいこっちゃになる

といったことを詳しくベンチマーク結果とともに書いてあります。

今回はここまで。
Go1.9では新しい追加機能の他、こういった細かい所のチューニングが楽しみですね💪

3連休を使ってしょうもないものを作ってしまった

素敵な3連休、皆様どうお過ごしでしょうか?

意識の高いエンジニア各位におかれましては、きっとエンジニアリングを磨き上げることに腐心なさっていることでしょう。

さて、そんな中「3連休中にアホなもの作りたい」という欲求を抑えきれずにアホなものを作ってしまいました。

その名も「go-kiriban」

github.com

なにこれ?

簡単に言うと「キリ番のプロセスIDがあればポップアップで教えてくれます」

f:id:syossan:20170717144027p:plain

なんで私はこんなものを作ってしまったのか・・・

技術的なお話

ここからは真面目に技術的な話をします。

今回のこのツールを作るに当たって、ザクッと以下のような仕様がありました。

  • goをデーモン化する
  • プロセスIDの取得
  • キリ番のプロセスIDがあれば何かしらで通知する

とりあえずこんな感じで実装進めていけばいけるでしょ、って謎の根拠を元に作り始めました。

goをデーモン化する

goのデーモン化については標準で備えているものがないため、自力でやる or ライブラリに頼るの二択になります。

自力でやるの選択肢を取る場合、

qiita.com

の記事が参考になるかと。

今回は楽にサクサクっとやりたかったので、ライブラリに頼ることにしました。

使ったライブラリはこちら。

github.com

コードの中身見たら分かるように、windowsdarwinfreebsdといった主要なOS毎に分けてあります。
とりあえずMacのみ対応させようと思ったので、launchdの仕組みを使ったdarwinのパッケージを使っていきます。

使い方はREADMEに書いてある通りで、Exampleの // Do something, call your goroutines, etc と書いてあるところに好きな処理を書いていく流れになります。

これで、goのdaemonizeは完了。

プロセスIDの取得

プロセスIDの取得にはこちらを使いました。

github.com

README・wikiともに詳しい説明がないので、気合でコード読んでいきましょう。

今回の場合では、 プロセスの一覧を取得プロセスのIDを参照 という2点を実現するために、以下のようなコードになりました。

processes := ps.Processes() // プロセスの一覧を取得

for _, p := range processes {
    fmt.Println(p.Pid()) // プロセスのIDの参照
}

go-psの中身はそんなに小難しくないので、使う分には困らないはず。

というわけでプロセスに関しても完了。

キリ番のプロセスIDがあれば何かしらで通知する

ここまではスイスイ出来たのですが、ここからがかなり難関でした。

最初、実装を考えた時に私の頭にあった通知形式はよくある右上にシュッと出てくる通知でした。

ただし、これをlaunchdに登録したプログラムから exec() で実行しようとすると、上手く動かないという問題にぶち当たりました。

原因としてはこの辺りだと思われるのですが、

apple.stackexchange.com

ちょっと提示されている解決法が良く分からなかったため、別のアプローチを取ることにしました。
それは display notification ではなく、 display dialog を使うアプローチです。

display dialog だと、表示の際にコントロールがダイアログに移ってしまうため、あまり使いたくなかったのですがとりあえず3連休中に作りきってしまいたかったために、止む無く使用することに。

こちらだと、launchdから exec() で実行しても動きます。

あとは、 giving up after 5 とかつけて良い感じに◯秒後にダイアログが消えるようにしたりとか。

完成

これでツールが完成しました!

実際は、同じプロセスIDの通知をしないようにoffsetつけたりとかしたのですが、その辺の細かいところはコード見てみてください。

たまには実用性とか何も考えずに、作ってみたいネタなツールを作ってみるのもありですね。

プログラミングは何も考えず楽しくやりましょう!!

depでの "is not within a known GOPATH" エラー in gvm

betaのgo1.9をちょこっと弄るためにgvmを導入したのですが、$GOPATHの扱いが $HOME/.gvm/pkgsets/go1.9beta2/global といった独自のものになります。

で、これの何が問題かというと、例えば普段設定している$GOPATHが $HOME/go だった場合には $HOME/go/src 直下にプロジェクトを作成してdepを使うと「$GOPATH内にねーよ」といって怒られます。

んじゃどうするかというと、とても簡単で gvm linkthis を実行します。

これを実行すると、現在のプロジェクトディレクトリをgvmでの$GOPATHの直下にlnしてくれます。
例えば $HOME/.gvm/pkgsets/go1.9beta2/global/src/hoge のような形ですね。

これでdepを実行すると無事動いてくれます👏