mirror of
https://github.com/matrix-org/sliding-sync.git
synced 2025-03-10 13:37:11 +00:00
Make HTTP timeout configurable
This commit is contained in:
parent
3a451cb22f
commit
a397b72c30
@ -42,19 +42,21 @@ const (
|
||||
EnvSecret = "SYNCV3_SECRET"
|
||||
|
||||
// Optional fields
|
||||
EnvBindAddr = "SYNCV3_BINDADDR"
|
||||
EnvTLSCert = "SYNCV3_TLS_CERT"
|
||||
EnvTLSKey = "SYNCV3_TLS_KEY"
|
||||
EnvPPROF = "SYNCV3_PPROF"
|
||||
EnvPrometheus = "SYNCV3_PROM"
|
||||
EnvDebug = "SYNCV3_DEBUG"
|
||||
EnvOTLP = "SYNCV3_OTLP_URL"
|
||||
EnvOTLPUsername = "SYNCV3_OTLP_USERNAME"
|
||||
EnvOTLPPassword = "SYNCV3_OTLP_PASSWORD"
|
||||
EnvSentryDsn = "SYNCV3_SENTRY_DSN"
|
||||
EnvLogLevel = "SYNCV3_LOG_LEVEL"
|
||||
EnvMaxConns = "SYNCV3_MAX_DB_CONN"
|
||||
EnvIdleTimeoutSecs = "SYNCV3_DB_IDLE_TIMEOUT_SECS"
|
||||
EnvBindAddr = "SYNCV3_BINDADDR"
|
||||
EnvTLSCert = "SYNCV3_TLS_CERT"
|
||||
EnvTLSKey = "SYNCV3_TLS_KEY"
|
||||
EnvPPROF = "SYNCV3_PPROF"
|
||||
EnvPrometheus = "SYNCV3_PROM"
|
||||
EnvDebug = "SYNCV3_DEBUG"
|
||||
EnvOTLP = "SYNCV3_OTLP_URL"
|
||||
EnvOTLPUsername = "SYNCV3_OTLP_USERNAME"
|
||||
EnvOTLPPassword = "SYNCV3_OTLP_PASSWORD"
|
||||
EnvSentryDsn = "SYNCV3_SENTRY_DSN"
|
||||
EnvLogLevel = "SYNCV3_LOG_LEVEL"
|
||||
EnvMaxConns = "SYNCV3_MAX_DB_CONN"
|
||||
EnvIdleTimeoutSecs = "SYNCV3_DB_IDLE_TIMEOUT_SECS"
|
||||
EnvHTTPTimeoutSecs = "SYNCV3_HTTP_TIMEOUT_SECS"
|
||||
EnvHTTPInitialTimeoutSecs = "SYNCV3_HTTP_INITIAL_TIMEOUT_SECS"
|
||||
)
|
||||
|
||||
var helpMsg = fmt.Sprintf(`
|
||||
@ -74,8 +76,10 @@ Environment var
|
||||
%s Default: info. The level of verbosity for messages logged. Available values are trace, debug, info, warn, error and fatal
|
||||
%s Default: unset. Max database connections to use when communicating with postgres. Unset or 0 means no limit.
|
||||
%s Default: 3600. The maximum amount of time a database connection may be idle, in seconds. 0 means no limit.
|
||||
%s Default: 300. The timeout in seconds for normal HTTP requests.
|
||||
%s Default: 1800. The timeout in seconds for initial sync requests.
|
||||
`, EnvServer, EnvDB, EnvSecret, EnvBindAddr, EnvTLSCert, EnvTLSKey, EnvPPROF, EnvPrometheus, EnvOTLP, EnvOTLPUsername, EnvOTLPPassword,
|
||||
EnvSentryDsn, EnvLogLevel, EnvMaxConns, EnvIdleTimeoutSecs)
|
||||
EnvSentryDsn, EnvLogLevel, EnvMaxConns, EnvIdleTimeoutSecs, EnvHTTPTimeoutSecs, EnvHTTPInitialTimeoutSecs)
|
||||
|
||||
func defaulting(in, dft string) string {
|
||||
if in == "" {
|
||||
@ -96,22 +100,24 @@ func main() {
|
||||
}
|
||||
|
||||
args := map[string]string{
|
||||
EnvServer: os.Getenv(EnvServer),
|
||||
EnvDB: os.Getenv(EnvDB),
|
||||
EnvSecret: os.Getenv(EnvSecret),
|
||||
EnvBindAddr: defaulting(os.Getenv(EnvBindAddr), "0.0.0.0:8008"),
|
||||
EnvTLSCert: os.Getenv(EnvTLSCert),
|
||||
EnvTLSKey: os.Getenv(EnvTLSKey),
|
||||
EnvPPROF: os.Getenv(EnvPPROF),
|
||||
EnvPrometheus: os.Getenv(EnvPrometheus),
|
||||
EnvDebug: os.Getenv(EnvDebug),
|
||||
EnvOTLP: os.Getenv(EnvOTLP),
|
||||
EnvOTLPUsername: os.Getenv(EnvOTLPUsername),
|
||||
EnvOTLPPassword: os.Getenv(EnvOTLPPassword),
|
||||
EnvSentryDsn: os.Getenv(EnvSentryDsn),
|
||||
EnvLogLevel: os.Getenv(EnvLogLevel),
|
||||
EnvMaxConns: defaulting(os.Getenv(EnvMaxConns), "0"),
|
||||
EnvIdleTimeoutSecs: defaulting(os.Getenv(EnvIdleTimeoutSecs), "3600"),
|
||||
EnvServer: os.Getenv(EnvServer),
|
||||
EnvDB: os.Getenv(EnvDB),
|
||||
EnvSecret: os.Getenv(EnvSecret),
|
||||
EnvBindAddr: defaulting(os.Getenv(EnvBindAddr), "0.0.0.0:8008"),
|
||||
EnvTLSCert: os.Getenv(EnvTLSCert),
|
||||
EnvTLSKey: os.Getenv(EnvTLSKey),
|
||||
EnvPPROF: os.Getenv(EnvPPROF),
|
||||
EnvPrometheus: os.Getenv(EnvPrometheus),
|
||||
EnvDebug: os.Getenv(EnvDebug),
|
||||
EnvOTLP: os.Getenv(EnvOTLP),
|
||||
EnvOTLPUsername: os.Getenv(EnvOTLPUsername),
|
||||
EnvOTLPPassword: os.Getenv(EnvOTLPPassword),
|
||||
EnvSentryDsn: os.Getenv(EnvSentryDsn),
|
||||
EnvLogLevel: os.Getenv(EnvLogLevel),
|
||||
EnvMaxConns: defaulting(os.Getenv(EnvMaxConns), "0"),
|
||||
EnvIdleTimeoutSecs: defaulting(os.Getenv(EnvIdleTimeoutSecs), "3600"),
|
||||
EnvHTTPTimeoutSecs: defaulting(os.Getenv(EnvIdleTimeoutSecs), "300"),
|
||||
EnvHTTPInitialTimeoutSecs: defaulting(os.Getenv(EnvHTTPInitialTimeoutSecs), "1800"),
|
||||
}
|
||||
requiredEnvVars := []string{EnvServer, EnvDB, EnvSecret, EnvBindAddr}
|
||||
for _, requiredEnvVar := range requiredEnvVars {
|
||||
@ -203,11 +209,21 @@ func main() {
|
||||
if err != nil {
|
||||
panic("invalid value for " + EnvIdleTimeoutSecs + ": " + args[EnvIdleTimeoutSecs])
|
||||
}
|
||||
httpTimeoutSecs, err := strconv.Atoi(args[EnvHTTPTimeoutSecs])
|
||||
if err != nil {
|
||||
panic("invalid value for " + EnvHTTPTimeoutSecs + ": " + args[EnvHTTPTimeoutSecs])
|
||||
}
|
||||
httpLongTimeoutSecs, err := strconv.Atoi(args[EnvHTTPInitialTimeoutSecs])
|
||||
if err != nil {
|
||||
panic("invalid value for " + EnvHTTPInitialTimeoutSecs + ": " + args[EnvHTTPInitialTimeoutSecs])
|
||||
}
|
||||
h2, h3 := syncv3.Setup(args[EnvServer], args[EnvDB], args[EnvSecret], syncv3.Opts{
|
||||
AddPrometheusMetrics: args[EnvPrometheus] != "",
|
||||
DBMaxConns: maxConnsInt,
|
||||
DBConnMaxIdleTime: time.Duration(idleTimeSecs) * time.Second,
|
||||
MaxTransactionIDDelay: time.Second,
|
||||
HTTPTimeout: time.Duration(httpTimeoutSecs) * time.Second,
|
||||
HTTPLongTimeout: time.Duration(httpLongTimeoutSecs) * time.Second,
|
||||
})
|
||||
|
||||
go h2.StartV2Pollers()
|
||||
|
@ -4,12 +4,13 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
@ -30,9 +31,24 @@ type Client interface {
|
||||
// One client can be shared among many users.
|
||||
type HTTPClient struct {
|
||||
Client *http.Client
|
||||
LongTimeoutClient *http.Client
|
||||
DestinationServer string
|
||||
}
|
||||
|
||||
func NewHTTPClient(shortTimeout, longTimeout time.Duration, destHomeServer string) *HTTPClient {
|
||||
return &HTTPClient{
|
||||
LongTimeoutClient: &http.Client{
|
||||
Timeout: longTimeout,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
},
|
||||
Client: &http.Client{
|
||||
Timeout: shortTimeout,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
},
|
||||
DestinationServer: destHomeServer,
|
||||
}
|
||||
}
|
||||
|
||||
// Return sync2.HTTP401 if this request returns 401
|
||||
func (v *HTTPClient) WhoAmI(ctx context.Context, accessToken string) (string, string, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", v.DestinationServer+"/_matrix/client/r0/account/whoami", nil)
|
||||
@ -72,11 +88,7 @@ func (v *HTTPClient) DoSyncV2(ctx context.Context, accessToken, since string, is
|
||||
}
|
||||
var res *http.Response
|
||||
if isFirst {
|
||||
longTimeoutClient := &http.Client{
|
||||
Timeout: 30 * time.Minute,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
}
|
||||
res, err = longTimeoutClient.Do(req)
|
||||
res, err = v.LongTimeoutClient.Do(req)
|
||||
} else {
|
||||
res, err = v.Client.Do(req)
|
||||
}
|
||||
|
17
v3.go
17
v3.go
@ -15,15 +15,13 @@ import (
|
||||
"github.com/matrix-org/sliding-sync/internal"
|
||||
"github.com/matrix-org/sliding-sync/pubsub"
|
||||
"github.com/matrix-org/sliding-sync/state"
|
||||
_ "github.com/matrix-org/sliding-sync/state/migrations"
|
||||
"github.com/matrix-org/sliding-sync/sync2"
|
||||
"github.com/matrix-org/sliding-sync/sync2/handler2"
|
||||
"github.com/matrix-org/sliding-sync/sync3/handler"
|
||||
"github.com/pressly/goose/v3"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/hlog"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
|
||||
_ "github.com/matrix-org/sliding-sync/state/migrations"
|
||||
)
|
||||
|
||||
//go:embed state/migrations/*
|
||||
@ -51,6 +49,11 @@ type Opts struct {
|
||||
|
||||
DBMaxConns int
|
||||
DBConnMaxIdleTime time.Duration
|
||||
|
||||
// HTTPTimeout is used for "normal" HTTP requests
|
||||
HTTPTimeout time.Duration
|
||||
// HTTPLongTimeout is used for initial sync requests
|
||||
HTTPLongTimeout time.Duration
|
||||
}
|
||||
|
||||
type server struct {
|
||||
@ -82,13 +85,7 @@ func allowCORS(next http.Handler) http.HandlerFunc {
|
||||
// Setup the proxy
|
||||
func Setup(destHomeserver, postgresURI, secret string, opts Opts) (*handler2.Handler, http.Handler) {
|
||||
// Setup shared DB and HTTP client
|
||||
v2Client := &sync2.HTTPClient{
|
||||
Client: &http.Client{
|
||||
Timeout: 5 * time.Minute,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
},
|
||||
DestinationServer: destHomeserver,
|
||||
}
|
||||
v2Client := sync2.NewHTTPClient(opts.HTTPTimeout, opts.HTTPLongTimeout, destHomeserver)
|
||||
db, err := sqlx.Open("postgres", postgresURI)
|
||||
if err != nil {
|
||||
sentry.CaptureException(err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user