The Round

合同会社ナイツオの開発ブログ

静岡でGo言語やりたい人!!→こちら

GAE/Go でのGOPATH設定

Google App Engine for GoでのGOPATH設定についていろいろ試行錯誤したのでメモしておきます。 ベストプラクティスかどうかは分かりません。

わるいGOPATH

まず、今迄ずっとやっていて相当ストレスを感じていた悪いGOPATH設定を晒しておきます。

GAEアプリケーション単位でワークスペース(参考:How to Write Go Code - The Go Programming Language)ディレクトリを作成し、そこをGOPATHに設定していました。

hello    <- GOPATHはここに設定
    + src
        + app.yaml
        + hello.go

この状態でgoapp getすると、取得してきた3rd partyライブラリはapp/srcの下に入ります。

hello
    + src
        + github.com   <- ここにgoapp getされる
            + somelibs
        + app.yaml
        + hello.go

そうすると、以下の困ったことが起きます。

  • ライブラリをリポジトリ単位で取ってきてしまう(回避するoptionとかあるのかも)為、巨大なライブラリ群だと不要なコードまで取得される。
  • GAE/Goはアプリケーションディレクトリ以下のgoコードを全てコンパイルする仕様の為、ビルド時間が長くなる。Goの魅力半減(´・ω・`)
  • 不要なコード中に別のライブラリ依存があった場合、不要なのにそれもgoapp getしないとビルド通らない。
  • 不要なコード中でGAEで使えないpackage(syscall, unsafe, etc)が使われていた場合、deployできない。深刻!!

よいGOPATH

GOPATHを、どこでもよいですがアプリケーションディレクトリの外に設定します。

例↓

hello
    + gopath     <- GOPATH
    + src
        + github.com   <- ここにgoapp getされる
            + somelibs
    + app          <- アプリケーションディレクトリ
        + app.yaml
        + hello.go

アプリケーションディレクトリにはGOPATH設定する必要はありません。

こうすると、goapp getはリポジトリ毎ごっそりGOPATH/srcに取得しますが、ビルド時には必要なパッケージのみ参照してくれる様になります。 GOPATH内でGAE使用不可なパッケージが使用されていてもビルド可能です。※実際にはパッケージディレクトリ単位で参照している様なので、使用したいパッケージにGAE使用不可なコードが含まれている場合はビルド出来ません。

なお、この様にGOPATHを別にした場合、ローカル開発サーバー起動時にはGOPATH内のコードに対してGAE不正importチェックが働きません(SDK1.9.15現在)。なのでローカルではsyscallパッケージとか普通に実行出来たりします。deploy時にはチェックが働いてエラーになるので注意して下さい。

GAEではない通常のGo開発用にすでにGOPATHを設定していて、GAEでの開発でもそれを共有したい場合はそのままでOKです。

何らかの理由でアプリケーションディレクトリにもGOPATHを設定したい場合は、コロン(windowsはセミコロン)で区切って両方設定できます。goapp getは先頭のGOPATHにインストールしますのでライブラリ用GOPATHを先頭に設定しましょう。

その他GOPATH

GOPATHが設定されない場合、goappコマンドにより自動でGOPATHが設定されます。

appengine sdkの場合

<sdk root>/gopath

google cloud sdkの場合

<sdk root>/platform/google_appengine/gopath

設定されているGOPATH以下のコマンドで確認できます。

goapp env GOPATH

appengine SDKのgopathは、SDKのバージョン上げたらコピーするかgoapp getしなおさないとダメそうですね(未確認)。

cloud sdkの方はバージョン上げても引き継いでくれそうです(未確認)。

参考資料:

  • GOPATHについて

How to Write Go Code - The Go Programming Language

  • GAE/GoでのGOPATHサポートについて

The App Engine SDK and workspaces (GOPATH) - The Go Blog

ionicでAngularJSの$anchorScrollを使ってハマった

ionicでAngularJSの$anchorScrollを使ってハマった

だいぶお久しぶりになりますマツウラです。
今回はionic frameworkでAngularJSの$anchorScrollが期待通りに動作しなかったことについてです。

続きを読む

GAE/Go Ancestorクエリについて

どうもお久しぶりになります、マツウラです。
取り上げる内容は、Google App EngineのDatastoreにおけるAncestorクエリです。
今回Ancestorクエリについて調べたのは次の理由からです。

put直後にQueryで問い合わせたところ、putしたハズのEntityが取れなかったのです。

原因は単純なことでした。
データをRoot Entityとして扱っていたためです。
put直後であったため、インデックスの更新が間に合っていなかったようで結果に含まれなかったんですね。

これを解決したのがAncestorクエリでした。
どんなものか、概要をサラッと見てゆきたいと思います。

続きを読む

Google App EngineのModules・Versionsとqueueやcronの設定ファイルとの関連をいろいろ試してみた。

どうもこんにちわ。マツウラです。
今回はGAEアプリケーションのModulesやバージョンと、CronやTaskqueueの設定がどう関連しているのかをいろいろ試してみました。

続きを読む

Google App Engine for GoからBigQueryへStreaming Insertしてみる

こんちわ!マツウラです。
前回に引き続きGAE/GoからBigQuery APIを使用してみます。
今回は、BigQueryにデータのリアルタイム挿入を行うStreaming Insertをやってみます。

続きを読む

Google App Engine for GoからBigQuery APIを使ってみる

どうもこんにちわ!マツウラです。
今回はGAE/Goと、BigQueryの組み合わせです。
BigQueryにデータセットを用意して、クエリを実行するところまでやっていこうと思います。

続きを読む

Go言語のstring, runeの正体とは? - golang

Ikedaです。

Goのstringとruneについて曖昧な知識のまま使ってきたが、そろそろちゃんと理解しようと思って下記事を読みました。

Strings, bytes, runes and characters in Go - The Go Blog

ざっくりと抜粋。

  • stringは実質read-onlyなbyteスライス。中身はUTF-8とは限らない
  • GoのソースコードUTF-8で書くルール
  • ソースがちゃんとUTF-8で書かれていればリテラルで初期化されたstringはUTF-8になるはず
  • len(string)はbyte数返す
  • string[n]はインデックスnのbyte(int8)
const sample = "日本語"
for i := 0; i < len(sample); i++ {
        fmt.Printf("%x ", sample[i])
}

↓結果

e6 97 a5 e6 9c ac e8 aa 9e 
  • runeはUnicodeのコードポイント。int32のalias
  • (UTF-8の)stringをrangeで回すとruneが取れる
const nihongo = "日本語"
for index, runeValue := range nihongo {
        fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
}

↓結果

U+65E5 '日' starts at byte position 0
U+672C '本' starts at byte position 3
U+8A9E '語' starts at byte position 6
  • runeでもっと凝ったことしたければ unicode/utf8パッケージ使え

φ( ̄^ ̄ )メモメモ