X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=udp.go;h=e3ca0fa0e028bf22560fd6a5569b00906b44914a;hb=fc8ae9eff238b916cc773abd76840a232f9036b6;hp=372aeadf20d8afc2117608f236f9614351a7a4b4;hpb=a457ecff137f07dbdf7f321e86b266a71db91fc1;p=go-anidb.git diff --git a/udp.go b/udp.go index 372aead..e3ca0fa 100644 --- a/udp.go +++ b/udp.go @@ -1,42 +1,32 @@ package anidb import ( - "encoding/gob" "github.com/Kovensky/go-anidb/udp" - "log" "sync" "time" ) -func init() { - gob.RegisterName("*github.com/Kovensky/go-anidb.banCache", &banCache{}) -} - const banDuration = 30*time.Minute + 1*time.Second -type banCache struct{ time.Time } - -func (c *banCache) Touch() { - c.Time = time.Now() -} -func (c *banCache) IsStale() bool { - return time.Now().Sub(c.Time) > banDuration -} - // Returns whether the last UDP API access returned a 555 BANNED message. func Banned() bool { - var banTime banCache - cache.Get(&banTime, "banned") + stat, err := Cache.Stat("banned") + if err != nil { + return false + } - stale := banTime.IsStale() - if stale { - cache.Delete("banned") + switch ts := stat.ModTime(); { + case ts.IsZero(): + return false + case time.Now().Sub(ts) > banDuration: + return false + default: + return true } - return !stale } func setBanned() { - cache.Set(&banCache{}, "banned") + Cache.Touch("banned") } type paramSet struct { @@ -48,17 +38,22 @@ type paramSet struct { type udpWrap struct { *udpapi.AniDBUDP + adb *AniDB + sendLock sync.Mutex sendQueueCh chan paramSet credLock sync.Mutex credentials *credentials connected bool + + user *User } -func newUDPWrap() *udpWrap { +func newUDPWrap(adb *AniDB) *udpWrap { u := &udpWrap{ AniDBUDP: udpapi.NewAniDBUDP(), + adb: adb, sendQueueCh: make(chan paramSet, 10), } go u.sendQueue() @@ -99,8 +94,21 @@ func (r *bannedAPIReply) Error() error { var bannedReply udpapi.APIReply = &bannedAPIReply{} +func (udp *udpWrap) logRequest(set paramSet) { + switch set.cmd { + case "AUTH": + udp.adb.Logger.Printf("UDP>>> AUTH user=%s\n", set.params["user"]) + default: + udp.adb.Logger.Printf("UDP>>> %s %s\n", set.cmd, udpapi.ParamMap(set.params).String()) + } +} + +func (udp *udpWrap) logReply(reply udpapi.APIReply) { + udp.adb.Logger.Printf("UDP<<< %d %s\n", reply.Code(), reply.Text()) +} + func (udp *udpWrap) sendQueue() { - initialWait := 6 * time.Second + initialWait := 5 * time.Second wait := initialWait for set := range udp.sendQueueCh { Retry: @@ -110,29 +118,42 @@ func (udp *udpWrap) sendQueue() { continue } + udp.logRequest(set) reply := <-udp.AniDBUDP.SendRecv(set.cmd, udpapi.ParamMap(set.params)) if reply.Error() == udpapi.TimeoutError { // retry - wait = (wait * 15) / 10 + wait = wait * 2 if wait > time.Minute { wait = time.Minute } + udp.adb.Logger.Printf("UDP--- Timeout; waiting %s before retry", wait) + + delete(set.params, "s") + delete(set.params, "tag") time.Sleep(wait) goto Retry } + udp.logReply(reply) + wait = initialWait switch reply.Code() { case 403, 501, 506: // not logged in, or session expired if r := udp.ReAuth(); r.Error() == nil { // retry + + delete(set.params, "s") + delete(set.params, "tag") + goto Retry } case 503, 504: // client library rejected panic(reply.Error()) - case 555: // IP (and user, possibly client) temporarily banned + // 555: IP (and user, possibly client) temporarily banned + // 601: Server down (treat the same as a ban) + case 555, 601: setBanned() } set.ch <- reply @@ -140,21 +161,6 @@ func (udp *udpWrap) sendQueue() { } } -type errorReply struct { - udpapi.APIReply - err error -} - -func (r *errorReply) Code() int { - return 999 -} -func (r *errorReply) Text() string { - return r.err.Error() -} -func (r *errorReply) Error() error { - return r.err -} - func (udp *udpWrap) SendRecv(cmd string, params paramMap) <-chan udpapi.APIReply { ch := make(chan udpapi.APIReply, 1)