1
0
Fork 0
mirror of https://github.com/diamondburned/arikawa.git synced 2025-01-21 03:57:26 +00:00

Added HTTP retry, fixed async JSON body corrupting

This commit is contained in:
diamondburned (Forefront) 2020-01-20 11:28:55 -08:00
parent ff0bc7b98b
commit 73f5cdec9e
6 changed files with 41 additions and 28 deletions

View file

@ -171,22 +171,13 @@ func (l *Limiter) Release(path string, headers http.Header) error {
} }
case reset != "": case reset != "":
date := headers.Get("Date")
t, err := http.ParseTime(date)
if err != nil {
return errors.Wrap(err, "Invalid date "+date)
}
unix, err := strconv.ParseFloat(reset, 64) unix, err := strconv.ParseFloat(reset, 64)
if err != nil { if err != nil {
return errors.Wrap(err, "Invalid reset "+reset) return errors.Wrap(err, "Invalid reset "+reset)
} }
reset := time.Unix(0, int64(unix*float64(time.Second))) b.reset = time.Unix(0, int64(unix*float64(time.Second))).
delta := reset.Sub(t) + ExtraDelay Add(ExtraDelay)
b.reset = time.Now().Add(delta)
} }
if remaining != "" { if remaining != "" {

1
go.mod
View file

@ -4,6 +4,7 @@ go 1.13
require ( require (
github.com/bwmarrin/discordgo v0.20.2 github.com/bwmarrin/discordgo v0.20.2
github.com/davecgh/go-spew v1.1.1
github.com/gorilla/schema v1.1.0 github.com/gorilla/schema v1.1.0
github.com/gorilla/websocket v1.4.1 github.com/gorilla/websocket v1.4.1
github.com/k0kubun/pp v3.0.1+incompatible github.com/k0kubun/pp v3.0.1+incompatible

1
go.sum
View file

@ -1,6 +1,7 @@
github.com/bwmarrin/discordgo v0.20.2 h1:nA7jiTtqUA9lT93WL2jPjUp8ZTEInRujBdx1C9gkr20= github.com/bwmarrin/discordgo v0.20.2 h1:nA7jiTtqUA9lT93WL2jPjUp8ZTEInRujBdx1C9gkr20=
github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= github.com/bwmarrin/discordgo v0.20.2/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=

View file

@ -6,7 +6,6 @@ import (
"context" "context"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"time" "time"
@ -14,10 +13,16 @@ import (
"github.com/diamondburned/arikawa/internal/json" "github.com/diamondburned/arikawa/internal/json"
) )
// Retries is the default attempts to retry if the API returns an error before
// giving up.
var Retries uint = 5
type Client struct { type Client struct {
http.Client http.Client
json.Driver json.Driver
SchemaEncoder SchemaEncoder
Retries uint
} }
var DefaultClient = NewClient() var DefaultClient = NewClient()
@ -29,6 +34,7 @@ func NewClient() Client {
}, },
Driver: json.Default{}, Driver: json.Default{},
SchemaEncoder: &DefaultSchema{}, SchemaEncoder: &DefaultSchema{},
Retries: Retries,
} }
} }
@ -97,12 +103,27 @@ func (c *Client) RequestCtx(ctx context.Context,
} }
} }
r, err := c.Client.Do(req) var r *http.Response
for i := uint(0); i < c.Retries; i++ {
r, err = c.Client.Do(req)
if err != nil {
continue
}
if r.StatusCode < 200 || r.StatusCode > 299 {
continue
}
break
}
// If all retries failed:
if err != nil { if err != nil {
log.Println("Do error", url, err)
return nil, RequestError{err} return nil, RequestError{err}
} }
// Response received, but with a failure status code:
if r.StatusCode < 200 || r.StatusCode > 299 { if r.StatusCode < 200 || r.StatusCode > 299 {
httpErr := &HTTPError{ httpErr := &HTTPError{
Status: r.StatusCode, Status: r.StatusCode,

View file

@ -5,18 +5,18 @@ import (
) )
type TransportWrapper struct { type TransportWrapper struct {
http.RoundTripper Default http.RoundTripper
Pre func(*http.Request) error
Pre func(*http.Request) error Post func(*http.Response) error
Post func(*http.Response) error
} }
var _ http.RoundTripper = (*TransportWrapper)(nil)
func NewTransportWrapper() *TransportWrapper { func NewTransportWrapper() *TransportWrapper {
return &TransportWrapper{ return &TransportWrapper{
RoundTripper: http.DefaultTransport, Default: http.DefaultTransport,
Pre: func(*http.Request) error { return nil },
Pre: func(*http.Request) error { return nil }, Post: func(*http.Response) error { return nil },
Post: func(*http.Response) error { return nil },
} }
} }
@ -25,7 +25,7 @@ func (c *TransportWrapper) RoundTrip(req *http.Request) (*http.Response, error)
return nil, err return nil, err
} }
r, err := c.RoundTripper.RoundTrip(req) r, err := c.Default.RoundTrip(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -1,9 +1,7 @@
package httputil package httputil
import ( import (
"bytes"
"io" "io"
"io/ioutil"
"net/http" "net/http"
"github.com/diamondburned/arikawa/internal/json" "github.com/diamondburned/arikawa/internal/json"
@ -62,11 +60,12 @@ func WithJSONBody(json json.Driver, v interface{}) RequestOption {
} }
} }
var buf bytes.Buffer
var err error var err error
var rp, wp = io.Pipe()
go func() { go func() {
err = json.EncodeStream(&buf, v) err = json.EncodeStream(wp, v)
wp.Close()
}() }()
return func(r *http.Request) error { return func(r *http.Request) error {
@ -75,7 +74,7 @@ func WithJSONBody(json json.Driver, v interface{}) RequestOption {
} }
r.Header.Set("Content-Type", "application/json") r.Header.Set("Content-Type", "application/json")
r.Body = ioutil.NopCloser(&buf) r.Body = rp
return nil return nil
} }
} }