SlideShare a Scribd company logo
1 of 77
Download to read offline
Goらしい
APIを求める旅路
GoCon 2018 Spring Apr 15 2018
Daisuke Maki @lestrrat (HDE inc)
• @lestrrat
• Perl/Go hacker, author, father
• Author of github.com/peco/peco
• Organizer for builderscon
<宣伝>
http://blog.builderscon.io/entry/call-for-sponsors-2018
スポンサー募集、今月末まで!
お題
「Goっぽい」コード
Goを使うなら
なるたけGoっぽいAPIがいい
Goを使うなら
なるたけGoっぽいAPIがいい
github.com/cenkalti/backoff
backoff.Retry(f, strategy)
github.com/cenkalti/backoff
backoff.Retry(f, strategy)
[func() error]
Callback/Closure
• 関数を受け取るAPIでは、シグネチャがポイ
ントになる
• 関数を許すからにはadhocな関数呼び出しが
できるべき
net/http
type HandleFunc func(ResponseWriter, *Request)
• net/httpでこの関数の副作用は気にしない
でよい
• AdhocなHandlerをポンポン登録できる
backoff.Retry(f, stretegy)
func Foo() (Result, Result, Result, error)
What About…
backoff.Retry(Foo, …)
This no worky…
backoff.Retry(Foo, …)
This no worky…
signatureが合わない
backoff.Retry(func() error {
a, b, c, err := Foo()
if err != nil {
return err
}
}, …)
Capture Return Values
backoff.Retry(func() error {
a, b, c, err := Foo()
if err != nil {
return err
}
}, …)
Capture Return Values
この戻り値をRetryの外側で使うには?
var a, b, c Result
backoff.Retry(func() error {
a, b, c, err := Foo()
if err != nil {
return err
}
}, …)
Upper Scope
var a, b, c Result
backoff.Retry(func() error {
a, b, c, err := Foo()
if err != nil {
return err
}
}, …)
Upper Scope
あ!
var a, b, c Result
backoff.Retry(func() error {
a, b, c, err = Foo()
if err != nil {
return err
}
}, …)
Final Result
ちょっとまった!
• スコープを気にしながらコードを書かな
いといけない
• := と = を間違ってもコンパイラが怒っ
てくれない
• 毎回ムダ?にクロージャを作ってて
どんなAPIだと ?
+
拡張性を持たせられる?
Use Interface?
backoff.Retry(f, stretegy)
Use Interface?
backoff.Retry(f, stretegy)
type Operation interface {
Do() error
}
type FooWrapper struct {
A Result
B Result
C Result
}
func (f *FooWrapper) Do() error {
f.A, f.B, f.C, err = Foo()
…
}
Store The Results
var f FooWrapper
backoff.Retry(f, …)
// Use f.A, f.B, f.C
Final Result
var f FooWrapper
backoff.Retry(f, …)
// Use f.A, f.B, f.C
Final Result
「これじゃない感」…
毎回型を作る必要がある…
たとえばadhocな関数は?
type OperationFunc func() error
func (f OperationFunc) Do() error {
return f()
}
Adhoc Functions?
type OperationFunc func() error
func (f OperationFunc) Do() error {
return f()
}
Adhoc Functions?
http.HandlerFuncと同じ
形にすればキレイになる?
var a, b, c Result
backoff.Retry(OperationFunc(func() error {
a, b, c, err = Foo()
if err != nil {
return err
}
}), …)
あ、これ前と同じだ
小細工では同じような形に
なってしまう
一歩引いて考え直す…
backoffは何をするのか
• 関数を実行する
• 成功したら終わる
• 失敗したら、待つ
• optional: context.Contextで途中停止
for {
if err := f(); err == nil {
return
}
time.Sleep(delay)
}
First pass
for {
if err := f(); err == nil {
return
}
time.Sleep(delay)
}
First pass
関数を実行する
成功したら終わる
失敗したら待つ
backoffは何をするのか
• 関数を実行する
• 成功したら終わる
• 失敗したら、待ち時間を増やしながら待つ
• optional: context.Contextで途中停止
for {
if err := f(); err == nil {
return
}
select {
case <-ctx.Done():
return
case <-time.After(nextDelay()):
}
}
Second pass
for {
if err := f(); err == nil {
return
}
select {
case <-ctx.Done():
return
case <-time.After(nextDelay()):
}
}
Second pass
関数を実行する
成功したら終わる
for {
if err := f(); err == nil {
return
}
select {
case <-ctx.Done():
return
case <-time.After(nextDelay()):
}
}
Second pass
関数を実行する
成功したら終わる
失敗したら待ち時間を
増やしながら待つ
context.Contextで
途中停止
この形を簡単に書けるように
すればいいはず…
github.com/lestrrat-go/backoff
policy := backoff.NewExponential(…)
Backoff Policy Object
b, cancel := policy.Start(ctx)
Backoff object
b, cancel := policy.Start(ctx)
defer cancel()
for {
if err := f(); err == nil {
return
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
b, cancel := policy.Start(ctx)
defer cancel()
for {
if err := f(); err == nil {
return
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
<-chan time.Time
<-chan struct{}
ただのコードブロックなので
戻り値も自由自在
b, cancel := policy.Start(ctx)
defer cancel()
for {
a, b, c, err := f()
if err == nil {
// use or return a, b, c here
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
b, cancel := policy.Start(ctx)
defer cancel()
for {
a, b, c, err := f()
if err == nil {
// use or return a, b, c here
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
Bonus: separate Policy/Backoff
b := cenkalti.NewExponential()
for … {
go func(b cenkalti.Backoff) {
// b is shared… be careful!
}(b)
}
bを共有せざるを得ない
for … {
go func(b backoff.Backoff, cancel func()) {
// b is safe to be used in a separate goroutine
}(policy.Start(ctx))
}
共有されるpolicyとbは別
Problem:
Boilerplate Code is Long
b, cancel := policy.Start(ctx)
defer cancel()
for {
a, b, c, err := f()
if err == nil {
return
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
b, cancel := policy.Start(ctx)
defer cancel()
for {
a, b, c, err := f()
if err == nil {
return
}
select {
case <-b.Done():
return
case <-b.Next():
}
}
for {
select {
case <-b.Done():
return
case <-b.Next():
}
}
for {
select {
case <-b.Done():
return
case <-b.Next():
}
}
for {
select {
case <-b.Done():
return
case <-b.Next():
}
}
bail out of loop
for {
select {
case <-b.Done():
return
case <-b.Next():
}
}
bail out of loop
continue loop
これ、Loop Condition だ
func Continue(b *Backoff) bool {
select {
case <-b.Done():
return false
case <-b.Next():
return true
}
return false // never reached
}
func to determine loop condition
b, cancel := policy.Start(ctx)
defer cancel()
for backoff.Continue(b) {
a, b, c, err := f()
if err == nil {
return
}
}
キュッとした!
b, cancel := policy.Start(ctx)
defer cancel()
for backoff.Continue(b) {
a, b, c, err := f()
if err == nil {
return
}
}
キュッとした!
use as condition
確認
確認
contextで途中停止
確認
channelでタイミング制御
contextで途中停止
確認
channelでタイミング制御
for backoff.Continue() でループ制御
contextで途中停止
確認
channelでタイミング制御
for backoff.Continue() でループ制御
contextで途中停止
goroutine safe by design
確認
クロージャに頼る必要がない
channelでタイミング制御
for backoff.Continue() でループ制御
contextで途中停止
goroutine safe by design
APIデザインをする時はその言
語の自然なフローを許す形を
考えるのがお勧め
(なお、コードをよく読むと、
cenkalti/backoffも実装はほぼ同じ仕
組みになっているが、公開しているイ
ンターフェースがまったく違う)
おまけ
「Google APIから学ぶ自動生成」
※ Goの連載記事です
※ GoのためのAPIデザインの話です
End

More Related Content

What's hot

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門増田 亨
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることShingo Fukui
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッドKohsuke Yuasa
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれKumazaki Hiroki
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ SEGADevTech
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 Hiroshi Ito
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるpospome
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)Yoshitaka Kawashima
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知るShuhei Fujita
 
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版Masahiro Nagano
 
君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?Teppei Sato
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣Masahiro Nishimi
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門泰 増田
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホンYou_Kinjoh
 

What's hot (20)

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門ドメイン駆動設計のためのオブジェクト指向入門
ドメイン駆動設計のためのオブジェクト指向入門
 
GraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ることGraphQLのsubscriptionで出来ること
GraphQLのsubscriptionで出来ること
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考えるGoのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
 
Kotlinアンチパターン
KotlinアンチパターンKotlinアンチパターン
Kotlinアンチパターン
 
イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)イミュータブルデータモデル(入門編)
イミュータブルデータモデル(入門編)
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知る
 
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
ISUCONで学ぶ Webアプリケーションのパフォーマンス向上のコツ 実践編 完全版
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?君はyarn.lockをコミットしているか?
君はyarn.lockをコミットしているか?
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
WebSocketのキホン
WebSocketのキホンWebSocketのキホン
WebSocketのキホン
 

Similar to GoらしいAPIを求める旅路 (Go Conference 2018 Spring)

C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいdigitalghost
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理Yuto Matsukubo
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
AOSPをミラーしてみた
AOSPをミラーしてみたAOSPをミラーしてみた
AOSPをミラーしてみたkinneko
 
基礎からC言語 part1
基礎からC言語 part1基礎からC言語 part1
基礎からC言語 part1Hiroyuki Ito
 
FuelPHPをさわってみて
FuelPHPをさわってみてFuelPHPをさわってみて
FuelPHPをさわってみてSotaro Omura
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2Preferred Networks
 
Let’s translate FuelPHP docs! [RELOADED]
Let’s translate FuelPHP docs! [RELOADED]Let’s translate FuelPHP docs! [RELOADED]
Let’s translate FuelPHP docs! [RELOADED]Sho A
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyistsnanki
 
PHPの戻り値型宣言でselfを使ってみよう
PHPの戻り値型宣言でselfを使ってみようPHPの戻り値型宣言でselfを使ってみよう
PHPの戻り値型宣言でselfを使ってみようDQNEO
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.ContextAkira Takahashi
 
React+TypeScriptもいいぞ
React+TypeScriptもいいぞReact+TypeScriptもいいぞ
React+TypeScriptもいいぞMitsuru Ogawa
 
Git pyfes201207-presen
Git pyfes201207-presenGit pyfes201207-presen
Git pyfes201207-presenKouhei Maeda
 
Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Masakazu Muraoka
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話bleis tift
 

Similar to GoらしいAPIを求める旅路 (Go Conference 2018 Spring) (20)

C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理明日から使える気になるGo言語による並行処理
明日から使える気になるGo言語による並行処理
 
Improvement future api
Improvement future apiImprovement future api
Improvement future api
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
AOSPをミラーしてみた
AOSPをミラーしてみたAOSPをミラーしてみた
AOSPをミラーしてみた
 
基礎からC言語 part1
基礎からC言語 part1基礎からC言語 part1
基礎からC言語 part1
 
Gopenflow demo v1
Gopenflow demo v1Gopenflow demo v1
Gopenflow demo v1
 
FuelPHPをさわってみて
FuelPHPをさわってみてFuelPHPをさわってみて
FuelPHPをさわってみて
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
Optuna Dashboardの紹介と設計解説 - 2022/12/10 Optuna Meetup #2
 
Let’s translate FuelPHP docs! [RELOADED]
Let’s translate FuelPHP docs! [RELOADED]Let’s translate FuelPHP docs! [RELOADED]
Let’s translate FuelPHP docs! [RELOADED]
 
ffi for rubyists
ffi for rubyistsffi for rubyists
ffi for rubyists
 
PHPの戻り値型宣言でselfを使ってみよう
PHPの戻り値型宣言でselfを使ってみようPHPの戻り値型宣言でselfを使ってみよう
PHPの戻り値型宣言でselfを使ってみよう
 
Continuation with Boost.Context
Continuation with Boost.ContextContinuation with Boost.Context
Continuation with Boost.Context
 
Deep Dive C# 6.0
Deep Dive C# 6.0Deep Dive C# 6.0
Deep Dive C# 6.0
 
React+TypeScriptもいいぞ
React+TypeScriptもいいぞReact+TypeScriptもいいぞ
React+TypeScriptもいいぞ
 
Git pyfes201207-presen
Git pyfes201207-presenGit pyfes201207-presen
Git pyfes201207-presen
 
Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話Async awaitでの繰り返し処理についての小話
Async awaitでの繰り返し処理についての小話
 
yieldとreturnの話
yieldとreturnの話yieldとreturnの話
yieldとreturnの話
 

More from lestrrat

Future of Tech "Conferences"
Future of Tech "Conferences"Future of Tech "Conferences"
Future of Tech "Conferences"lestrrat
 
ONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 WinterONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 Winterlestrrat
 
Slicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPISlicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPIlestrrat
 
Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由lestrrat
 
Rejectcon 2018
Rejectcon 2018Rejectcon 2018
Rejectcon 2018lestrrat
 
Builderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinnerBuilderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinnerlestrrat
 
Google container builderと友だちになるまで
Google container builderと友だちになるまでGoogle container builderと友だちになるまで
Google container builderと友だちになるまでlestrrat
 
筋肉によるGoコードジェネレーション
筋肉によるGoコードジェネレーション筋肉によるGoコードジェネレーション
筋肉によるGoコードジェネレーションlestrrat
 
iosdc 2017
iosdc 2017iosdc 2017
iosdc 2017lestrrat
 
シュラスコの食べ方 超入門
シュラスコの食べ方 超入門シュラスコの食べ方 超入門
シュラスコの食べ方 超入門lestrrat
 
OSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃないOSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃないlestrrat
 
Coding in the context era
Coding in the context eraCoding in the context era
Coding in the context eralestrrat
 
Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)lestrrat
 
Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016lestrrat
 
Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24lestrrat
 
小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016lestrrat
 
いまさら聞けないselectあれこれ
いまさら聞けないselectあれこれいまさら聞けないselectあれこれ
いまさら聞けないselectあれこれlestrrat
 
Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016lestrrat
 
How To Think In Go
How To Think In GoHow To Think In Go
How To Think In Golestrrat
 
On internationalcommunityrelations
On internationalcommunityrelationsOn internationalcommunityrelations
On internationalcommunityrelationslestrrat
 

More from lestrrat (20)

Future of Tech "Conferences"
Future of Tech "Conferences"Future of Tech "Conferences"
Future of Tech "Conferences"
 
ONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 WinterONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 Winter
 
Slicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPISlicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPI
 
Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由
 
Rejectcon 2018
Rejectcon 2018Rejectcon 2018
Rejectcon 2018
 
Builderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinnerBuilderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinner
 
Google container builderと友だちになるまで
Google container builderと友だちになるまでGoogle container builderと友だちになるまで
Google container builderと友だちになるまで
 
筋肉によるGoコードジェネレーション
筋肉によるGoコードジェネレーション筋肉によるGoコードジェネレーション
筋肉によるGoコードジェネレーション
 
iosdc 2017
iosdc 2017iosdc 2017
iosdc 2017
 
シュラスコの食べ方 超入門
シュラスコの食べ方 超入門シュラスコの食べ方 超入門
シュラスコの食べ方 超入門
 
OSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃないOSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃない
 
Coding in the context era
Coding in the context eraCoding in the context era
Coding in the context era
 
Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)
 
Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016
 
Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24
 
小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016
 
いまさら聞けないselectあれこれ
いまさら聞けないselectあれこれいまさら聞けないselectあれこれ
いまさら聞けないselectあれこれ
 
Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016
 
How To Think In Go
How To Think In GoHow To Think In Go
How To Think In Go
 
On internationalcommunityrelations
On internationalcommunityrelationsOn internationalcommunityrelations
On internationalcommunityrelations
 

GoらしいAPIを求める旅路 (Go Conference 2018 Spring)