Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Httpリクエストを自動リトライ・ポーリングするイテレータを作ってみた
Search
miyamo2
September 04, 2024
Programming
210
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Httpリクエストを自動リトライ・ポーリングするイテレータを作ってみた
2024/09/04 Go Connect #2
https://gotalk.connpass.com/event/327544/
miyamo2
September 04, 2024
More Decks by miyamo2
See All by miyamo2
Go 1.24 tool directiveは何を変えるのか
miyamo2
1
290
AWS Cloud Formation Git Syncで始める 頑張らない自動デプロイ
miyamo2
0
190
Other Decks in Programming
See All in Programming
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
320
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
気持ちぃ〜角丸 Squircle
ryu1013
0
310
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
270
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
440
JIS keyboard support in Omarchy
lef237
0
130
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.1k
The Rails Doctrine Decade
koic
2
600
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
800
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
3.9k
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.3k
Featured
See All Featured
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
270
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
480
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3.1k
Optimizing for Happiness
mojombo
378
71k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
760
Amusing Abliteration
ianozsvald
1
350
Between Models and Reality
mayunak
4
500
The Cost Of JavaScript in 2023
addyosmani
55
10k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.4k
The agentic SEO stack - context over prompts
schlessera
0
970
Transcript
Httpリクエストを自動リトライ・ポーリングす るイテレータを作ってみた 2024/09/04 Go Connect #2 @miyamo2
話すこと・話さないこと 話すこと 作ったものの概要とその使い方 話さないこと イテレータの概要や実装方法 作ったパッケージの内部実装について
作ったもの できること ステータスコードに応じた自動リトライ レスポンスボディとエラーに応じた自動リトライ(ポーリング処理) 上記の結果のイテレーション
サンプルコード url := "http://example.com" ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer
cancel() opts := []r2.Option{ r2.WithMaxRequestAttempts(3), r2.WithPeriod(time.Second), } for resp, err := range r2.Get(ctx, url, opts...) { if err != nil { slog.WarnContext(ctx, "something happened.", slog.Any("error", err)) // Note: continueを使用してもイテレータが終了する場合がある continue } if resp == nil { slog.WarnContext(ctx, "response is nil") continue } if resp.StatusCode != http.StatusOK { slog.WarnContext(ctx, "unexpected status code.", slog.Int("expect", http.StatusOK), slog.Int("got", resp.StatusCode)) continue } buf, err := io.ReadAll(resp.Body) if err != nil { slog.ErrorContext(ctx, "failed to read response body.", slog.Any("error", err)) continue } slog.InfoContext(ctx, "response", slog.String("response", string(buf))) // r2ではデフォルトでリクエストボディが自動クローズするため明示的にクローズ処理を行う必要がない }
r2がイテレータを終了する条件 リクエストが成功(ステータスコードが200 ~ 399)、 かつ WithTerminateIf が指定されていない場合 WithTerminateIf で指定された条件が満たされた場合 429:
Too Many Requests以外の4xx クライアントエラーが返された 場合 WithMaxRequestAttempts によって指定されたリクエストの最大回数 を超えた場合 引数で渡された context.Context がキャンセルされた場合 for rangeループがbreakによって中断された場合
Get 以外にr2で用意されている関数 func Head(ctx context.Context, url string, options ...Option) (*http.Response,
error) func Post(ctx context.Context, url string, body io.Reader, options ...Option) (*http.Response, error) func Put(ctx context.Context, url string, body io.Reader, options ...Option) (*http.Response, error) func Patch(ctx context.Context, url string, body io.Reader, options ...Option) (*http.Response, error) func Delete(ctx context.Context, url string, body io.Reader, options ...Option) (*http.Response, error) func PostForm(ctx context.Context, url string, data url.Values, options ...Option) (*http.Response, error)
r2で用意されているオプション WithMaxRequestAttempts WithPeriod WithInterval WithTerminateIf WithHttpClient WithHeader WithContentType WithAspect WithAutoCloseResponseBody
r2で用意されているオプション WithMaxRequestAttempts WithPeriod WithInterval WithTerminateIf WithHttpClient WithHeader WithContentType WithAspect WithAutoCloseResponseBody
WithMaxRequestAttempts func WithMaxRequestAttempts(maxRequestTimes int) Option r2.WithMaxRequestAttempts(3) リクエストの最大回数を指定する デフォルト、もしくは0が設定された場合は回数無制限でリクエスト を行う リトライではなく、リクエストの回数を指定するオプションなので注
意
WithPeriod func WithPeriod(period time.Duration) Option r2.WithPeriod(time.Second) 各リクエストのタイムアウト時間を指定する デフォルト、もしくは0が設定された場合はタイムアウトしない http.Client.Timeout を使用せず
r2 独自で context.WithTimeout を用い たハンドリングを行う http.Client.Timeout と併用して同じ値が設定された場合にどちらのタ イムアウトが適用されるかの動作は未定義
WithInterval func WithInterval(interval time.Duration) Option r2.WithInterval(time.Second) 各リクエストの間隔を指定する デフォルト、もしくは0が設定された場合は以下のどちらかで算出さ れる Backoff
And Jitterアルゴリズム 'Retry-After'ヘッダーを参照 (Too Many Requestsが返された場合に限り)
WithTerminateIf func WithTerminateIf(terminationCondition func(resp *http.Response, err error) bool) Option r2.WithTerminateIf(
func(resp *http.Response, _ error) bool { buf, err := io.ReadAll(resp.Body) if err != nil { return true } data := map[string]any{} if err := json.Unmarshal(buf, data); err != nil { return false } return data["foo"] == "bar" }) ユーザー独自の終了条件を指定する レスポンスボディの巻き戻しは r2 側で対応
WithAutoCloseResponseBody func WithAutoCloseResponseBody(autoCloseResponseBody bool) Option r2.WithAutoCloseResponseBody(false) リクエストボディを r2 側で自動でクローズする デフォルト、もしくはtrueが設定された場合は有効
参考 イテレータによってGoはどう変わるのか https://audience.ahaslides.com/cl965inb88/review?lookback-tab=slides Go の iter パッケージを使ってみよう https://zenn.dev/mattn/articles/641f1d86fffdc9 Goのリトライ処理で考慮すること https://zenn.dev/imamura_sh/articles/retry-46aa586aeb5c3c28244e
mattn/go-for-range-experiment-example https://github.com/mattn/go-for-range-experiment-example avast/retry-go https://github.com/avast/retry-go