[ARVADOS] created: 2.1.0-1388-gf2bceb1e4
Git user
git at public.arvados.org
Thu Sep 23 13:48:02 UTC 2021
at f2bceb1e477bfc981c8c88c6ec435593480df561 (commit)
commit f2bceb1e477bfc981c8c88c6ec435593480df561
Author: Tom Clegg <tom at curii.com>
Date: Thu Sep 23 09:44:29 2021 -0400
13697: Remove HandlerWithContext.
Use http.Server's BaseContext feature instead.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/lib/controller/auth_test.go b/lib/controller/auth_test.go
index 69458655b..175241146 100644
--- a/lib/controller/auth_test.go
+++ b/lib/controller/auth_test.go
@@ -8,6 +8,7 @@ import (
"context"
"encoding/json"
"fmt"
+ "net"
"net/http"
"net/http/httptest"
"os"
@@ -99,9 +100,10 @@ func (s *AuthSuite) SetUpTest(c *check.C) {
s.testHandler = &Handler{Cluster: cluster}
s.testServer = newServerFromIntegrationTestEnv(c)
- s.testServer.Server.Handler = httpserver.HandlerWithContext(
- ctxlog.Context(context.Background(), s.log),
- httpserver.AddRequestIDs(httpserver.LogRequests(s.testHandler)))
+ s.testServer.Server.BaseContext = func(net.Listener) context.Context {
+ return ctxlog.Context(context.Background(), s.log)
+ }
+ s.testServer.Server.Handler = httpserver.AddRequestIDs(httpserver.LogRequests(s.testHandler))
c.Assert(s.testServer.Start(), check.IsNil)
}
diff --git a/lib/controller/federation_test.go b/lib/controller/federation_test.go
index 6d74ab65f..211c76198 100644
--- a/lib/controller/federation_test.go
+++ b/lib/controller/federation_test.go
@@ -11,6 +11,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
"net/http"
"net/http/httptest"
"net/url"
@@ -71,9 +72,10 @@ func (s *FederationSuite) SetUpTest(c *check.C) {
arvadostest.SetServiceURL(&cluster.Services.Controller, "http://localhost:/")
s.testHandler = &Handler{Cluster: cluster}
s.testServer = newServerFromIntegrationTestEnv(c)
- s.testServer.Server.Handler = httpserver.HandlerWithContext(
- ctxlog.Context(context.Background(), s.log),
- httpserver.AddRequestIDs(httpserver.LogRequests(s.testHandler)))
+ s.testServer.Server.BaseContext = func(net.Listener) context.Context {
+ return ctxlog.Context(context.Background(), s.log)
+ }
+ s.testServer.Server.Handler = httpserver.AddRequestIDs(httpserver.LogRequests(s.testHandler))
cluster.RemoteClusters = map[string]arvados.RemoteCluster{
"zzzzz": {
diff --git a/lib/controller/server_test.go b/lib/controller/server_test.go
index 051f35571..b2b3365a2 100644
--- a/lib/controller/server_test.go
+++ b/lib/controller/server_test.go
@@ -6,6 +6,7 @@ package controller
import (
"context"
+ "net"
"net/http"
"os"
"path/filepath"
@@ -48,9 +49,10 @@ func newServerFromIntegrationTestEnv(c *check.C) *httpserver.Server {
srv := &httpserver.Server{
Server: http.Server{
- Handler: httpserver.HandlerWithContext(
- ctxlog.Context(context.Background(), log),
- httpserver.AddRequestIDs(httpserver.LogRequests(handler))),
+ BaseContext: func(net.Listener) context.Context {
+ return ctxlog.Context(context.Background(), log)
+ },
+ Handler: httpserver.AddRequestIDs(httpserver.LogRequests(handler)),
},
Addr: ":",
}
diff --git a/sdk/go/httpserver/logger.go b/sdk/go/httpserver/logger.go
index 191688096..a0ca6bf28 100644
--- a/sdk/go/httpserver/logger.go
+++ b/sdk/go/httpserver/logger.go
@@ -22,15 +22,6 @@ var (
requestTimeContextKey = contextKey{"requestTime"}
)
-// HandlerWithContext returns an http.Handler that changes the request
-// context to ctx (replacing http.Server's default
-// context.Background()), then calls next.
-func HandlerWithContext(ctx context.Context, next http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- next.ServeHTTP(w, r.WithContext(ctx))
- })
-}
-
// HandlerWithDeadline cancels the request context if the request
// takes longer than the specified timeout.
func HandlerWithDeadline(timeout time.Duration, next http.Handler) http.Handler {
diff --git a/services/keep-web/server.go b/services/keep-web/server.go
index 8f623c627..b0375ff8d 100644
--- a/services/keep-web/server.go
+++ b/services/keep-web/server.go
@@ -6,6 +6,7 @@ package main
import (
"context"
+ "net"
"net/http"
"git.arvados.org/arvados.git/sdk/go/arvados"
@@ -24,10 +25,10 @@ func (srv *server) Start(logger *logrus.Logger) error {
h := &handler{Config: srv.Config}
reg := prometheus.NewRegistry()
h.Config.Cache.registry = reg
- ctx := ctxlog.Context(context.Background(), logger)
- mh := httpserver.Instrument(reg, logger, httpserver.HandlerWithContext(ctx, httpserver.AddRequestIDs(httpserver.LogRequests(h))))
+ mh := httpserver.Instrument(reg, logger, httpserver.AddRequestIDs(httpserver.LogRequests(h)))
h.MetricsAPI = mh.ServeAPI(h.Config.cluster.ManagementToken, http.NotFoundHandler())
srv.Handler = mh
+ srv.BaseContext = func(net.Listener) context.Context { return ctxlog.Context(context.Background(), logger) }
var listen arvados.URL
for listen = range srv.Config.cluster.Services.WebDAV.InternalURLs {
break
commit e66079459c25a3e7dd2e9e4999ebd9f19e2d33b8
Author: Tom Clegg <tom at curii.com>
Date: Thu Sep 23 09:41:20 2021 -0400
13697: Cancel request context after API.RequestTimeout.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/lib/service/cmd.go b/lib/service/cmd.go
index 40db4f9c7..772371888 100644
--- a/lib/service/cmd.go
+++ b/lib/service/cmd.go
@@ -126,13 +126,14 @@ func (c *command) RunCommand(prog string, args []string, stdin io.Reader, stdout
}
instrumented := httpserver.Instrument(reg, log,
- httpserver.HandlerWithContext(ctx,
+ httpserver.HandlerWithDeadline(cluster.API.RequestTimeout,
httpserver.AddRequestIDs(
httpserver.LogRequests(
httpserver.NewRequestLimiter(cluster.API.MaxConcurrentRequests, handler, reg)))))
srv := &httpserver.Server{
Server: http.Server{
- Handler: instrumented.ServeAPI(cluster.ManagementToken, instrumented),
+ Handler: instrumented.ServeAPI(cluster.ManagementToken, instrumented),
+ BaseContext: func(net.Listener) context.Context { return ctx },
},
Addr: listenURL.Host,
}
diff --git a/sdk/go/httpserver/logger.go b/sdk/go/httpserver/logger.go
index 78a1f77ad..191688096 100644
--- a/sdk/go/httpserver/logger.go
+++ b/sdk/go/httpserver/logger.go
@@ -31,6 +31,16 @@ func HandlerWithContext(ctx context.Context, next http.Handler) http.Handler {
})
}
+// HandlerWithDeadline cancels the request context if the request
+// takes longer than the specified timeout.
+func HandlerWithDeadline(timeout time.Duration, next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ ctx, cancel := context.WithDeadline(r.Context(), time.Now().Add(timeout))
+ defer cancel()
+ next.ServeHTTP(w, r.WithContext(ctx))
+ })
+}
+
// LogRequests wraps an http.Handler, logging each request and
// response.
func LogRequests(h http.Handler) http.Handler {
diff --git a/sdk/go/httpserver/logger_test.go b/sdk/go/httpserver/logger_test.go
index af45a640c..b623aa4ee 100644
--- a/sdk/go/httpserver/logger_test.go
+++ b/sdk/go/httpserver/logger_test.go
@@ -41,6 +41,35 @@ func (s *Suite) SetUpTest(c *check.C) {
s.ctx = ctxlog.Context(context.Background(), s.log)
}
+func (s *Suite) TestWithDeadline(c *check.C) {
+ req, err := http.NewRequest("GET", "https://foo.example/bar", nil)
+ c.Assert(err, check.IsNil)
+
+ // Short timeout cancels context in <1s
+ resp := httptest.NewRecorder()
+ HandlerWithDeadline(time.Millisecond, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ select {
+ case <-req.Context().Done():
+ w.Write([]byte("ok"))
+ case <-time.After(time.Second):
+ c.Error("timed out")
+ }
+ })).ServeHTTP(resp, req.WithContext(s.ctx))
+ c.Check(resp.Body.String(), check.Equals, "ok")
+
+ // Long timeout does not cancel context in <1ms
+ resp = httptest.NewRecorder()
+ HandlerWithDeadline(time.Second, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+ select {
+ case <-req.Context().Done():
+ c.Error("request context done too soon")
+ case <-time.After(time.Millisecond):
+ w.Write([]byte("ok"))
+ }
+ })).ServeHTTP(resp, req.WithContext(s.ctx))
+ c.Check(resp.Body.String(), check.Equals, "ok")
+}
+
func (s *Suite) TestLogRequests(c *check.C) {
h := AddRequestIDs(LogRequests(
http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
@@ -52,7 +81,7 @@ func (s *Suite) TestLogRequests(c *check.C) {
c.Assert(err, check.IsNil)
resp := httptest.NewRecorder()
- HandlerWithContext(s.ctx, h).ServeHTTP(resp, req)
+ h.ServeHTTP(resp, req.WithContext(s.ctx))
dec := json.NewDecoder(s.logdata)
@@ -104,12 +133,12 @@ func (s *Suite) TestLogErrorBody(c *check.C) {
c.Assert(err, check.IsNil)
resp := httptest.NewRecorder()
- HandlerWithContext(s.ctx, LogRequests(
+ LogRequests(
http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(trial.statusCode)
w.Write([]byte(trial.sentBody))
}),
- )).ServeHTTP(resp, req)
+ ).ServeHTTP(resp, req.WithContext(s.ctx))
gotReq := make(map[string]interface{})
err = dec.Decode(&gotReq)
commit d90f02c0e969b649da61fdd272a9aab69c487de3
Author: Tom Clegg <tom at curii.com>
Date: Wed Sep 22 16:57:57 2021 -0400
13697: Set Rails database timeout to API.RequestTimeout config.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/services/api/config/arvados_config.rb b/services/api/config/arvados_config.rb
index ea421a289..49865039c 100644
--- a/services/api/config/arvados_config.rb
+++ b/services/api/config/arvados_config.rb
@@ -84,6 +84,7 @@ arvcfg.declare_config "API.MaxRequestSize", Integer, :max_request_size
arvcfg.declare_config "API.MaxIndexDatabaseRead", Integer, :max_index_database_read
arvcfg.declare_config "API.MaxItemsPerResponse", Integer, :max_items_per_response
arvcfg.declare_config "API.MaxTokenLifetime", ActiveSupport::Duration
+arvcfg.declare_config "API.RequestTimeout", ActiveSupport::Duration
arvcfg.declare_config "API.AsyncPermissionsUpdateInterval", ActiveSupport::Duration, :async_permissions_update_interval
arvcfg.declare_config "Users.AutoSetupNewUsers", Boolean, :auto_setup_new_users
arvcfg.declare_config "Users.AutoSetupNewUsersWithVmUUID", String, :auto_setup_new_users_with_vm_uuid
diff --git a/services/api/config/initializers/db_timeout.rb b/services/api/config/initializers/db_timeout.rb
new file mode 100644
index 000000000..3b61f15c8
--- /dev/null
+++ b/services/api/config/initializers/db_timeout.rb
@@ -0,0 +1,9 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+ActiveRecord::ConnectionAdapters::AbstractAdapter.set_callback :checkout, :before, ->(conn) do
+ ms = Rails.configuration.API.RequestTimeout.to_i * 1000
+ conn.execute("SET statement_timeout = #{ms}")
+ conn.execute("SET lock_timeout = #{ms}")
+end
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list