Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: common/retry/transient/transient.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: more refactor Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file.
4
5 // Package transient allows you to tag and retry 'transient' errors (i.e.
6 // non-permanent errors which may resolve themselves by trying an operation
7 // again). This should be used on errors due to network flake, improperly
8 // responsive remote servers (e.g. status 500), unusual timeouts, etc. where
9 // there's no concrete knowledge that something is permanently wrong.
10 //
11 // Said another way, transient errors appear to resolve themselves with nothing
12 // other than the passage of time.
13 package transient
14
15 import (
16 "time"
17
18 "github.com/luci/luci-go/common/errors"
19 "github.com/luci/luci-go/common/retry"
20 "golang.org/x/net/context"
21 )
22
23 // transientOnlyIterator is an Iterator implementation that only retries errors
24 // if they are tagged with `transient.Tag`.
25 type transientOnlyIterator struct {
26 retry.Iterator // The wrapped Iterator.
27 }
28
29 func (i *transientOnlyIterator) Next(ctx context.Context, err error) time.Durati on {
30 if !Tag.In(err) {
31 return retry.Stop
32 }
33 return i.Iterator.Next(ctx, err)
34 }
35
36 // Only returns a retry.Iterator that wraps another retry.Iterator. It
37 // will fall through to the wrapped Iterator ONLY if an error with the
38 // transient.Tag is encountered; otherwise, it will not retry.
39 //
40 // Returns nil if f is nil.
41 //
42 // Example:
43 // err := retry.Retry(c, transient.Only(retry.Default), func() error {
44 // if condition == "red" {
45 // // This error isn't transient, so it won't be retried.
46 // return errors.New("fatal bad condition")
47 // } elif condition == "green" {
48 // // This isn't an error, so it won't be retried.
49 // return nil
50 // }
51 // // This will get retried, because it's transient.
52 // return errors.New("dunno what's wrong", transient.Tag)
53 // })
54 func Only(next retry.Factory) retry.Factory {
55 if next == nil {
56 return nil
57 }
58 return func() retry.Iterator {
59 if it := next(); it != nil {
60 return &transientOnlyIterator{it}
61 }
62 return nil
63 }
64 }
65
66 // Tag is used to indicate that an error is transient (i.e. something is
67 // temporarially wrong).
68 var Tag = errors.BoolTag{Key: errors.NewTagKey("this error is temporary")}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698