# HG changeset patch # User Sascha L. Teichmann # Date 1557141599 -7200 # Node ID 6a44a89ffb5148c950de0d38181b9048064bf435 # Parent 94935895e6d7b59f769126e411056a07be3b7862 SOAP: Added a globally configurable timeout (default 1min) till a SOAP request is canceled. diff -r 94935895e6d7 -r 6a44a89ffb51 pkg/config/config.go --- a/pkg/config/config.go Mon May 06 13:05:49 2019 +0200 +++ b/pkg/config/config.go Mon May 06 13:19:59 2019 +0200 @@ -22,6 +22,7 @@ "time" homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" "github.com/spf13/viper" @@ -110,6 +111,11 @@ // to be served to to the web client. func PublishedConfig() string { return viper.GetString("published-config") } +// SOAPTimeout is the timeout till a SOAP request is canceled. +func SOAPTimeout() time.Duration { + return viper.GetDuration("soap-timeout") +} + var ( proxyKeyOnce sync.Once proxyKey []byte @@ -229,6 +235,10 @@ fl.Bool(name, value, usage) vbind(name) } + d := func(name string, value time.Duration, usage string) { + fl.Duration(name, value, usage) + vbind(name) + } strP("db-host", "H", "localhost", "host of the database") uiP("db-port", "P", 5432, "port of the database") @@ -273,6 +283,8 @@ str("schema-dirs", ".", "Directories to find XSD schema files in (recursive).") str("published-config", "", "path to a config file served to client.") + + d("soap-timeout", time.Minute, "Timeout till a SOAP request is canceled.") } var ( diff -r 94935895e6d7 -r 6a44a89ffb51 pkg/imports/erdms.go --- a/pkg/imports/erdms.go Mon May 06 13:05:49 2019 +0200 +++ b/pkg/imports/erdms.go Mon May 06 13:19:59 2019 +0200 @@ -18,6 +18,7 @@ "context" "database/sql" "fmt" + "log" "strings" "gemma.intevation.de/gemma/pkg/soap" @@ -93,8 +94,18 @@ }, } + const maxTries = 3 + + tries := 0 + + again: data, err := client.GetRisDataXML(request) if err != nil { + if t, ok := err.(interface{ Timeout() bool }); ok && t.Timeout() && tries < maxTries { + log.Println("warn: ERDMS SOAP request timed out. Trying again.") + tries++ + goto again + } return nil, fmt.Errorf("Error requesting ERDMS service: %v", err) } responseData = append(responseData, data) diff -r 94935895e6d7 -r 6a44a89ffb51 pkg/soap/soap.go --- a/pkg/soap/soap.go Mon May 06 13:05:49 2019 +0200 +++ b/pkg/soap/soap.go Mon May 06 13:19:59 2019 +0200 @@ -15,6 +15,7 @@ import ( "bytes" + "context" "crypto/tls" "encoding/xml" "fmt" @@ -23,7 +24,10 @@ "math/rand" "net" "net/http" + "sync" "time" + + "gemma.intevation.de/gemma/pkg/config" ) const timeout = time.Duration(30 * time.Second) @@ -272,6 +276,21 @@ client := &http.Client{Transport: tr} + timeout := config.SOAPTimeout() + + ctx, cancel := context.WithTimeout(context.Background(), timeout) + + var once sync.Once + + defer once.Do(cancel) + + req = req.WithContext(ctx) + + go func() { + defer once.Do(cancel) + <-ctx.Done() + }() + res, err := client.Do(req) if err != nil { return err