From d7e9be99f9dd9cd73f02b1609357e111a5a59084 Mon Sep 17 00:00:00 2001 From: Dmitry Verkhoturov Date: Mon, 26 Dec 2022 20:13:38 +0400 Subject: [PATCH] make Close() calls idempotent Previously, few of them resulted in panics when called more than once. --- .../memory_store/accessor/data_test.go | 1 + backend/_example/memory_store/go.mod | 2 +- backend/_example/memory_store/go.sum | 4 +- .../_example/memory_store/server/data_test.go | 4 +- backend/app/notify/notify.go | 6 + backend/app/notify/notify_test.go | 2 + backend/app/store/engine/bolt_test.go | 7 ++ backend/app/store/engine/remote_test.go | 12 +- backend/app/store/image/image_test.go | 8 ++ backend/app/store/service/service_test.go | 24 ++++ backend/app/store/service/title_test.go | 7 ++ backend/go.mod | 10 +- backend/go.sum | 28 +++-- .../github.com/go-pkgz/auth/.golangci.yml | 10 +- .../vendor/github.com/go-pkgz/auth/README.md | 8 +- .../github.com/go-pkgz/auth/avatar/gridfs.go | 3 +- .../github.com/go-pkgz/auth/avatar/localfs.go | 2 +- .../go-pkgz/auth/provider/custom_server.go | 3 +- .../go-pkgz/auth/provider/dev_provider.go | 3 +- .../vendor/github.com/go-pkgz/email/email.go | 2 +- .../github.com/go-pkgz/lcw/.golangci.yml | 6 +- .../vendor/github.com/go-pkgz/lcw/README.md | 39 +++--- .../vendor/github.com/go-pkgz/lcw/cache.go | 2 - .../go-pkgz/lcw/internal/cache/cache.go | 6 + .../hashicorp/golang-lru/.golangci.yml | 30 +++++ .../github.com/hashicorp/golang-lru/2q.go | 3 +- .../github.com/hashicorp/golang-lru/LICENSE | 2 + .../github.com/hashicorp/golang-lru/README.md | 2 +- .../github.com/hashicorp/golang-lru/arc.go | 1 - .../github.com/hashicorp/golang-lru/lru.go | 119 +++++++++++++++--- .../hashicorp/golang-lru/simplelru/lru.go | 6 +- .../golang-lru/simplelru/lru_interface.go | 5 +- .../hashicorp/golang-lru/testing.go | 16 +++ backend/vendor/modules.txt | 12 +- 34 files changed, 298 insertions(+), 97 deletions(-) create mode 100644 backend/vendor/github.com/hashicorp/golang-lru/.golangci.yml create mode 100644 backend/vendor/github.com/hashicorp/golang-lru/testing.go diff --git a/backend/_example/memory_store/accessor/data_test.go b/backend/_example/memory_store/accessor/data_test.go index abc22d7a..db052979 100644 --- a/backend/_example/memory_store/accessor/data_test.go +++ b/backend/_example/memory_store/accessor/data_test.go @@ -624,6 +624,7 @@ func TestMemData_DeleteComment(t *testing.T) { func TestMemData_Close(t *testing.T) { b := prepMem(t) assert.NoError(t, b.Close()) + assert.NoError(t, b.Close(), "second call should not result in panic or errors") } func TestMemData_DeleteHard(t *testing.T) { diff --git a/backend/_example/memory_store/go.mod b/backend/_example/memory_store/go.mod index 332e65c3..40d5c619 100644 --- a/backend/_example/memory_store/go.mod +++ b/backend/_example/memory_store/go.mod @@ -6,7 +6,7 @@ require ( github.com/go-pkgz/jrpc v0.3.0 github.com/go-pkgz/lgr v0.10.4 github.com/jessevdk/go-flags v1.5.0 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.1 github.com/umputun/remark42/backend v1.10.1 ) diff --git a/backend/_example/memory_store/go.sum b/backend/_example/memory_store/go.sum index 4269bbd8..48445533 100644 --- a/backend/_example/memory_store/go.sum +++ b/backend/_example/memory_store/go.sum @@ -60,11 +60,13 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw= diff --git a/backend/_example/memory_store/server/data_test.go b/backend/_example/memory_store/server/data_test.go index 5e8f7efe..b1d2fd3d 100644 --- a/backend/_example/memory_store/server/data_test.go +++ b/backend/_example/memory_store/server/data_test.go @@ -338,6 +338,6 @@ func TestRPC_closeHndl(t *testing.T) { api := fmt.Sprintf("http://localhost:%d/test", port) re := engine.RPC{Client: jrpc.Client{API: api, Client: http.Client{Timeout: 1 * time.Second}}} - err := re.Close() - assert.NoError(t, err) + assert.NoError(t, re.Close()) + assert.NoError(t, re.Close(), "second call should not result in panic or errors") } diff --git a/backend/app/notify/notify.go b/backend/app/notify/notify.go index 54d8d404..d8bdddbe 100644 --- a/backend/app/notify/notify.go +++ b/backend/app/notify/notify.go @@ -143,6 +143,12 @@ func (s *Service) SubmitVerification(req VerificationRequest) { // Close queue channel and wait for completion func (s *Service) Close() { if s.queue != nil { + // don't panic in case service is already closed + select { + case <-s.ctx.Done(): + return + default: + } log.Print("[DEBUG] close notifier") close(s.queue) close(s.verificationQueue) diff --git a/backend/app/notify/notify_test.go b/backend/app/notify/notify_test.go index 91e677d9..07b88c30 100644 --- a/backend/app/notify/notify_test.go +++ b/backend/app/notify/notify_test.go @@ -21,6 +21,8 @@ func TestService_NoDestinations(t *testing.T) { s.Submit(Request{Comment: store.Comment{ID: "123"}}) s.Submit(Request{Comment: store.Comment{ID: "123"}}) s.Close() + // second call should not result in panic + s.Close() } func TestService_WithDestinations(t *testing.T) { diff --git a/backend/app/store/engine/bolt_test.go b/backend/app/store/engine/bolt_test.go index 5985e57c..b51f4ebe 100644 --- a/backend/app/store/engine/bolt_test.go +++ b/backend/app/store/engine/bolt_test.go @@ -911,6 +911,13 @@ func TestBoltDB_NewFailed(t *testing.T) { assert.EqualError(t, err, "failed to make boltdb for /tmp/no-such-place/tmp.db: open /tmp/no-such-place/tmp.db: no such file or directory") } +func TestBoltDB_DoubleClose(t *testing.T) { + var b, teardown = prep(t) + defer teardown() + assert.NoError(t, b.Close()) + assert.NoError(t, b.Close(), "second call should not result in panic or errors") +} + // makes new boltdb, put two records func prep(t *testing.T) (b *BoltDB, teardown func()) { _ = os.Remove(testDB) diff --git a/backend/app/store/engine/remote_test.go b/backend/app/store/engine/remote_test.go index fe0a10fd..25cd253d 100644 --- a/backend/app/store/engine/remote_test.go +++ b/backend/app/store/engine/remote_test.go @@ -186,11 +186,17 @@ func TestRemote_Delete(t *testing.T) { } func TestRemote_Close(t *testing.T) { - ts := testServer(t, `{"method":"store.close","id":1}`, `{}`) + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + require.NoError(t, err) + assert.Contains(t, string(body), "{\"method\":\"store.close\",\"id\":") + t.Logf("req: %s", string(body)) + _, _ = fmt.Fprint(w, "{}") + })) defer ts.Close() c := RPC{Client: jrpc.Client{API: ts.URL, Client: http.Client{}}} - err := c.Close() - assert.NoError(t, err) + assert.NoError(t, c.Close()) + assert.NoError(t, c.Close(), "second call should not result in panic or errors") } func testServer(t *testing.T, req, resp string) *httptest.Server { diff --git a/backend/app/store/image/image_test.go b/backend/app/store/image/image_test.go index d1f11a8f..5e234009 100644 --- a/backend/app/store/image/image_test.go +++ b/backend/app/store/image/image_test.go @@ -286,3 +286,11 @@ func TestCachedImgID(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "cached_images/"+Sha1Str("example.org")+"-"+Sha1Str(imgURL), img) } + +func TestService_DoubleClose(t *testing.T) { + store := StoreMock{} + svc := NewService(&store, ServiceParams{EditDuration: 20 * time.Millisecond}) + svc.Close(context.TODO()) + // second call should not result in panic + svc.Close(context.TODO()) +} diff --git a/backend/app/store/service/service_test.go b/backend/app/store/service/service_test.go index 80f57d2c..e4ff08f7 100644 --- a/backend/app/store/service/service_test.go +++ b/backend/app/store/service/service_test.go @@ -1638,6 +1638,30 @@ func Benchmark_ServiceCreate(b *testing.B) { } } +func TestService_DoubleClose_Bolt(t *testing.T) { + dbFile := fmt.Sprintf("%s/test-remark42-%d.db", os.TempDir(), rand.Intn(9999999999)) + defer func() { _ = os.Remove(dbFile) }() + + boltStore, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: dbFile, SiteID: "radio-t"}) + svc := DataStore{Engine: boltStore, EditDuration: 50 * time.Millisecond, AdminStore: admin.NewStaticKeyStore("secret 123")} + require.NoError(t, err) + assert.NoError(t, boltStore.Close()) + assert.NoError(t, boltStore.Close(), "second call should not result in panic or errors") + assert.NoError(t, svc.Close()) + assert.NoError(t, svc.Close(), "second call should not result in panic or errors") +} + +func TestService_DoubleClose_Static(t *testing.T) { + ks := admin.NewStaticKeyStore("secret 123") + eng, teardown := prepStoreEngine(t) + defer teardown() + b := DataStore{Engine: eng, AdminStore: ks, + TitleExtractor: NewTitleExtractor(http.Client{Timeout: 5 * time.Second})} + b.Close() + // second call should not result in panic or errors + b.Close() +} + // makes new boltdb, put two records func prepStoreEngine(t *testing.T) (e engine.Interface, teardown func()) { testDBLoc, err := os.MkdirTemp("", "test_image_r42") diff --git a/backend/app/store/service/title_test.go b/backend/app/store/service/title_test.go index 17a83ea1..2dd5af76 100644 --- a/backend/app/store/service/title_test.go +++ b/backend/app/store/service/title_test.go @@ -123,3 +123,10 @@ func TestTitle_GetFailed(t *testing.T) { } assert.Equal(t, int32(1), atomic.LoadInt32(&hits), "hit once, errors cached") } + +func TestTitle_DoubleClosed(t *testing.T) { + ex := NewTitleExtractor(http.Client{Timeout: 5 * time.Second}) + ex.Close() + // second call should not result in panic + ex.Close() +} diff --git a/backend/go.mod b/backend/go.mod index a7d8d958..831a11de 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -11,9 +11,9 @@ require ( github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 github.com/go-chi/render v1.0.2 - github.com/go-pkgz/auth v1.20.0 + github.com/go-pkgz/auth v1.20.1-0.20221226231300-65f433fba0f1 github.com/go-pkgz/jrpc v0.3.0 - github.com/go-pkgz/lcw v1.0.1 + github.com/go-pkgz/lcw v1.0.3-0.20221226231215-a66ea7c4aff7 github.com/go-pkgz/lgr v0.10.4 github.com/go-pkgz/notify v0.2.0 github.com/go-pkgz/repeater v1.1.3 @@ -29,7 +29,7 @@ require ( github.com/rs/xid v1.4.0 github.com/russross/blackfriday/v2 v2.1.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.1 go.etcd.io/bbolt v1.3.6 go.uber.org/goleak v1.2.0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d @@ -48,7 +48,7 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dlclark/regexp2 v1.4.0 // indirect github.com/go-oauth2/oauth2/v4 v4.5.1 // indirect - github.com/go-pkgz/email v0.4.0 // indirect + github.com/go-pkgz/email v0.4.1 // indirect github.com/go-pkgz/expirable-cache v0.1.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -56,7 +56,7 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/klauspost/compress v1.15.2 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 // indirect diff --git a/backend/go.sum b/backend/go.sum index 9e4bda2d..4a1d6a86 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -69,8 +69,8 @@ github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis/v2 v2.22.0 h1:lIHHiSkEyS1MkKHCHzN+0mWrA4YdbGdimE5iZ2sHSzo= -github.com/alicebob/miniredis/v2 v2.22.0/go.mod h1:XNqvJdQJv5mSuVMc0ynneafpnL/zv52acZ6kqeS0t88= +github.com/alicebob/miniredis/v2 v2.23.1 h1:jR6wZggBxwWygeXcdNyguCOCIjPsZyNUNlAkTx2fu0U= +github.com/alicebob/miniredis/v2 v2.23.1/go.mod h1:84TWKZlxYkfgMucPBf5SOQBYJceZeQRFIaQgNMiCX6Q= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= @@ -140,17 +140,17 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-oauth2/oauth2/v4 v4.5.1 h1:3vxp+cjLqDe1TbogbwtMyeHRHr1tD+ksrK7xNppYRDs= github.com/go-oauth2/oauth2/v4 v4.5.1/go.mod h1:wk/2uLImWIa9VVQDgxz99H2GDbhmfi/9/Xr+GvkSUSQ= -github.com/go-pkgz/auth v1.20.0 h1:9SHkolgv9+zOI9U+8IFXra0pl/H90oE4+ciJWtXoDl4= -github.com/go-pkgz/auth v1.20.0/go.mod h1:jz0djN+4XoCyieuOzc+rB9l0RdqeuiXoQfE02yonLAI= +github.com/go-pkgz/auth v1.20.1-0.20221226231300-65f433fba0f1 h1:MJA4rZAwjd+KpaR2PqrxeDPloNu9Wml1UVQjL2fOtVM= +github.com/go-pkgz/auth v1.20.1-0.20221226231300-65f433fba0f1/go.mod h1:fG1CP4+LDPnebYeO1BAZg/euTQQ8cnGn+5ZrXvJfckA= github.com/go-pkgz/email v0.3.1-0.20221002173339-19d25a20d99c/go.mod h1:TpnmSLkQW3FyICit2hn7WIhCUDrhCX6btzz5wS3wHRI= -github.com/go-pkgz/email v0.4.0 h1:NiYCwKPR6sW8nJsOR3GyB9Yw1AQZdnY78Xnhd9SLHEs= -github.com/go-pkgz/email v0.4.0/go.mod h1:TpnmSLkQW3FyICit2hn7WIhCUDrhCX6btzz5wS3wHRI= +github.com/go-pkgz/email v0.4.1 h1:2vtP2gibsSzqhz6eD5DklSp11m657XEVf17fuXaxMvk= +github.com/go-pkgz/email v0.4.1/go.mod h1:BdxglsQnymzhfdbnncEE72a6DrucZHy6I+42LK2jLEc= github.com/go-pkgz/expirable-cache v0.1.0 h1:3bw0m8vlTK8qlwz5KXuygNBTkiKRTPrAGXU0Ej2AC1g= github.com/go-pkgz/expirable-cache v0.1.0/go.mod h1:GTrEl0X+q0mPNqN6dtcQXksACnzCBQ5k/k1SwXJsZKs= github.com/go-pkgz/jrpc v0.3.0 h1:Fls38KqPsHzvp0FWfivr6cGnncC+iFBodHBqvUPY+0U= github.com/go-pkgz/jrpc v0.3.0/go.mod h1:MFtKs75JESiSqVicsQkgN2iDFFuCd3gVT1/vKiwRi00= -github.com/go-pkgz/lcw v1.0.1 h1:svYC6LIyzRaHF3TwJ8GCS+2RkJreBfaFjoeS+UYwJBc= -github.com/go-pkgz/lcw v1.0.1/go.mod h1:CPJJzunpmGToOtD0Ga82TV152eL69sYEIIPcy9fbxlU= +github.com/go-pkgz/lcw v1.0.3-0.20221226231215-a66ea7c4aff7 h1:PJ1JEt2G0Dn7OUkLEgbNIrABRcbkCPM8v58BIBOSkm8= +github.com/go-pkgz/lcw v1.0.3-0.20221226231215-a66ea7c4aff7/go.mod h1:adhOCEhc8G6+Bd992MMp0h796aBxZ/b4feUGU5twkRU= github.com/go-pkgz/lgr v0.10.4 h1:l7qyFjqEZgwRgaQQSEp6tve4A3OU80VrfzpvtEX8ngw= github.com/go-pkgz/lgr v0.10.4/go.mod h1:CD0s1z6EFpIUplV067gitF77tn25JItzwHNKAPqeCF0= github.com/go-pkgz/notify v0.2.0 h1:mxHjcLc3goT+k1qnBPJ06PpNuVUDcu21Xy+6hEo4IaU= @@ -270,8 +270,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= +github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -343,6 +343,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -350,8 +351,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E= github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8= github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo= @@ -403,8 +405,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw= -github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= +github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 h1:5mLPGnFdSsevFRFc9q3yYbBkB6tsm4aCwwQV/j1JQAQ= +github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.mongodb.org/mongo-driver v1.10.2 h1:4Wk3cnqOrQCn0P92L3/mmurMxzdvWWs5J9jinAVKD+k= diff --git a/backend/vendor/github.com/go-pkgz/auth/.golangci.yml b/backend/vendor/github.com/go-pkgz/auth/.golangci.yml index 25d24330..67c4ebac 100644 --- a/backend/vendor/github.com/go-pkgz/auth/.golangci.yml +++ b/backend/vendor/github.com/go-pkgz/auth/.golangci.yml @@ -29,17 +29,13 @@ linters: - revive - govet - unconvert - - megacheck - - structcheck + - unused - gas - gocyclo - misspell - unparam - - varcheck - - deadcode - typecheck - ineffassign - - varcheck - stylecheck - gochecknoinits - exportloopref @@ -67,5 +63,9 @@ issues: - text: "Use of weak cryptographic primitive" linters: - gosec + - path: _test\.go + text: "Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server" + linters: + - gosec exclude-use-default: false diff --git a/backend/vendor/github.com/go-pkgz/auth/README.md b/backend/vendor/github.com/go-pkgz/auth/README.md index 26f12ae8..575be4c1 100644 --- a/backend/vendor/github.com/go-pkgz/auth/README.md +++ b/backend/vendor/github.com/go-pkgz/auth/README.md @@ -153,10 +153,6 @@ Such provider acts like any other, i.e. will be registered as `/auth/local/login The API for this provider supports both GET and POST requests: -* GET request with user credentials provided as query params: - ``` - GET /auth//login?user=&passwd=&aud=&session=[1|0] - ``` * POST request could be encoded as application/x-www-form-urlencoded or application/json: ``` POST /auth//login?session=[1|0] @@ -172,6 +168,10 @@ The API for this provider supports both GET and POST requests: "aud": "bar", } ``` +* GET request with user credentials provided as query params, but be aware that [the https query string is not secure](https://stackoverflow.com/a/323286/633961): + ``` + GET /auth//login?user=&passwd=&aud=&session=[1|0] + ``` _note: password parameter doesn't have to be naked/real password and can be any kind of password hash prepared by caller._ diff --git a/backend/vendor/github.com/go-pkgz/auth/avatar/gridfs.go b/backend/vendor/github.com/go-pkgz/auth/avatar/gridfs.go index 59ce0108..a6f4b0ab 100644 --- a/backend/vendor/github.com/go-pkgz/auth/avatar/gridfs.go +++ b/backend/vendor/github.com/go-pkgz/auth/avatar/gridfs.go @@ -59,7 +59,6 @@ func (gf *GridFS) Get(avatar string) (reader io.ReadCloser, size int, err error) return io.NopCloser(buf), int(sz), nil } -// // ID returns a fingerprint of the avatar content. Uses MD5 because gridfs provides it directly func (gf *GridFS) ID(avatar string) (id string) { @@ -143,7 +142,7 @@ func (gf *GridFS) List() (ids []string, err error) { return ids, nil } -// Close gridfs does nothing but satisfies interface +// Close gridfs store func (gf *GridFS) Close() error { ctx, cancel := context.WithTimeout(context.Background(), gf.timeout) defer cancel() diff --git a/backend/vendor/github.com/go-pkgz/auth/avatar/localfs.go b/backend/vendor/github.com/go-pkgz/auth/avatar/localfs.go index 8e3bf651..f387d2f7 100644 --- a/backend/vendor/github.com/go-pkgz/auth/avatar/localfs.go +++ b/backend/vendor/github.com/go-pkgz/auth/avatar/localfs.go @@ -104,7 +104,7 @@ func (fs *LocalFS) List() (ids []string, err error) { return ids, nil } -// Close gridfs does nothing but satisfies interface +// Close LocalFS does nothing but satisfies interface func (fs *LocalFS) Close() error { return nil } diff --git a/backend/vendor/github.com/go-pkgz/auth/provider/custom_server.go b/backend/vendor/github.com/go-pkgz/auth/provider/custom_server.go index f5bde31c..d3a48d99 100644 --- a/backend/vendor/github.com/go-pkgz/auth/provider/custom_server.go +++ b/backend/vendor/github.com/go-pkgz/auth/provider/custom_server.go @@ -88,7 +88,8 @@ func (c *CustomServer) Run(ctx context.Context) { } c.httpServer = &http.Server{ - Addr: fmt.Sprintf(":%s", port), + Addr: fmt.Sprintf(":%s", port), + ReadHeaderTimeout: 5 * time.Second, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case strings.HasSuffix(r.URL.Path, "/authorize"): diff --git a/backend/vendor/github.com/go-pkgz/auth/provider/dev_provider.go b/backend/vendor/github.com/go-pkgz/auth/provider/dev_provider.go index d9e654f8..b225e20a 100644 --- a/backend/vendor/github.com/go-pkgz/auth/provider/dev_provider.go +++ b/backend/vendor/github.com/go-pkgz/auth/provider/dev_provider.go @@ -57,7 +57,8 @@ func (d *DevAuthServer) Run(ctx context.Context) { // nolint (gocyclo) } d.httpServer = &http.Server{ - Addr: fmt.Sprintf(":%d", d.Provider.Port), + Addr: fmt.Sprintf(":%d", d.Provider.Port), + ReadHeaderTimeout: 5 * time.Second, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d.Logf("[DEBUG] dev oauth request %s %s %+v", r.Method, r.URL, r.Header) switch { diff --git a/backend/vendor/github.com/go-pkgz/email/email.go b/backend/vendor/github.com/go-pkgz/email/email.go index beb9525d..033eb51d 100644 --- a/backend/vendor/github.com/go-pkgz/email/email.go +++ b/backend/vendor/github.com/go-pkgz/email/email.go @@ -177,7 +177,7 @@ func (em *Sender) client() (c *smtp.Client, err error) { } if em.tls { - conn, e := tls.Dial("tcp", srvAddress, tlsConf) + conn, e := tls.DialWithDialer(&net.Dialer{Timeout: em.timeOut}, "tcp", srvAddress, tlsConf) if e != nil { return nil, fmt.Errorf("failed to dial smtp tls to %s: %w", srvAddress, e) } diff --git a/backend/vendor/github.com/go-pkgz/lcw/.golangci.yml b/backend/vendor/github.com/go-pkgz/lcw/.golangci.yml index 1a78e9cf..b84ca8d7 100644 --- a/backend/vendor/github.com/go-pkgz/lcw/.golangci.yml +++ b/backend/vendor/github.com/go-pkgz/lcw/.golangci.yml @@ -26,18 +26,14 @@ linters: - revive - govet - unconvert - - megacheck - - structcheck - gas - gocyclo - dupl - misspell - unparam - - varcheck - - deadcode + - unused - typecheck - ineffassign - - varcheck - stylecheck - gochecknoinits - exportloopref diff --git a/backend/vendor/github.com/go-pkgz/lcw/README.md b/backend/vendor/github.com/go-pkgz/lcw/README.md index 8032b2d6..6a553a10 100644 --- a/backend/vendor/github.com/go-pkgz/lcw/README.md +++ b/backend/vendor/github.com/go-pkgz/lcw/README.md @@ -30,22 +30,30 @@ Main features: ## Usage ```go -cache, err := lcw.NewLruCache(lcw.MaxKeys(500), lcw.MaxCacheSize(65536), lcw.MaxValSize(200), lcw.MaxKeySize(32)) -if err != nil { - panic("failed to create cache") +package main + +import ( + "github.com/go-pkgz/lcw" +) + +func main() { + cache, err := lcw.NewLruCache(lcw.MaxKeys(500), lcw.MaxCacheSize(65536), lcw.MaxValSize(200), lcw.MaxKeySize(32)) + if err != nil { + panic("failed to create cache") + } + defer cache.Close() + + val, err := cache.Get("key123", func() (interface{}, error) { + res, err := getDataFromSomeSource(params) // returns string + return res, err + }) + + if err != nil { + panic("failed to get data") + } + + s := val.(string) // cached value } -defer cache.Close() - -val, err := cache.Get("key123", func() (lcw.Value, error) { - res, err := getDataFromSomeSource(params) // returns string - return res, err -}) - -if err != nil { - panic("failed to get data") -} - -s := val.(string) // cached value ``` ### Cache with URI @@ -73,7 +81,6 @@ Cache can be created with URIs: that mutable values can be changed outside of cache. `ExampleLoadingCache_Mutability` illustrates that. - All byte-size limits (MaxCacheSize and MaxValSize) only work for values implementing `lcw.Sizer` interface. - Negative limits (max options) rejected -- `lgr.Value` wraps `interface{}` and should be converted back to the concrete type. - The implementation started as a part of [remark42](https://github.com/umputun/remark) and later on moved to [go-pkgz/rest](https://github.com/go-pkgz/rest/tree/master/cache) library and finally generalized to become `lcw`. diff --git a/backend/vendor/github.com/go-pkgz/lcw/cache.go b/backend/vendor/github.com/go-pkgz/lcw/cache.go index 56f9f0a1..3861f0c4 100644 --- a/backend/vendor/github.com/go-pkgz/lcw/cache.go +++ b/backend/vendor/github.com/go-pkgz/lcw/cache.go @@ -6,8 +6,6 @@ // 3 flavors of cache provided - NoP (do-nothing cache), ExpirableCache (TTL based), and LruCache package lcw -//go:generate sh -c "mockery -inpkg -name LoadingCache -print > /tmp/cache-mock.tmp && mv /tmp/cache-mock.tmp cache_mock.go" - import ( "fmt" ) diff --git a/backend/vendor/github.com/go-pkgz/lcw/internal/cache/cache.go b/backend/vendor/github.com/go-pkgz/lcw/internal/cache/cache.go index e9a54535..b1d386e3 100644 --- a/backend/vendor/github.com/go-pkgz/lcw/internal/cache/cache.go +++ b/backend/vendor/github.com/go-pkgz/lcw/internal/cache/cache.go @@ -185,6 +185,12 @@ func (c *LoadingCache) ItemCount() int { func (c *LoadingCache) Close() { c.mu.Lock() defer c.mu.Unlock() + // don't panic in case service is already closed + select { + case <-c.done: + return + default: + } close(c.done) } diff --git a/backend/vendor/github.com/hashicorp/golang-lru/.golangci.yml b/backend/vendor/github.com/hashicorp/golang-lru/.golangci.yml new file mode 100644 index 00000000..49202fc4 --- /dev/null +++ b/backend/vendor/github.com/hashicorp/golang-lru/.golangci.yml @@ -0,0 +1,30 @@ +linters: + enable: + - megacheck + - revive + - govet + - unconvert + - megacheck + - gas + - gocyclo + - dupl + - misspell + - unparam + - unused + - typecheck + - ineffassign + - stylecheck + - exportloopref + - gocritic + - nakedret + - gosimple + - prealloc + fast: false + disable-all: true + +issues: + exclude-rules: + - path: _test\.go + linters: + - dupl + exclude-use-default: false diff --git a/backend/vendor/github.com/hashicorp/golang-lru/2q.go b/backend/vendor/github.com/hashicorp/golang-lru/2q.go index e474cd07..15fcad03 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/2q.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/2q.go @@ -44,7 +44,7 @@ func New2Q(size int) (*TwoQueueCache, error) { // New2QParams creates a new TwoQueueCache using the provided // parameter values. -func New2QParams(size int, recentRatio float64, ghostRatio float64) (*TwoQueueCache, error) { +func New2QParams(size int, recentRatio, ghostRatio float64) (*TwoQueueCache, error) { if size <= 0 { return nil, fmt.Errorf("invalid size") } @@ -138,7 +138,6 @@ func (c *TwoQueueCache) Add(key, value interface{}) { // Add to the recently seen list c.ensureSpace(false) c.recent.Add(key, value) - return } // ensureSpace is used to ensure we have space in the cache diff --git a/backend/vendor/github.com/hashicorp/golang-lru/LICENSE b/backend/vendor/github.com/hashicorp/golang-lru/LICENSE index be2cc4df..0e5d580e 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/LICENSE +++ b/backend/vendor/github.com/hashicorp/golang-lru/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2014 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/backend/vendor/github.com/hashicorp/golang-lru/README.md b/backend/vendor/github.com/hashicorp/golang-lru/README.md index 33e58cfa..063bb160 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/README.md +++ b/backend/vendor/github.com/hashicorp/golang-lru/README.md @@ -7,7 +7,7 @@ thread safe LRU cache. It is based on the cache in Groupcache. Documentation ============= -Full docs are available on [Godoc](http://godoc.org/github.com/hashicorp/golang-lru) +Full docs are available on [Godoc](https://pkg.go.dev/github.com/hashicorp/golang-lru) Example ======= diff --git a/backend/vendor/github.com/hashicorp/golang-lru/arc.go b/backend/vendor/github.com/hashicorp/golang-lru/arc.go index 555225a2..e396f842 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/arc.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/arc.go @@ -173,7 +173,6 @@ func (c *ARCCache) Add(key, value interface{}) { // Add to the recently seen list c.t1.Add(key, value) - return } // replace is used to adaptively evict from either T1 or T2 diff --git a/backend/vendor/github.com/hashicorp/golang-lru/lru.go b/backend/vendor/github.com/hashicorp/golang-lru/lru.go index 4e5e9d8f..895d8e3e 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/lru.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/lru.go @@ -6,10 +6,17 @@ import ( "github.com/hashicorp/golang-lru/simplelru" ) +const ( + // DefaultEvictedBufferSize defines the default buffer size to store evicted key/val + DefaultEvictedBufferSize = 16 +) + // Cache is a thread-safe fixed size LRU cache. type Cache struct { - lru simplelru.LRUCache - lock sync.RWMutex + lru *simplelru.LRU + evictedKeys, evictedVals []interface{} + onEvictedCB func(k, v interface{}) + lock sync.RWMutex } // New creates an LRU of the given size. @@ -19,30 +26,63 @@ func New(size int) (*Cache, error) { // NewWithEvict constructs a fixed size cache with the given eviction // callback. -func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) { - lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted)) - if err != nil { - return nil, err +func NewWithEvict(size int, onEvicted func(key, value interface{})) (c *Cache, err error) { + // create a cache with default settings + c = &Cache{ + onEvictedCB: onEvicted, } - c := &Cache{ - lru: lru, + if onEvicted != nil { + c.initEvictBuffers() + onEvicted = c.onEvicted } - return c, nil + c.lru, err = simplelru.NewLRU(size, onEvicted) + return +} + +func (c *Cache) initEvictBuffers() { + c.evictedKeys = make([]interface{}, 0, DefaultEvictedBufferSize) + c.evictedVals = make([]interface{}, 0, DefaultEvictedBufferSize) +} + +// onEvicted save evicted key/val and sent in externally registered callback +// outside of critical section +func (c *Cache) onEvicted(k, v interface{}) { + c.evictedKeys = append(c.evictedKeys, k) + c.evictedVals = append(c.evictedVals, v) } // Purge is used to completely clear the cache. func (c *Cache) Purge() { + var ks, vs []interface{} c.lock.Lock() c.lru.Purge() + if c.onEvictedCB != nil && len(c.evictedKeys) > 0 { + ks, vs = c.evictedKeys, c.evictedVals + c.initEvictBuffers() + } c.lock.Unlock() + // invoke callback outside of critical section + if c.onEvictedCB != nil { + for i := 0; i < len(ks); i++ { + c.onEvictedCB(ks[i], vs[i]) + } + } } // Add adds a value to the cache. Returns true if an eviction occurred. func (c *Cache) Add(key, value interface{}) (evicted bool) { + var k, v interface{} c.lock.Lock() evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } c.lock.Unlock() - return evicted + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } + return } // Get looks up a key's value from the cache. @@ -75,13 +115,21 @@ func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) { // recent-ness or deleting it for being stale, and if not, adds the value. // Returns whether found and whether an eviction occurred. func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { + var k, v interface{} c.lock.Lock() - defer c.lock.Unlock() - if c.lru.Contains(key) { + c.lock.Unlock() return true, false } evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } return false, evicted } @@ -89,47 +137,80 @@ func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) { // recent-ness or deleting it for being stale, and if not, adds the value. // Returns whether found and whether an eviction occurred. func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) { + var k, v interface{} c.lock.Lock() - defer c.lock.Unlock() - previous, ok = c.lru.Peek(key) if ok { + c.lock.Unlock() return previous, true, false } - evicted = c.lru.Add(key, value) + if c.onEvictedCB != nil && evicted { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } + c.lock.Unlock() + if c.onEvictedCB != nil && evicted { + c.onEvictedCB(k, v) + } return nil, false, evicted } // Remove removes the provided key from the cache. func (c *Cache) Remove(key interface{}) (present bool) { + var k, v interface{} c.lock.Lock() present = c.lru.Remove(key) + if c.onEvictedCB != nil && present { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } c.lock.Unlock() + if c.onEvictedCB != nil && present { + c.onEvictedCB(k, v) + } return } // Resize changes the cache size. func (c *Cache) Resize(size int) (evicted int) { + var ks, vs []interface{} c.lock.Lock() evicted = c.lru.Resize(size) + if c.onEvictedCB != nil && evicted > 0 { + ks, vs = c.evictedKeys, c.evictedVals + c.initEvictBuffers() + } c.lock.Unlock() + if c.onEvictedCB != nil && evicted > 0 { + for i := 0; i < len(ks); i++ { + c.onEvictedCB(ks[i], vs[i]) + } + } return evicted } // RemoveOldest removes the oldest item from the cache. -func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) { +func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) { + var k, v interface{} c.lock.Lock() key, value, ok = c.lru.RemoveOldest() + if c.onEvictedCB != nil && ok { + k, v = c.evictedKeys[0], c.evictedVals[0] + c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0] + } c.lock.Unlock() + if c.onEvictedCB != nil && ok { + c.onEvictedCB(k, v) + } return } // GetOldest returns the oldest entry -func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) { - c.lock.Lock() +func (c *Cache) GetOldest() (key, value interface{}, ok bool) { + c.lock.RLock() key, value, ok = c.lru.GetOldest() - c.lock.Unlock() + c.lock.RUnlock() return } diff --git a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go index a86c8539..9233583c 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go @@ -25,7 +25,7 @@ type entry struct { // NewLRU constructs an LRU of the given size func NewLRU(size int, onEvict EvictCallback) (*LRU, error) { if size <= 0 { - return nil, errors.New("Must provide a positive size") + return nil, errors.New("must provide a positive size") } c := &LRU{ size: size, @@ -109,7 +109,7 @@ func (c *LRU) Remove(key interface{}) (present bool) { } // RemoveOldest removes the oldest item from the cache. -func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { +func (c *LRU) RemoveOldest() (key, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { c.removeElement(ent) @@ -120,7 +120,7 @@ func (c *LRU) RemoveOldest() (key interface{}, value interface{}, ok bool) { } // GetOldest returns the oldest entry -func (c *LRU) GetOldest() (key interface{}, value interface{}, ok bool) { +func (c *LRU) GetOldest() (key, value interface{}, ok bool) { ent := c.evictList.Back() if ent != nil { kv := ent.Value.(*entry) diff --git a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go index 92d70934..cb7f8caf 100644 --- a/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ b/backend/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go @@ -1,3 +1,4 @@ +// Package simplelru provides simple LRU implementation based on build-in container/list. package simplelru // LRUCache is the interface for simple LRU cache. @@ -34,6 +35,6 @@ type LRUCache interface { // Clears all cache entries. Purge() - // Resizes cache, returning number evicted - Resize(int) int + // Resizes cache, returning number evicted + Resize(int) int } diff --git a/backend/vendor/github.com/hashicorp/golang-lru/testing.go b/backend/vendor/github.com/hashicorp/golang-lru/testing.go new file mode 100644 index 00000000..49276078 --- /dev/null +++ b/backend/vendor/github.com/hashicorp/golang-lru/testing.go @@ -0,0 +1,16 @@ +package lru + +import ( + "crypto/rand" + "math" + "math/big" + "testing" +) + +func getRand(tb testing.TB) int64 { + out, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) + if err != nil { + tb.Fatal(err) + } + return out.Int64() +} diff --git a/backend/vendor/modules.txt b/backend/vendor/modules.txt index db0614a8..0e757ebd 100644 --- a/backend/vendor/modules.txt +++ b/backend/vendor/modules.txt @@ -65,7 +65,7 @@ github.com/go-chi/render github.com/go-oauth2/oauth2/v4 github.com/go-oauth2/oauth2/v4/errors github.com/go-oauth2/oauth2/v4/server -# github.com/go-pkgz/auth v1.20.0 +# github.com/go-pkgz/auth v1.20.1-0.20221226231300-65f433fba0f1 ## explicit; go 1.17 github.com/go-pkgz/auth github.com/go-pkgz/auth/avatar @@ -74,8 +74,8 @@ github.com/go-pkgz/auth/middleware github.com/go-pkgz/auth/provider github.com/go-pkgz/auth/provider/sender github.com/go-pkgz/auth/token -# github.com/go-pkgz/email v0.4.0 -## explicit; go 1.17 +# github.com/go-pkgz/email v0.4.1 +## explicit; go 1.19 github.com/go-pkgz/email # github.com/go-pkgz/expirable-cache v0.1.0 ## explicit; go 1.14 @@ -83,7 +83,7 @@ github.com/go-pkgz/expirable-cache # github.com/go-pkgz/jrpc v0.3.0 ## explicit; go 1.16 github.com/go-pkgz/jrpc -# github.com/go-pkgz/lcw v1.0.1 +# github.com/go-pkgz/lcw v1.0.3-0.20221226231215-a66ea7c4aff7 ## explicit; go 1.15 github.com/go-pkgz/lcw github.com/go-pkgz/lcw/eventbus @@ -143,7 +143,7 @@ github.com/hashicorp/errwrap # github.com/hashicorp/go-multierror v1.1.1 ## explicit; go 1.13 github.com/hashicorp/go-multierror -# github.com/hashicorp/golang-lru v0.5.4 +# github.com/hashicorp/golang-lru v0.6.0 ## explicit; go 1.12 github.com/hashicorp/golang-lru github.com/hashicorp/golang-lru/simplelru @@ -196,7 +196,7 @@ github.com/slack-go/slack/internal/backoff github.com/slack-go/slack/internal/errorsx github.com/slack-go/slack/internal/timex github.com/slack-go/slack/slackutilsx -# github.com/stretchr/testify v1.8.0 +# github.com/stretchr/testify v1.8.1 ## explicit; go 1.13 github.com/stretchr/testify/assert github.com/stretchr/testify/require