Created
September 4, 2018 13:08
-
-
Save excavador/e0da2ee133f044a741219d191c6b83f8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func Temporary(err error) bool { | |
switch err.(type) { | |
case net.Error: | |
return err.(net.Error).Temporary() | |
} | |
if err, ok := err.(*pq.Error); ok { | |
code := err.Code | |
switch code.Class() { | |
case "00": // Successful Completion | |
case "01": // Warning | |
case "02": // No Data (this is also a warning class per the SQL standard) | |
case "03": // SQL Statement Not Yet Done | |
case "08": // Connection Exception | |
return true | |
case "40": // Transaction Rollback | |
// deadlock_detected | |
if string(code) == "40P01" { | |
return true | |
} | |
// could not serialize access due to concurrent update | |
if string(code) == "40001" { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
func (db *db) Db(ctx context.Context, action action) (err error) { | |
for { | |
// try to perform the action | |
... | |
if err = action(ctx, session); err == nil { | |
return | |
} else if Temporary(err) { | |
logger.Debugf(ctx, "temporary problem %s", err) | |
select { | |
// check for cancel | |
case <-ctx.Done(): | |
err = ctx.Err() | |
logger.Errorf(ctx, "canceled %s", err) | |
return | |
// TODO: Randomize timeout a little? | |
// wait retry interval | |
case <-time.After(time.Duration(db.cfgRetryInterval)): | |
logger.Debugf(ctx, "repeat") | |
} | |
} else { | |
return | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func UseMagicLink(ctx context.Context, token string) (username string, err error) { | |
action := func(ctx context.Context, tx *sql.Tx) (err error) { | |
err = db.Get(ctx, tx, db.JSONB(&username), | |
"SELECT func.get_magic_link($1)", token) | |
if err != nil { | |
logger.Errorf(ctx, "problem: %s", err) | |
} | |
return | |
} | |
err = ctx.Value("db").(db.DB).Tx(ctx, action) | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment