- 投稿日:2019-08-30T23:55:28+09:00
goleakでgoroutine leakのリスクを減らす
このページについて
uberが手掛けているgoleakを使ってgoroutine leakを検出できるか試してみました。簡単なデモコードではしっかりエラーにしてくれたので、使ってみてもよいのかなと思います。
現在(2019-08)α版 なのでもう少し待ってみてもいいかもしれませんが、、
内容
goroutine leakの起こる関数を書き、goleakを使って検出できるか試してみます。
関数
package helper import ( "fmt" "time" ) func Leak(sleep int) { fmt.Println("leak test") go func() { fmt.Println("start goroutine") for { // leak しないパターンも試す if sleep == 0 { return } time.Sleep(time.Duration(sleep) * time.Second) } }() }テスト
leak_test.gopackage helper import "testing" func TestLeak(t *testing.T) { type args struct { sleep int } tests := []struct { name string args args }{ { name: "leak", args: args{ sleep: 1, }, }, { name: "not leak", args: args{ sleep: 0, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { Leak(tt.args.sleep) }) } }goleakはパッケージ全体に適用したい場合はTestMainから動かすと良いみたいです
main_test.gopackage helper import ( "testing" "go.uber.org/goleak" ) func TestMain(m *testing.M) { goleak.VerifyTestMain(m) }これで準備は整いました。
テストを実行します$ go test -v ./... === RUN TestLeak === RUN TestLeak/leak leak test start goroutine === RUN TestLeak/not_leak leak test start goroutine --- PASS: TestLeak (0.00s) --- PASS: TestLeak/leak (0.00s) --- PASS: TestLeak/not_leak (0.00s) PASS coverage: 100.0% of statements goleak: Errors on successful test run: found unexpected goroutines: [Goroutine 33 in state sleep, with runtime.goparkunlock on top of the stack: goroutine 33 [sleep]: runtime.goparkunlock(...) /usr/local/Cellar/go/1.12.1/libexec/src/runtime/proc.go:307 time.Sleep(0x3b9aca00) /usr/local/Cellar/go/1.12.1/libexec/src/runtime/time.go:105 +0x159 github.com/smith-30/ootd/helper.Leak.func1(0x1) /go/src/github.com/smith-30/ootd/helper/leak.go:16 +0xa0 created by github.com/smith-30/ootd/helper.Leak /go/src/github.com/smith-30/ootd/helper/leak.go:10 +0xa6 ] FAIL github.com/smith-30/ootd/helper 0.457s Error: Tests failed.goroutineリークを検出してテストを落としてくれていますね!
もちろん、テストケースがnot leak
のみの場合はエラーで落ちません
goroutineをバリバリ使うデーモンや並列処理を使うAPIのメインロジックのe2eテストの際には使っていきたいと思っています。
- 投稿日:2019-08-30T18:37:52+09:00
golangを触った初日メモ
概要
知ったことをメモする。
golang幼稚園生?ライブラリ
Left align Right align realize ホットリロード goose DBマイグレーション siris Webアプリケーションフレームワーク go-cmp 値比較 pprof プロファイリング guregu/null 変数にnullが入ってきたときに型のデフォルト値にするのではなくnullとして扱えるようにする hashicorp/golang-lru LRUキャッシュ gorm ORM julienschmidt/httprouter ルーティング kr/pty unix操作するやつ labstack/echo Webサーバー go-urn URNパーサー Log出力
import "log" func main() { log.Print("hoge") }実行結果
# go run main.go 2019/08/30 09:20:52 hogeechoのサーバー起動
import "github.com/labstack/echo/v4" func main() { e := echo.New() }# go run main.go ____ __ / __/___/ / ___ / _// __/ _ \/ _ \ /___/\__/_//_/\___/ v4.1.5 High performance, minimalist Go web framework https://echo.labstack.com ____________________________________O/_______ O\ ⇨ http server started on [::]:8081
- 投稿日:2019-08-30T11:15:38+09:00
GORM エラーハンドリング
user, err := module.Configure.Repositories.UserRepository.FindByID(id) // データがない時のエラー if err == gorm.ErrRecordNotFound { c.JSON(http.StatusNotFound, gin.H{"error": fmt.Sprintf("reservation number not found")}) return } // その他のエラー if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return }
err == gorm.ErrRecordNotFound
の時はhttp.StatusNotFound
http.StatusInternalServerError
http.StatusBadRequest
http.StatusNotFound 404 // 欲しいデータが見つからない。 http.StatusBadRequest 400 // リクエストがおかしい type reqParams struct { user_id uint64 } なのにstring でパラメーターを送ってしまったとか。 http.StatusInternalServerError 500 // サーバーと接続ができない //サーバーがダウンしているなど。
- 投稿日:2019-08-30T02:57:01+09:00
Go言語+VSCodeで"run test"を押したときにも.envの環境変数を適用
はじめに
VSCodeでGoのコードを書いている場合、任意の関数・メソッド内で右クリックメニューから
Go: Generate Unit Tests For Function
を押すだけでテーブルテスト形式のテストが
編集中ファイル名_test.go
に自動生成され、さらにテスト関数の上に出るコードレンズのリンク
run test
をポチるだけでテスト実行できます。
ドチャクソ便利ですね。
↑これでも上記テストを実行する環境はVSCodeを開いた環境なので、
.env
等で環境変数を管理していると適用されません。.envを使用するように設定を変更
Goのextentionには標準で設定項目が用意されているので、
そこに.envファイルのパスを指定するだけでOKです。(開いているワークスペース直下に
.env
ファイルが有ると仮定します。)
VSCodeの設定画面を開き、Go configurationのTest Env File
テキストフィールドに${workspaceFolder}/.env
と指定しましょう。これだけでOKです。
あ、これはユーザー設定というよりPJに依存した設定であることが多いと思うので
User SettingsではなくWorkspase Settingsの方に書いたほうがいいかもしれません。おまけ
スクショに見えている
Test Env Vars
を編集でもテスト開始前に環境変数をセットできます。
また、Test Flags
をsettings.json
上で編集("go.testFlags": ["-v"],
を追加)して
-v
をつけておけば、テスト中に標準出力に吐かれたログを見ることができるので
テストがサイレント落ちして理由わかんねーよって時には威力を発揮します。
- 投稿日:2019-08-30T00:15:17+09:00
Win10にてパッケージ管理(chocolatey)を使ってGo言語をインストール
目的
- WindowsでもLinuxのようにパッケージ管理を使ってソフトを管理したい
Chocolatey(パッケージ管理)のインストール
(以下、公式サイトの手順)
管理者権限でコマンドプロンプトを起動
インストール実行
コマンドプロンプトで以下を実行@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"ちなみに管理者権限でコマンドプロンプト起動しないと実行時に以下のエラーになります。
コマンドプロンプトでバージョン確認
コマンドプロンプトで以下を実行C:\Windows\system32>choco Chocolatey v0.10.15 Please run 'choco -?' or 'choco <command> -?' for help menu.パッケージ管理からGo言語(Golang)のインストール
コマンドプロンプトで以下を実行C:\Windows\system32>choco install golangチョコってコマンドが個人的に好きです。