YAMAGUCHI::weblog

海水パンツとゴーグルで、巨万の富を築きました。カリブの怪物、フリーアルバイター瞳です。

OSCON 2013でのGo関連の発表

はじめに

こんにちは、Go界の平賀源内です。さて、先月末にOSCON 2013がオレゴンで開催されましたが、その中発表でいくつかGo関連で話題になったものもあったので、一つまとめてみようと思います。

Go関連の発表

Go関連の発表は以下の7つでした。(発表時間順)

特に最後の @bradfitz による dl.google.com をGoで置き換えた話はかなり話題になっていましたね。というわけで以下、僕が注目した順に簡単に内容を紹介します。

dl.google.com: powered by Go (by Brad Fitzpatrick)

スライドはGo製のオリジナルツールで次のURLでホスティングされています。

数多の著名なオープンソースプロダクトを作ってきた @bradfitz 先輩ですが、いまはGoのコアチームで働いています。そんな彼が、Google社内でプロダクションユースでGoが使われている例としてdl.google.comをC++からGoに移植した例を紹介し、その中で使われているgroupcacheについても紹介しています。

スライド概要

  • (スライド #01-#11)Googleのコンテンツダウンロード用サーバであるdl.google.comは、元々2007年にC++で実装されていたが、リクエストが増加するに連れてサーバが逼迫され、速度が有り得ないほど遅くなったので、 @bradfitz はじめとするGoチームが「俺らが書き換えてやるよ!」と言って2012年に書き換えた。
  • (スライド #12-#17)ここで「なぜコードは悪くなっていくのか」について語っている。はじめは良くても、複雑な要件に対応するためコードも複雑になり、また前提とする環境やスケール感も変わり、さらにドキュメントやテストもないハックやワークアラウンドが増え、メンテナーもどんどん出入りし、あるいは出て行くだけで、メンテがされなくなっていくためである。
  • (スライド #18-#19) Googleでは上に挙げたような前提が日々変化していて、開発当時は素晴らしかったコードもすぐに古びたものになってしまう。実際にdl.google.comの場合は、シングルスレッドのイベントループが実装されていて、マルチコアCPUでも1コアしか消費せずに固まっていた。
  • (スライド #20-#30) 根本原因はシングルスレッドのイベントループとコンテンツをローカルディスクから配布していたことにあり、それを回避するために諸々行ったが、そもそものイベントループ内でNバイトのデータをコピーするだけでありえない量のコードを書かなければいけなかった。(node.js、Twisted等々他のイベントループを持つフレームワークでも同様)
  • (スライド #31-#34) Goではそもそも並列性が言語仕様レベルでサポートされてるので、さらっと書けた。その後、少しずつ既存のC++製の部分を置き換えていって、最終的にGo製に置き換わって、遅かったローカルディスクからのデータ読み込みもblobstoreを使うようになり、スタートアップも早くなった。
  • (スライド #35-#42)dl.google.comではほぼ標準パッケージしか使っていない。net/http、ioのパッケージ内にファイルサーバに必要な型や関数がすべて定義されている。
  • (スライド #43-#47)groupcacheの紹介。memcachedの代替をするクライアントとサーバ両方のためのライブラリ。poolとpeerを宣言して、その後グローバルで一意なgroupを宣言する。groupにキーを指定すると値が取れる。groupはpeerグループ内で共有され、キーに対応する値はpeerグループ内のいずれかのpeerから取得される。 
  • (スライド #48-#54)dl.google.comではchunkとio.SectionReaderをうまく使い、複数の値を読み込んでデータを結合して返している。結果としてHTTPの煩わしいロジックから開放され、純粋にビジネスロジックの実装に集中できた。
  • (スライド #55-#58)サービス自体をバイナリ1つに出来たし、すごくよかった。
  • (スライド #59)いいことづくめ
  • (スライド #60-#63)C++版を再実装する理由が見当たらない。dl.google.comの内容はほとんどオープンソースになってるからみんな使ってね。

というわけで、groupcacheがこの日に公開されました。

Go Best Practices (by Francesc Campoy Flores)

こちらもGoのコアチームにいる @compoy83 からのGoのベストプラクティス集。 @bradfitz のプレゼンはGoの啓蒙寄りな内容だったのに対し、こちらはすでにGoを書いているエンジニアを対象としたノウハウ集でした。挙げられていたベストプラクティスは次のとおり。

こちらもスライドはgo.talksに置いてある。

ベストプラクティスの内容は次の通り。

  1. エラーハンドリングをまず行い、ifのネストを避けろ
  2. エラーハンドリングの繰り返しを避けるために、一時的な型を作る。必要であればtype switchで例外的処理を扱ったり、switchで変数宣言する。関数アダプタを使って例外処理とロジックを分ける。
  3. 大事な情報から先に書く。ライセンス情報やドキュメント。import内ではグループ(標準パッケージ or 3rd party)ごとに空行で区切りをつける。補助関数や補助的な型は後ろの方に書く。
  4. ドキュメントを書く
  5. 命名時は読んで意味が分かる一番短い名前を付けるように努める
  6. パッケージは複数ファイルで構成する。net/httpを例として次の3つの規則を紹介。「長いファイルは分割する」「テストと本体は分ける」「ドキュメントもdoc.goというファイルに分ける」
  7. パッケージを"go get"した時に便利なようにする
  8. 本当に必要なものを書く。structでなくinterfaceを引数に取ることでテストしやすくなる。
  9. 独立したパッケージをきちんと分けておく。
  10. API内で並列なコードを避ける。同期なAPIを提供すれば、呼び出し側で簡単に並列にできる。
  11. 状態管理にgoroutineを使う。
  12. goroutineリークを避ける。buffered channelやquit channelを使う。

Go Language for Ops and Site Reliability Engineering (by Gustavo Franco)

GoogleのSites Reliability Engineer(インフラ部隊)の人が語るGo言語。このプレゼンはOSCONの3ヶ月前にO'Reilly主催のHangout on Airで既に話されていましたので、動画も貼りました。いわゆるアプリケーションエンジニアとは異なる観点からのGo言語の評価、という点で興味深いプレゼンです。


O'Reilly Webcast: Go Language for Ops and Site ...

スライドの要点は下記

  • インフラエンジニアからしたら、ただ書き捨てのスクリプトが欲しいだけで、新しい言語は覚えたくない。ワンライナーは便利なので使い続けるけど、できれば道具として見れる言語を少しだけ覚えるだけに留めたい。
  • その点でGoは、オープンソースだし、バイナリが出来ればそれを動かすだけで済むし、ビルドファイルは要らないし、ビルドも速いし、GCはあるし、読みやすいし、RE2は使えるし、テスト、ベンチマーク、プロファイラが全部標準で入ってるので楽。標準パッケージが豊富なのも良い。
  • またgoroutineとchannelを用いた並列性のサポートがはじめからあるのもよい。
  • 最近のLLが持っているような特徴も兼ね備えていて良い。(map、slice、モジュール機構、struct、メソッド、ポインタ演算のないポインタ)
  • Google社内はもちろん、Google外にも多くのプロダクションレベルのインフラ環境での利用がある。

啓蒙という視点ではなく、現実的な視点からプロダクションに耐える言語だということを説明しているプレゼンでした。

Rethinking Errors: Learning from Scala and Go (by Bruce Eckel)

今回のOSCONでは珍しいGoogler以外からのGoのプレゼン。その意味で、非常に貴重だし、なによりGoを始めるとすぐに取り沙汰されるGoにおけるエラー処理を言及したプレゼン。資料はこちら。タイトルにはGoとScalaしか書いてないけど、むしろサンプルはPythonで説明している。

スライドの要点

  • 新しいエラー処理機構の潮流として正常系の返り値とエラーを同時に返すというやり方がある
  • C, C++, Java, Python, Ruby, PHPと、数値またはシグナルを返すところから始まったエラー通知が徐々に例外処理へと変化していったが、制限も大きかった。
  • Goは初期はエラー処理機構はなく後からpanicとrecoverが追加され、ScalaではEitherまたは専用型で、Pythonでは例外以外にもGoのようにタプルでエラーを返したり専用オブジェクトを返す方法をとれる
  • Pythonでの例ではあるが、スピーカーの結論は必要以外には例外処理を使わず、通常の分岐処理で対応できるようにしよう、という事のようです。

Goの話はタプルで正常値とエラーを同時に返して、通常の分岐処理で対応できている点がいいね、という話しか出てきてなかったです。

How Learning Go Made Me A Better Programmer (by Johan Euphrosine)

こちらはGoogle App EngineのDeveloper Program Engineerの @proppy による、Goの優れたところ紹介集。時々PythonJava、node.jsとの比較をしながらGoの良いところを挙げている。

このスライドで上がっているのは次の点

  • 可読性(Pythonとの比較。ほぼPseudo Codeだよ。言語仕様だけでなく、go fmtなどのツールが標準であるのも良い)
  • エラーハンドリング(PythonJava、node.js、Haskell、Rustとの比較。
  • 標準パッケージ(非常にリッチ。Pythonと比較してもリッチ。)
  • XMLとJSONの扱い(標準パッケージでサポートされている。XMLとJSONの扱いで一貫性がある。Pythonとの比較。)
  • パッケージングと配布(ツールが良きに計らってくれて非常に楽。ビルドファイル要らない。PythonJava、node.jsとの比較)
  • ツール(標準でテスト、文法チェック、パッケージング等々行なってくれる。Python、node.jsとの比較)
  • 並列性のサポート(ランタイムに含まれている。node.js、Pythonとの比較。)
  • Interface(暗黙的に判定、Compositionも可能。Pythonのduck typingとの比較。)
  • Composition(複数のstructを組み合わせられる。Interfaceと直交する機能。PythonRubyのmixinとの比較。)
  • Community(もりあがってるよ)

Introduction to Go (by Francesc Campoy Flores)

"A Tour of Go" を使ったチュートリアルセッションでした。みなさんもGoを始める時はまずは"A Tour of Go"で文法を学ぶのがベスト。(演習問題は飛ばしていいと思う。)

Office Hour with the Gophers (by Brad Fitzpatrick, Johan Euphrosine, Francesc Campoy Flores)

オフィスアワーです。僕も @bradfitz と @compoy83 にまだ直接会って話したこと無いので話してみたい。 @proppy はもしかすると今度のPyCon APAC 2013に来るよ。

おわりに

Goはまだまだ若い言語ですが、OSCONのような場所でしっかりと実例を紹介できるところまで来ていると認識出来たのは素晴らしいですね。groupcacheは今回の目玉でしたが、Google SREのGastavoのスライドにあったように、DockerやPackerやJujuといったインフラ系のツールにGoが使われている点で、流行り廃りでない、本物の存在感を感じ取ることが出来るような気がします。

これからのGoが楽しみですね!

Google画像検索を使って偽アカウント判定

はじめに

こんにちは、Go界の谷崎潤一郎です。さて、半年ほど前に一時期Facebookの偽アカウントが大量発生しましたが、今もまだしぶとく偽アカウントが発生しているようです。 IT系の知り合いはあまり引っかかってないようですが、地元の友達などは結構簡単に友だち登録してしまっているようです。 可愛いお姉さんのプロフィール写真があったら許可したくなっちゃいますよね。 でも、色々と危ないんで、スパムアカウントは運営にブロック申請したほうがいいです。まじで。

Google画像検索

しかし、プロフィール写真の可愛いお姉さんが本当にその人なのかどうかは気になっちゃうと思うので、その判定方法を教えます。Google画像検索です。 おあつらえ向きに偽アカウントが友達申請してきたので実際に確認してみます。

f:id:ymotongpoo:20130803095720p:plain

写真も可愛らしいうえに、プロフィールで出身地が僕の地元の山梨県。しかも既に僕の地元の友達が2人友達になってしまっていますね。 しかしプロフィールが生まれ年と出身地しか無い上に、投稿がプロフィール写真と背景画像の投稿だけという、非常に偽アカウント臭が漂うアカウントです。 早速プロフィール写真をGoogle画像検索にかけてみます。まず画像のURLをコピー。

f:id:ymotongpoo:20130803100547p:plain

Googleトップから画像検索に行く。

f:id:ymotongpoo:20130803100231p:plain

カメラのアイコンを押して、さきほどの画像URLを貼り付けて検索。

f:id:ymotongpoo:20130803100737p:plain

f:id:ymotongpoo:20130803100751p:plain

すると、検索結果に台湾ドメインのウェブサイトのURLが出て来ました!

f:id:ymotongpoo:20130803100943p:plain

どうやらこのお姉さんは台湾のどこかにいるようです。

おわりに

いくらプロフィール写真が可愛いからってホイホイ友達申請許可してはダメです。

#Go羅温泉 #電車でGo というイベントをしてきました

はじめに

こんにちは、Go界のアインシュテュルツェンデ・ノイバウテンです。7月にGo界隈の人々でイベントをしてきましたのでここにご報告します。

Go羅温泉

Pythonコミュニティも大きくなりましたが、その中で「Python温泉」というイベントがあります。「ドキッ、男だらけの(ry」状態な2泊3日のハッカソンイベントなわけですが、Goのコミュニティの一でもそういうことしたいよねえ、ということで、箱根温泉街の強羅温泉に行ってきました。 朝9:00に新宿に集合して、余裕のロマンスカー乗車で、箱根でちょっと観光しようと思っていたのに、当日はロマンスカーが全部運休、箱根登山鉄道もなかなかの混み具合で大変でした。 ラフォーレ強羅の会議室はなかなか広く、結構快適でした。

IMG_20130706_134530

皆それぞれに持ってきた課題を結構こなせたようで、僕にとっても皆さんにとっても実りある温泉旅行でした。以下、ハイライト箇条書き。

  • LiveLeak.comでロシア人の動画を探しているとかなりクレイジー
  • goclipseはいろいろ動かすのがしんどそうなのでやめとこう
  • 強羅温泉は箱根湯本から結構遠い
  • ラフォーレ強羅の周辺は徒歩30分圏内にはコンビニがないので気をつけろ

幹事行をしてくださった、 @Jxck_ さん、ありがとうございました!

電車でGo

Go羅温泉のあとに「電車でGo」というイベントを行いました。

募集告知をした直後にはキチガイイベント認定されました。

実際に行なってみると非常に楽しいイベントで、お子さん連れの参加者も楽しんでくれたようです。なによりお子さんが楽しんでくれました。 貸切の都電荒川線。「前にGopher人形乗せていいですか?」と運転手さんに聞いたら「はいはい、なんでも置きな!」とのこと。フランクすぎる。

R0010354

ハッカソン中の様子

R0010362

都電荒川線の醍醐味、飛鳥山周辺での路面。

R0010365

最後三ノ輪橋駅での記念撮影。

R0010379

撮影の @nuki_pon さん、ありがとうございました!

Goコミュニティではこれからもネタドリブンのイベントをどんどん行なっていこうと思います。どうぞよろしくお願いします。

パスポート盗まれて何とか帰国したけど事後処理めんどくさかった事件

はじめに

こんにちは、Go界のジャック・ニコルソンです。2ヶ月弱前のエントリで、San Franciscoでパスポート盗まれてめんどくさかった、という話を書いたんですが、帰ってきてからもさらに事後始末がめんどくさかったんで記録を残しておきます。

前回までのあらすじ

ベイエリアへの1ヶ月出張からの帰国2日前にSan Francisco市内で車上荒らしにあって、パスポート等が入ったバックパックを盗まれた。諸々とゴタゴタあったが、なんとか帰国できた。

後始末

戸籍謄本(戸籍抄本)の提出

在サンフランシスコ総領事館で「帰国のための渡航書」を発行してもらったのですが、その際に「帰国後に戸籍謄本(戸籍抄本)を提出します」という誓約書を書かされます。戸籍謄本(戸籍抄本)を在サンフランシスコ総領事館に送付します。

Consulate-General of Japan, Passport Div.

50 Freemont St. Suite #2300, San Francisco, 94105

盗難保険のための報告書提出

幸いにも加入しているカードでは海外旅行中での盗難が保険でカバーされるとの事だったので、早速申請書を作成しましたが、これがまた非常に面倒。 書類で求められるものは各保険会社によって異なると思いますが、自分の場合には次の内容の提出を求められました。

  • 事件遭遇時の状況説明
  • 三者による証明(もしくは自認書)
  • 補填金振込用口座
  • 盗難された物品一覧の名前、ブランド、購入年月、購入時の実際の値段
  • 日本入出国確認用のパスポートのコピー(自分の場合は帰国のみしかスタンプがないので、飛行機のeチケットの控えもコピー)
  • 現地警察への被害届控え

申請書提出からは1週間程度で保険金が振り込まれました。保険金は次のような計算式でした。(これは保険会社によって変わると思います)

  • 被害1件の処理につき3000円の手数料
  • 盗難物は購入時金額から購入時より半年で5%の減価償却費が引かれた分が帰ってくる。

というわけで、結局どれも購入時期が2年以内のものばかりだったので、購入時金額の合計の9割程度が戻ってきました。

ESTA

パスポートを失効したので、ESTAも無効になります。次に渡米するまでに再申請しなければいけません。

おわりに

帰国後も面倒なことになるので、やっぱり盗難事故に遭わないように、細心の注意を払うしかないですね。

Emacsを使ったGo言語開発手法(2013.07版)

はじめに

こんにちは、Go界の橋爪功です。以前mattnさんがVimを使ったGoの開発環境というエントリを書かれていたんですが、自分用にもEmacs版を、と思ったので、まとめておきます。

基礎からわかる Go言語

基礎からわかる Go言語

参考

設定

Go mode

Go用のメジャーモードのGo modeというのが標準で配布されています。使いましょう。load-pathにgo-mode.elとgo-mode-load.elを突っ込んでおきます。

(require 'go-mode-load)
(add-hook 'go-mode-hook
          '(lambda()
            (setq c-basic-offset 4)
            (setq indent-tabs-mode t)
            (local-set-key (kbd "M-.") 'godef-jump)
            (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)
            (local-set-key (kbd "C-c i") 'go-goto-imports)
            (local-set-key (kbd "C-c d") 'godoc)))

(add-hook 'before-save-hook 'gofmt-before-save)

Goでは標準のインデントはハードタブなのでindent-tabs-modeはtにしておいたほうがいいでしょう。「俺はハードタブなんか使いたくない!」と駄々をこねても、どうせgofmtで修正されるので諦めてください。

コードジャンプ

godef

godefを入れておくとTAGSを作成せずとも定義元まで参照できて大変便利です。

% go get code.google.com/p/rog-go/exp/cmd/godef

ctags (etags, Exuberant Ctags)

ソースコードの検索にetags使いたいんですが、まだGo言語にはデフォルトでは対応してません。でも下記の.ctagsファイル書いておけばtagsファイル生成できます。

--langdef=Go
--langmap=Go:.go
--regex-Go=/func([ \t]+\([^)]+\))?[ \t]+([a-zA-Z0-9_]+)/\2/d,func/
--regex-Go=/var[ \t]+([a-zA-Z_][a-zA-Z0-9_]+)/\1/d,var/
--regex-Go=/const[ \t]+([a-zA-Z_][a-zA-Z0-9_]+)/\1/d,const/
--regex-Go=/type[ \t]+([a-zA-Z_][a-zA-Z0-9_]+)/\1/d,type/

これを ~/.ctags として通常のctagsと同様プロジェクト内で次のコマンド実行するとEmacs用のTAGSファイルが作成される。

% cd /path/to/project
% ctags -Re

あとは M-x visit-tags-table で作成されたTAGSファイルを指定して M-. でジャンプするだけ。(上記のelispでgo-modeで定義されたgodef-jumpを利用するように変更している)

auto-complete + gocode

mattnさんの記事にもありますが、gocodeを使って自動補完を有効にします。

auto-complete

そういえば以前のものから更新してなかったので、更新しがてらinit.elの設定を確認。

(add-to-list 'load-path "~/.emacs.d/auto-complete")

;;;; auto-complete
(require 'auto-complete-config)
(global-auto-complete-mode t)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict")
(ac-config-default)

gocode

まずはgocodeを設定します。mattnさんのブログにあるようにGOPATHとPATHをちゃんと確認してgo getで持ってくる。

% GOPATH=/path/to/project
% PATH=$GOPATH/bin:$PATH
% go get -u https://github.com/nsf/gocode

次に go-autocomplete.el をload-pathが通っているディレクトリに突っ込んでおく。

init.elにGo modeではM-TABでauto-completeを起動するように設定を追加。(上記のものを編集)

(add-hook 'go-mode-hook
          '(lambda()
            (setq c-basic-offset 4)
            (setq indent-tabs-mode t)
            (local-set-key (kbd "M-." 'godef-jump)
            (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)
            (local-set-key (kbd "C-c i") 'go-goto-imports)
            (local-set-key (kbd "C-c d") 'godoc)
            (define-key ac-mode-map (kbd "M-TAB") 'auto-complete)))

あとは C-c C-a のimport packageを使えばだいたい幸せです。