go

quic-goはどのようにUDPをコネクション指向で扱っているか

TCPは接続相手ごとに1本のコネクション(1つのsocket)を持ち、そこを通路として通信する。 しかし、UDPは異なる。1つのsocketであらゆる通信相手からのパケットを受け取る。 では、UDPで実装されたQUICはどのように接続相手ごとのコネクションを保持してい…

sync.Mutexを使って初歩的なミスで詰まった思い出

go

Goでコードを書いてて、排他制御のためsync.Mutexを使っていた。 テストしてると、ある時点でロック獲得待ちのままずっと止まってしまい「あれ・・・???」てなったので覚えてるうちにメモ。 原因:Lock()するメソッドの中でさらにLockするメソッドを呼ん…

context.Contextの親子とキャンセル処理の順序

go

非同期処理をキャンセルする機構としてよく使う context.Context Contextは親子関係が作れて、親をキャンセルするとその子孫も一緒にキャンセルされる。 一緒にといっても、親のキャンセルがトリガーなので、親がわずかに先にキャンセルされると考えるのが自…

Goでcallback patternを考える

go

プログラミング言語ではおなじみのcallbackについて、Goでどのように実装すると良いか考えた。 Goではcallbackよりもchannelが良い? まず、非同期な処理からの結果を通知するしくみとして、Goだとchannelが使える。 しかし、chnanelは双方向だったりcloseで…

GoでTCPソケットを読み書きするときに起こるエラー

ソケット通信は双方向で遠隔という複雑な条件下のためさまざまなエラーが発生する。 Goでソケット通信を書いていて、言語の力のおかげで記述は楽になっているが、下層で同じOSの機能を使っている以上エラーは避けられない。 そもそも、どんなときにどんなエ…

go run -race の有無で挙動が変わる例

go

goroutineを利用したプログラムではよく -race オプションをつけてデータ競合 (race condition) がないかチェックして開発する。 しかし、今日 -race をつけると挙動が変わるという現象に遭遇したのでそれを調べたメモ。 次のようなコードで再現可能。 packa…

GoLand で goenv のSDKをつかう

go

GoLand 上で指定した Go のバージョンでプログラムを動かしたい。 複数バージョンの Go を管理する goenv があるのでこれを使ったが、GoLand のエディタ上では自動的には認識してくれない。そこで goenv で指定したバージョンを GoLand にも認識させる作業が…

Go のエラー処理を整理

go

Go のエラー処理はけっこう独特。なにをもってエラーかというと、次の interface を満たすだけ。 type error interface { Error() string } めっちゃシンプル。でも、これだけで本当に実際にエラー処理やっていけるのか。 特定のエラーを判別する エラーによ…

Go のミドルウェア Adapter パターンに美しさを感じた話

medium.com 間に処理を差し込みたいとき、直接中身をいじるのではなく handler を引数にとって、新しい handler で返す関数(decorator pattern?) なのが良いね。 そして、Go の http.Handler の仕組みってすげーってなった。 handler は本来は Handle() を…

goroutine の数はどれくらいが良いのか

Go の主要な機能である Goroutine 好きなだけ並列に実行できるけど、増やしすぎるとかえって遅くなったりするのかどうなのか、気になった。 CPU処理か、IO処理かで変わる CPU処理であれば、CPU数以上上げても切り替わりが激しくなるだけで性能は上がらない I…