SlideShare a Scribd company logo
1 of 23
Download to read offline
The Go gopher was designed by Renée French.
The gopher stickers was made by Takuya Ueda.
Licensed under the Creative Commons 3.0 Attributions license.
GAE/Goとsyncパッケージ
2018年3月2日(金)
@酔いどれGCPUG
自己紹介
上田拓也
@tenntenn
所属
コミュニティ活動
&
Go ビギナーズ
Go Conference
上田拓也
@tenntenn
ソウゾウ エキスパートチーム
技術をアウトプットするところに技術は集まる
■ エキスパートチームとは?
● 50%以上の時間を技術コミュニティへの貢献に充てる
■ エキスパートチームの役割
● 社内に新しい技術を取り取り込む
● 社外のコミュニティなどを通じて社会へ還元する
■ エキスパートチームの活動
● カンファレンス・勉強会の開催/運営
● 対外的な講演活動
● 執筆、雑誌への寄稿、インタビュー
● 社内外での担当技術の普及推進
@tenntenn
担当:Go・GCP
@mhidaka
担当:Android
メンバー
アジェンダ
■ ゴールーチンとチャネル
■ GAE/Goでのゴールーチンの使い所
■ syncパッケージ
■ golang.org/x/syncパッケージ
■ github.com/tenntenn/syncパッケージ
■ まとめ
Goの並行処理
■ ゴールーチン
■ 軽量なスレッドに近いもの
■ goキーワードをつけて関数呼び出し
■ チャネル
■ ゴールーチン間のデータのやり取り
■ 安全にデータをやり取りできる
5
チャネル
ゴールーチン
A
ゴールーチン
B
データ
データ
// 関数fを別のゴールーチンで呼び出す
go f()
GAE/Goでの並行処理の使い所
■ 並列度は1
● GAE/Go上ではゴールーチンは並列には実行されない
● ずっと1とは限らないので適切にロックは取ろう
■ ゴールーチンのスケジューラの挙動を把握する
● 特定の処理が走ると別のゴールーチンに処理が切り替わる
○ I/Oやシステムコール、チャネルのブロックなど
● Datastoreへ複数のリクエストを投げる場合には有効
○ 通信が発生しているため
Cloud
Datastore
App
Engine
Get A
Get B
Get C
ゴールーチン間のデータ競合
ゴールーチン-main
ゴールーチン-2ゴールーチン-1
go f1() go f2()
変数v
print(v) v = 100
処理順序が保証されない
競合
7
データ競合の解決
■ 問題点
■ どのゴールーチンが先にアクセスするか分からない
■ 値の変更や参照が競合する
■ 解決方法
■ 1つの変数には1つのゴールーチンからアクセスする
■ チャネルを使ってゴールーチン間で通信をする
■ またはロックをとる(syncパッケージ)
Do not communicate by sharing memory;
instead, share memory by communicating
8
syncパッケージ
■ チャネル以外を使う理由
● チャネルだけを使っているとコードが難解になる場合がある
● 複数のチャネルが登場したり
● 競合を防ぎたいデータが複数ある場合
■ syncパッケージ
● データの競合を防ぐロックなどを提供するパッケージ
● sync/atomicではアトミックな演算をするための型などを提供
9
ロック
var m sync.Mutex
m.Lock()
go func() {
time.Sleep(3 * time.Second)
m.Unlock()
fmt.Println("unlock 1")
}()
m.Lock()
m.Unlock()
fmt.Println("unlock 2")
Playgroundで動かす
ゼロ値で使える
ここでブロック
10
■ sync.Mutex
● Lockメソッドを呼ぶとUnlockメソッドが呼ばれるまで
Lockメソッドの呼び出しでブロックする
書き込み・読み込みロック
■ sync.RWMutex
● Mutexに読み込み用のRLockとRUnlockが入ったもの
var m sync.RWMutex
m.RLock()
go func() {
time.Sleep(3 * time.Second)
m.RUnlock()
fmt.Println("unlock 1")
}()
m.RLock()
m.RUnlock()
fmt.Println("unlock 2")
Playgroundで動かす
読み込みロックだけでは
ブロックしない
11
1度しか実行しない関数
■ sync.Onceを使う
● 1回以上Doメソッドを呼んでも意味がない
● 複数のゴールーチンから1回しか呼ばないようにするために利用する
func f() { fmt.Println("Do!!") }
func main() {
var once sync.Once
once.Do(f)
once.Do(f)
fmt.Println("done")
}
12
2回目は実行されない
Playgroundで動かす
sync.Onceを使って初期化を行う
■ init関数を用いる
● context.Contextを取得できないのでログすらだせない
■ /_ah/warmupリクエストで処理する
● インスタンス起動時に送られてくるリクエスト
● app.yamlで設定して、ハンドラを設定すればよい
● しかし、必ず最初にリクエストがくるわけではない
○ sync.Onceで処理して必ず1回だけ実行されるようにする
inbound_services:
- warmup
warmup
first requst
初期化
処理
sync.Once
1回だけ実行
複数のゴールーチンの待機
■ sync.WaitGroupを使う
var wg sync.WaitGroup
wg.Add(1)
go func() { /* do something */ wg.Done() }()
wg.Add(1)
go func() { /* do something */ wg.Done() }()
wg.Wait()
Playgroundで動かす
14
エラーを返すゴールーチンの待機
■ golang.org/x/sync/errgroupを使う
● 失敗した場合にエラーが取得できる
● 1つでもエラーを起こすとキャンセルされる
var eg errgroup.Group
eg.Go(func() error { /*...*/ })
eg.Go(func() error { /*...*/ })
if err := eg.Wait(); err != nil {
log.Fatal(err)
}
15
golang.org/x/syncパッケージ
■ errgroupパッケージ
● エラーを返すゴールーチンの待機
■ singleflightパッケージ
● 1度しかリクエストが飛ばないようにする
● 2度目は同じ値を返す
■ semaphoreパッケージ
● 重み付きセマフォ
■ syncmapパッケージ
● スレッドセーフなマップ
● Go1.9から標準パッケージになった
github.com/tenntenn/syncパッケージ
■ recoverableパッケージ
● ゴールーチンまたいだpanicを安全に処理する
■ fcfsパッケージ
● 早い物勝ち(First Come First Serve)
● 最初に処理したものだけ有効にする
■ groutinegroupパッケージ
● x/errgroupパッケージのエラーが発生しても全部続ける版
● まだ非公開
● メルカリ アッテで使われている
recoverableパッケージ
■ ゴールーチンを跨いでpanicをrecoverできない
■ panicをエラーに変換する
func main() {
defer func() { fmt.Println(recover()) }()
go func() { panic("PANIC!!!") }()
time.Sleep(1 * time.Second)
}
func main() {
var eg errgroup.Group
eg.Go(recoverable.Func(func() { panic("PANIC!!!") }))
if err := eg.Wait(); err != nil { /* エラー処理 */ }
}
fcfsパッケージ
■ 早い者勝ち(First Come First Served)
● とあるサービスからリソースを取得することを考える
● 1回目のリクエストを投げる
● 1回目が一定期間で帰ってこなかったらもう一つ投げる
● 早く帰ってきた方を使って、他方をキャンセルする
リクエスト
リクエスト
100ms待機
fcfsパッケージ
■ 早い者勝ち(First Come First Served)
● とあるサービスからリソースを取得することを考える
● 1回目のリクエストを投げる
● 1回目が一定期間で帰ってこなかったらもう一つ投げる
● 早く帰ってきた方を使って、他方をキャンセルする
var g fcfs.Group
f := func() (interface{}, error) { /* 処理 */ }
g.Go(f)
g.Delay(100 * time.Millisecond, f) // 100ms遅れて処理
v, err := g.Wait()
if err != nil { /* エラー処理 */}
/* vを使った処理 */
goroutinegroupパッケージ
■ エラーと処理結果をそれぞれ取り出せる
● エラーが発生しても他の処理には影響しない
● エラーと結果が安全に取り出せる
var g goroutinegroup.Group
g.Go("処理1", func() (interface{}, error) { /* 処理1 */ })
g.Go("処理2", func() (interface{}, error) { /* 処理1 */ })
<-g.Done()
v1, err := g.Return("処理1")
if err != nil { /* エラー処理 */}
v2, err := g.Return("処理2")
if err != nil { /* エラー処理 */}
/* v1とv2を使った処理 */
まとめ
■ GAE/Goでゴールーチンは有効
● 現在の並列度は1
○ ずっと1とは限らないので注意
● 複数のDatastoreへのアクセスなどを並行に投げれる
■ syncパッケージを使おう
● 初期化処理はsync.Onceで行う
● Group系の型を使えば楽にゴールーチンを利用できる
Thank you!
twitter: @tenntenn
Qiita: tenntenn
connpass: tenntenn
23

More Related Content

What's hot

今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋
Takuya Ueda
 

What's hot (20)

WebAssembly with Go
WebAssembly with GoWebAssembly with Go
WebAssembly with Go
 
GoによるiOSアプリの開発
GoによるiOSアプリの開発GoによるiOSアプリの開発
GoによるiOSアプリの開発
 
Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −Goにおけるバージョン管理の必要性 − vgoについて −
Goにおけるバージョン管理の必要性 − vgoについて −
 
goパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現するgoパッケージで型情報を用いたソースコード検索を実現する
goパッケージで型情報を用いたソースコード検索を実現する
 
Goとテスト
GoとテストGoとテスト
Goとテスト
 
GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門GAE/GoでWebアプリ開発入門
GAE/GoでWebアプリ開発入門
 
Pyladies tokyo 2nd anniversary LT
Pyladies tokyo 2nd anniversary LTPyladies tokyo 2nd anniversary LT
Pyladies tokyo 2nd anniversary LT
 
Cloud functionsの紹介
Cloud functionsの紹介Cloud functionsの紹介
Cloud functionsの紹介
 
条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化条件式評価器の実装による管理ツールの抽象化
条件式評価器の実装による管理ツールの抽象化
 
PyCon JP 2016 ビギナーセッション
PyCon JP 2016 ビギナーセッションPyCon JP 2016 ビギナーセッション
PyCon JP 2016 ビギナーセッション
 
Pynyumon03 LT
Pynyumon03 LTPynyumon03 LT
Pynyumon03 LT
 
Google Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめGoogle Assistant関係のセッションまとめ
Google Assistant関係のセッションまとめ
 
粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法粗探しをしてGoのコントリビューターになる方法
粗探しをしてGoのコントリビューターになる方法
 
Cloud Functionsの紹介
Cloud Functionsの紹介Cloud Functionsの紹介
Cloud Functionsの紹介
 
Gopher Fest 2017参加レポート
Gopher Fest 2017参加レポートGopher Fest 2017参加レポート
Gopher Fest 2017参加レポート
 
今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋今日から始めるGopher - スタートGo #0 @GDG名古屋
今日から始めるGopher - スタートGo #0 @GDG名古屋
 
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
静的解析とUIの自動生成を駆使してモバイルアプリの運用コストを大幅に下げた話
 
久しぶりのPythonでgoogleのアレを制御してみた
久しぶりのPythonでgoogleのアレを制御してみた久しぶりのPythonでgoogleのアレを制御してみた
久しぶりのPythonでgoogleのアレを制御してみた
 
Go mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろうGo mobileでモバイルアプリを作ろう
Go mobileでモバイルアプリを作ろう
 
Stapy#17LT
Stapy#17LTStapy#17LT
Stapy#17LT
 

Similar to GAE/Goとsyncパッケージ

今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
Takuto Matsuu
 
Windowsにpythonをインストールしてみよう
WindowsにpythonをインストールしてみようWindowsにpythonをインストールしてみよう
Windowsにpythonをインストールしてみよう
Kenji NAKAGAKI
 

Similar to GAE/Goとsyncパッケージ (16)

Go静的解析ハンズオン
Go静的解析ハンズオンGo静的解析ハンズオン
Go静的解析ハンズオン
 
Goのパッケージ構成で 試行錯誤してみた話 ~ Gocon 2015 Summer
Goのパッケージ構成で 試行錯誤してみた話 ~ Gocon 2015 SummerGoのパッケージ構成で 試行錯誤してみた話 ~ Gocon 2015 Summer
Goのパッケージ構成で 試行錯誤してみた話 ~ Gocon 2015 Summer
 
実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで実践Go ツールの作成から配布まで
実践Go ツールの作成から配布まで
 
エキスパートGo
エキスパートGoエキスパートGo
エキスパートGo
 
Go入門
Go入門Go入門
Go入門
 
Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用Goにおける静的解析と製品開発への応用
Goにおける静的解析と製品開発への応用
 
マスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ IIマスター・オブ・reflectパッケージ II
マスター・オブ・reflectパッケージ II
 
静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発静的解析を使った開発ツールの開発
静的解析を使った開発ツールの開発
 
Go言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンドGo言語ってどんな言語? 導入実績や気になるトレンド
Go言語ってどんな言語? 導入実績や気になるトレンド
 
Gopenflow demo v1
Gopenflow demo v1Gopenflow demo v1
Gopenflow demo v1
 
Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて今最もアツイdistribution Gentoo Linuxについて
今最もアツイdistribution Gentoo Linuxについて
 
Windowsにpythonをインストールしてみよう
WindowsにpythonをインストールしてみようWindowsにpythonをインストールしてみよう
Windowsにpythonをインストールしてみよう
 
GoでMinecraftっぽいの作る
GoでMinecraftっぽいの作るGoでMinecraftっぽいの作る
GoでMinecraftっぽいの作る
 
RgGen ご紹介
RgGen ご紹介RgGen ご紹介
RgGen ご紹介
 
etckeeperをopenSUSEの公式リポジトリに入れたいぞ! Ver.2
etckeeperをopenSUSEの公式リポジトリに入れたいぞ! Ver.2etckeeperをopenSUSEの公式リポジトリに入れたいぞ! Ver.2
etckeeperをopenSUSEの公式リポジトリに入れたいぞ! Ver.2
 

More from Takuya Ueda (7)

そうだ、Goを始めよう
そうだ、Goを始めようそうだ、Goを始めよう
そうだ、Goを始めよう
 
マスター・オブ・goパッケージ
マスター・オブ・goパッケージマスター・オブ・goパッケージ
マスター・オブ・goパッケージ
 
メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新メルカリ カウルのマスタデータの更新
メルカリ カウルのマスタデータの更新
 
Static Analysis in Go
Static Analysis in GoStatic Analysis in Go
Static Analysis in Go
 
メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?メルカリ・ソウゾウでは どうGoを活用しているのか?
メルカリ・ソウゾウでは どうGoを活用しているのか?
 
Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践Namespace API を用いたマルチテナント型 Web アプリの実践
Namespace API を用いたマルチテナント型 Web アプリの実践
 
Mobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse BindingMobile Apps by Pure Go with Reverse Binding
Mobile Apps by Pure Go with Reverse Binding
 

Recently uploaded

Recently uploaded (9)

部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
部内勉強会(IT用語ざっくり学習) 実施日:2024年5月17日(金) 対象者:営業部社員
 
MPAなWebフレームワーク、Astroの紹介 (その1) 2024/05/17の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その1) 2024/05/17の勉強会で発表されたものです。MPAなWebフレームワーク、Astroの紹介 (その1) 2024/05/17の勉強会で発表されたものです。
MPAなWebフレームワーク、Astroの紹介 (その1) 2024/05/17の勉強会で発表されたものです。
 
Hyperledger Fabricコミュニティ活動体験& Hyperledger Fabric最新状況ご紹介
Hyperledger Fabricコミュニティ活動体験& Hyperledger Fabric最新状況ご紹介Hyperledger Fabricコミュニティ活動体験& Hyperledger Fabric最新状況ご紹介
Hyperledger Fabricコミュニティ活動体験& Hyperledger Fabric最新状況ご紹介
 
LoRaWAN無位置ロープ型水漏れセンサー WL03A-LB/LSカタログ ファイル
LoRaWAN無位置ロープ型水漏れセンサー WL03A-LB/LSカタログ ファイルLoRaWAN無位置ロープ型水漏れセンサー WL03A-LB/LSカタログ ファイル
LoRaWAN無位置ロープ型水漏れセンサー WL03A-LB/LSカタログ ファイル
 
Keywordmap overview material/CINC.co.ltd
Keywordmap overview material/CINC.co.ltdKeywordmap overview material/CINC.co.ltd
Keywordmap overview material/CINC.co.ltd
 
LoRaWAN無位置ロープ式水漏れセンサーWL03A 日本語マニュアル
LoRaWAN無位置ロープ式水漏れセンサーWL03A 日本語マニュアルLoRaWAN無位置ロープ式水漏れセンサーWL03A 日本語マニュアル
LoRaWAN無位置ロープ式水漏れセンサーWL03A 日本語マニュアル
 
情報を表現するときのポイント
情報を表現するときのポイント情報を表現するときのポイント
情報を表現するときのポイント
 
ネットワーク可視化 振る舞い検知(NDR)ご紹介_キンドリル202405.pdf
ネットワーク可視化 振る舞い検知(NDR)ご紹介_キンドリル202405.pdfネットワーク可視化 振る舞い検知(NDR)ご紹介_キンドリル202405.pdf
ネットワーク可視化 振る舞い検知(NDR)ご紹介_キンドリル202405.pdf
 
2024年5月17日 先駆的科学計算フォーラム2024 機械学習を用いた新たなゲーム体験の創出の応用
2024年5月17日 先駆的科学計算フォーラム2024 機械学習を用いた新たなゲーム体験の創出の応用2024年5月17日 先駆的科学計算フォーラム2024 機械学習を用いた新たなゲーム体験の創出の応用
2024年5月17日 先駆的科学計算フォーラム2024 機械学習を用いた新たなゲーム体験の創出の応用
 

GAE/Goとsyncパッケージ