Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
POSレジとGo
Search
Terry
August 11, 2021
Programming
340
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
POSレジとGo
2021/08/11に行われたGeekGigの登壇資料です
https://showcase-gig.connpass.com/event/217914/
Terry
August 11, 2021
More Decks by Terry
See All by Terry
信頼されるPOを目指して
hiroyaterui
0
640
Goで実践するBFP
hiroyaterui
1
270
scratch imageでのtime.Location()
hiroyaterui
0
37
goroutineで親のctxのkey/valueを引き継ぐ実装
hiroyaterui
0
230
Go 1.20で入った Wrapping multiple errorsをみてみる
hiroyaterui
0
150
intSize = 32 << (^uint(0) >> 63)とは
hiroyaterui
1
830
リモート開発でのコミュニケーションどうしてますか?
hiroyaterui
0
140
プリンシプルオブプログラミング ~3章(Unix除く)と7章~
hiroyaterui
0
250
データ連携2ヶ月
hiroyaterui
0
53
Other Decks in Programming
See All in Programming
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
1
250
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
380
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
AIエージェントで 変わるAndroid開発環境
takahirom
2
730
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
160
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
880
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
510
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
540
数百円から始めるRuby電子工作
tarosay
0
110
自作OSでスライド発表する
uyuki234
1
3.9k
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
180
Featured
See All Featured
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
180
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
290
Typedesign – Prime Four
hannesfritz
42
3.1k
The agentic SEO stack - context over prompts
schlessera
0
850
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
190
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
640
Marketing to machines
jonoalderson
1
5.6k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
270
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
350
Bash Introduction
62gerente
615
220k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
200
Transcript
POSレジとGo 2021/08/11 GeekGig
2 今回話す内容 チャネルとgoroutineを 実際のビジネスロジックで使われている事例と そこから得た学びを共有します。
3 1. 自己紹介 2. O:derとPOSレジ 3. チャネルとgoroutineを用いたPOS連携 4. 学び アジェンダ
自己紹介
自己紹介 • 照井 寛也(てるいひろや) • 株式会社Showcase Gigに2021年2月よりジョイン • POS連携サービスにおけるバックエンドエンジニアを担当 •
Goを書いて半年ちょっと • Twitter: @1019Hiroya
O:derとPOSレジ
7 POSレジ • POS ◦ Point Of Sales • 役割
◦ 「何を・いつ・いくらで・何個販売したのか」を記録 ◦ 商品のマスタを管理.... • 種類 ◦ パソコン型 ◦ ターミナル型 ◦ タブレット型...
8 O:derとの関係性 POSレジからのマスタを O:derに同期 O:derからの注文・会計をPOS レジに連携 POS連携サービス
9 O:derとの関係性 POSレジからのマスタを O:derに同期 O:derからの注文・会計をPOS レジに連携 POS連携サービス
Goを用いたPOS連携
11 POS連携サービス POSレジからのマスタを O:derに同期 POS連携サービス
12 マスタ同期 • 店舗毎個別でマスタ同期できる機能がもともとあった 同期 同期 同期
13 マスタ同期 • 店舗毎個別に加えて店舗一括でマスタ同期できる機能が必要 同期 同期 同期 同期 同期 同期
14 マスタ同期 • 店舗毎個別に加えて店舗一括でマスタ同期できる機能が必要 同期 同期 同期 同期 同期 同期
15 マスタとは • O:derにはカテゴリー・メニューの概念がある ◦ カテゴリーに対してメニューが紐づく カテゴリー (店舗横断) メニュー (店舗毎)
冷菜 本日の鮮魚の カルパッチョ 柚子の香り 生ハム盛り合 わせ
16 マスタ同期の仕様 • マスタ同期のリクエスト毎に排他制御がされている必要がある ◦ リクエスト成功:202(accepted)を返し、実行はgoroutineで行う ◦ 既に実行中:409(conflicted)を返す • マスタ同期する内容は以下
2つ ◦ カテゴリー ▪ 店舗横断 ◦ メニュー ▪ 店舗毎
17 マスタ同期の仕様 O:der POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 1.カテゴリー同期 2.
メニュー同期 の順で同期する必要がある
18 マスタ同期の仕様 POS連携サービス POSレジ 店舗A メニュー同期 店舗B メニュー同期 店舗C メニュー同期
複数店舗同時に同期する必要がある O:der
19 マスタ同期の仕様 POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 店舗B メニュー同期 店舗C
メニュー同期 O:der 成功 リクエスト 202
20 マスタ同期の仕様 POS連携サービス POSレジ O:der 既に実行中 リクエスト 409
21 ここから ビジネスロジックをどうGoで実装するかを見ていく
22 マスタ同期の仕様 POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 1.カテゴリー同期 2. メニュー同期
の順で同期する必要がある O:der
23 チャネル POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 チャネルを用いてカテゴリー同期が終わり次第メニュー同期の実行 O:der
24 チャネル func categorySync(ch chan struct{}, .....) (err error) {
defer func() { ch <- struct{}{} } /* カテゴリー同期処理 */ } func menuSync(ch struct{}, .....) (err error) { select { case <-ch: /* メニュー同期処理 */ } }
25 マスタ同期の仕様 POS連携サービス POSレジ 店舗A メニュー同期 店舗B メニュー同期 店舗C メニュー同期
複数店舗同時に同期する必要がある O:der
26 マスタ同期の仕様 POS連携サービス POSレジ 店舗A メニュー同期 店舗B メニュー同期 店舗C メニュー同期
goroutineで並列実行 O:der
27 メニュー同期 func Sync(.....) (err error) { for _, shop
:= range shops { // メニュー同期 go menuSync(ch, ......) } ……. }
28 マスタ同期 func Sync(.....) (err error) { // カテゴリー同期 go
categorySync(ch) for _, shop := range shops { // メニュー同期 go menuSync(ch, ......) } ……. }
学び
30 「よし!できた!」 「アトミックではないね」 (アトミック...でない...)
31 アトミック(不可分性) コンピュータ上のプログラムの動作で、密接に関連する複数の処理が外部から一つの操作に見 え、途中の状態を観測したり介入できない性質を、操作のアトミック性、不可分性などという。 (https://e-words.jp/w/%E5%8E%9F%E5%AD%90%E6%80%A7.html) リクエストは他のリクエストが何をしているか観測できない
32 マスタ同期の仕様 • マスタ同期のリクエスト毎に排他制御がされている必要がある ◦ リクエスト成功:202(accepted)を返し、実行はgoroutineで行う ◦ 既に実行中:409(conflicted)を返す • マスタ同期する内容は以下
2つ ◦ カテゴリー ▪ 店舗横断 ◦ メニュー ▪ 店舗毎
33 アトミック(不可分性)でない 同期開始 同期終了 ロック の確認 409(conflicted) ロック中 カテゴリー同期 ロックの取得
メニュー同期
34 アトミック(不可分性)でない 同期開始 同期終了 ロック の確認 409(conflicted) ロック中 カテゴリー同期 ロックの取得
メニュー同期 ロックの確認と 取得までに 間が空いている
35 アトミック(不可分性)でない 同期開始 同期終了 ロック の確認 カテゴリー同期 ロックの取得 メニュー同期 同期開始
同期終了 ロック の確認 カテゴリー同期 ロックの取得 メニュー同期 リクエストA リクエストB ロックがかかっていない と判断される
36 不可分性を保つために 同期開始 同期終了 ロック の確認 409(conflicted) ロック中 カテゴリー同期 メニュー同期
ロックの確認と取 得を 確認直後に行う ロック の取得 ロック中
37 不可分性を保つために func changeState(db *sql.DB, from to state, .....) (err
error) { result, err := db.Exec("UPDATE sync_state SET state = to where state = from and …") affected, err := result.RowsAffected() if affected < 1 { /* 更新行なし = 他のプロセスで変更された */ } } • UPDATEでも不可分性を保つためのコードを利用
38 「よし!今度こそ!」 「同時並列が多すぎると高負荷になるね」 (確かに、、)
39 同時並列による負荷分散 O:der POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 店舗B メニュー同期
店舗C メニュー同期
40 同時並列による負荷分散 O:der POS連携サービス POSレジ カテゴリー同期 店舗A メニュー同期 店舗B メニュー同期
店舗C メニュー同期
まとめ
42 実装を通しての学び • チャネルやgoroutineをビジネスロジックに当てはめて実装できたことは初の経験だった ◦ struct{}でメモリの削減になることも学んだ • ロックの確認・取得・解放にはアトミックを意識したいところ ◦ stateなどのDB値リクエスト同士で奪い合わないように気をつけたい
• 負荷分散 ◦ goroutineで並行処理が簡単にできるが、連携サービスだからこそ、その前後のサー ビスの負荷を意識して双方に優しいサービスを心がけたい