]> git.lizzy.rs Git - go-anidb.git/blobdiff - udp.go
anidb: Simplify (*AniDB).EpisodeByID()
[go-anidb.git] / udp.go
diff --git a/udp.go b/udp.go
index 84cd5c8124b0c0ad3b6e2f73e37c591738f4d4e9..ec8f83d9d16c9c02018dbdca678521c3317bf947 100644 (file)
--- a/udp.go
+++ b/udp.go
@@ -3,6 +3,8 @@ package anidb
 import (
        "encoding/gob"
        "github.com/Kovensky/go-anidb/udp"
+       "log"
+       "sync"
        "time"
 )
 
@@ -46,8 +48,10 @@ type paramSet struct {
 type udpWrap struct {
        *udpapi.AniDBUDP
 
+       sendLock    sync.Mutex
        sendQueueCh chan paramSet
 
+       credLock    sync.Mutex
        credentials *credentials
        connected   bool
 }
@@ -95,11 +99,31 @@ func (r *bannedAPIReply) Error() error {
 
 var bannedReply udpapi.APIReply = &bannedAPIReply{}
 
+func logRequest(set paramSet) {
+       switch set.cmd {
+       case "AUTH":
+               log.Printf("UDP>>> AUTH user=%s\n", set.params["user"])
+       default:
+               log.Printf("UDP>>> %s %s\n", set.cmd, udpapi.ParamMap(set.params).String())
+       }
+}
+
+func logReply(reply udpapi.APIReply) {
+       log.Printf("UDP<<< %d %s\n", reply.Code(), reply.Text())
+}
+
 func (udp *udpWrap) sendQueue() {
        initialWait := 6 * time.Second
        wait := initialWait
        for set := range udp.sendQueueCh {
        Retry:
+               if Banned() {
+                       set.ch <- bannedReply
+                       close(set.ch)
+                       continue
+               }
+
+               logRequest(set)
                reply := <-udp.AniDBUDP.SendRecv(set.cmd, udpapi.ParamMap(set.params))
 
                if reply.Error() == udpapi.TimeoutError {
@@ -108,14 +132,18 @@ func (udp *udpWrap) sendQueue() {
                        if wait > time.Minute {
                                wait = time.Minute
                        }
+                       log.Printf("UDP--- Timeout; waiting %s before retry", wait)
+
                        time.Sleep(wait)
                        goto Retry
                }
+               logReply(reply)
+
                wait = initialWait
 
                switch reply.Code() {
                case 403, 501, 506: // not logged in, or session expired
-                       if err := udp.ReAuth(); err == nil {
+                       if r := udp.ReAuth(); r.Error() == nil {
                                // retry
                                goto Retry
                        }
@@ -129,13 +157,26 @@ 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)
-       if udp.credentials == nil {
-               ch <- &noauthAPIReply{}
-               close(ch)
-               return ch
-       }
+
+       udp.sendLock.Lock()
+       defer udp.sendLock.Unlock()
 
        if Banned() {
                ch <- bannedReply
@@ -143,6 +184,14 @@ func (udp *udpWrap) SendRecv(cmd string, params paramMap) <-chan udpapi.APIReply
                return ch
        }
 
+       if !udp.connected {
+               if r := udp.ReAuth(); r.Error() != nil {
+                       ch <- r
+                       close(ch)
+                       return ch
+               }
+       }
+
        udp.sendQueueCh <- paramSet{
                cmd:    cmd,
                params: params,