From ec55edfbc411b8fce417da774feb86ce458a91aa Mon Sep 17 00:00:00 2001 From: Phillip Stagnet Date: Thu, 6 Aug 2020 11:14:36 +0200 Subject: [PATCH 1/5] Add additional options to redis session prov Adding option for frequency of checking timed out connections as well as an option to specify retries. These changes make redis provider more stable since connection problems are becoming fewer. Since redigo does not have this options and since redis_sentinel and redis_cluster are using go-redis as a client, this commit changes from redigo to go-redis for redis session provider. Added tests for redis session provider as well. --- go.mod | 4 +- go.sum | 50 +++-------- pkg/session/redis/sess_redis.go | 89 +++++++++---------- pkg/session/redis/sess_redis_test.go | 88 ++++++++++++++++++ pkg/session/redis_cluster/redis_cluster.go | 26 +++++- .../redis_sentinel/sess_redis_sentinel.go | 26 +++++- 6 files changed, 189 insertions(+), 94 deletions(-) create mode 100644 pkg/session/redis/sess_redis_test.go diff --git a/go.mod b/go.mod index a6c27488..1951d76d 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,8 @@ require ( github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a // indirect github.com/elastic/go-elasticsearch/v6 v6.8.5 github.com/elazarl/go-bindata-assetfs v1.0.0 - github.com/go-kit/kit v0.9.0 github.com/go-redis/redis v6.14.2+incompatible + github.com/go-redis/redis/v7 v7.4.0 github.com/go-sql-driver/mysql v1.5.0 github.com/gogo/protobuf v1.1.1 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect @@ -31,8 +31,6 @@ require ( github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c // indirect github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b // indirect golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 - golang.org/x/net v0.0.0-20190620200207-3b0461eec859 // indirect - google.golang.org/grpc v1.31.0 // indirect gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index 12b76333..6c1bfe10 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg= @@ -21,13 +20,10 @@ github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVx github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ= github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d h1:OMrhQqj1QCyDT2sxHCDjE+k8aMdn2ngTCGG7g4wrdLo= github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808 h1:8s2l8TVUwMXl6tZMe3+hPCRJ25nQXiA3d1x622JtOqc= @@ -45,9 +41,6 @@ github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+ github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw= @@ -59,6 +52,8 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiNaInPgym8nzfg0= github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v7 v7.4.0 h1:7obg6wUoj05T0EpY0o8B59S9w5yeMWql7sw2kwNW1x4= +github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -67,12 +62,9 @@ github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d h1:xy93KVe+KrIIwWDEAf github.com/go-yaml/yaml v0.0.0-20180328195020-5420a8b6744d/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -85,7 +77,6 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pO github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= @@ -121,8 +112,10 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -143,7 +136,6 @@ github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -181,55 +173,35 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -252,5 +224,3 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/session/redis/sess_redis.go b/pkg/session/redis/sess_redis.go index cf2dddf4..7e991ef5 100644 --- a/pkg/session/redis/sess_redis.go +++ b/pkg/session/redis/sess_redis.go @@ -41,7 +41,7 @@ import ( "github.com/astaxie/beego/pkg/session" - "github.com/gomodule/redigo/redis" + "github.com/go-redis/redis/v7" ) var redispder = &Provider{} @@ -51,7 +51,7 @@ var MaxPoolSize = 100 // SessionStore redis session store type SessionStore struct { - p *redis.Pool + p *redis.Client sid string lock sync.RWMutex values map[interface{}]interface{} @@ -103,9 +103,8 @@ func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { if err != nil { return } - c := rs.p.Get() - defer c.Close() - c.Do("SETEX", rs.sid, rs.maxlifetime, string(b)) + c := rs.p + c.Set(rs.sid, string(b), time.Duration(rs.maxlifetime)*time.Second) } // Provider redis session provider @@ -115,7 +114,7 @@ type Provider struct { poolsize int password string dbNum int - poollist *redis.Pool + poollist *redis.Client } // SessionInit init redis session @@ -157,45 +156,40 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { idleTimeout = time.Duration(timeout) * time.Second } } - rp.poollist = &redis.Pool{ - Dial: func() (redis.Conn, error) { - c, err := redis.Dial("tcp", rp.savePath) - if err != nil { - return nil, err - } - if rp.password != "" { - if _, err = c.Do("AUTH", rp.password); err != nil { - c.Close() - return nil, err - } - } - // some redis proxy such as twemproxy is not support select command - if rp.dbNum > 0 { - _, err = c.Do("SELECT", rp.dbNum) - if err != nil { - c.Close() - return nil, err - } - } - return c, err - }, - MaxIdle: rp.poolsize, + var idleCheckFrequency time.Duration = 0 + if len(configs) > 5 { + checkFrequency, err := strconv.Atoi(configs[5]) + if err == nil && checkFrequency > 0 { + idleCheckFrequency = time.Duration(checkFrequency) * time.Second + } + } + var maxRetries = 0 + if len(configs) > 6 { + retries, err := strconv.Atoi(configs[6]) + if err == nil && retries > 0 { + maxRetries = retries + } } - rp.poollist.IdleTimeout = idleTimeout + rp.poollist = redis.NewClient(&redis.Options{ + Addr: rp.savePath, + Password: rp.password, + PoolSize: rp.poolsize, + DB: rp.dbNum, + IdleTimeout: idleTimeout, + IdleCheckFrequency: idleCheckFrequency, + MaxRetries: maxRetries, + }) - return rp.poollist.Get().Err() + return rp.poollist.Ping().Err() } // SessionRead read redis session by sid func (rp *Provider) SessionRead(sid string) (session.Store, error) { - c := rp.poollist.Get() - defer c.Close() - var kv map[interface{}]interface{} - kvs, err := redis.String(c.Do("GET", sid)) - if err != nil && err != redis.ErrNil { + kvs, err := rp.poollist.Get(sid).Result() + if err != nil && err != redis.Nil { return nil, err } if len(kvs) == 0 { @@ -212,10 +206,9 @@ func (rp *Provider) SessionRead(sid string) (session.Store, error) { // SessionExist check redis session exist by sid func (rp *Provider) SessionExist(sid string) (bool, error) { - c := rp.poollist.Get() - defer c.Close() + c := rp.poollist - if existed, err := redis.Int(c.Do("EXISTS", sid)); err != nil || existed == 0 { + if existed, err := c.Exists(sid).Result(); err != nil || existed == 0 { return false, err } return true, nil @@ -223,27 +216,24 @@ func (rp *Provider) SessionExist(sid string) (bool, error) { // SessionRegenerate generate new sid for redis session func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) { - c := rp.poollist.Get() - defer c.Close() - - if existed, _ := redis.Int(c.Do("EXISTS", oldsid)); existed == 0 { + c := rp.poollist + if existed, _ := c.Exists(oldsid).Result(); existed == 0 { // oldsid doesn't exists, set the new sid directly // ignore error here, since if it return error // the existed value will be 0 - c.Do("SET", sid, "", "EX", rp.maxlifetime) + c.Do(c.Context(), "SET", sid, "", "EX", rp.maxlifetime) } else { - c.Do("RENAME", oldsid, sid) - c.Do("EXPIRE", sid, rp.maxlifetime) + c.Rename(oldsid, sid) + c.Expire(sid, time.Duration(rp.maxlifetime)) } return rp.SessionRead(sid) } // SessionDestroy delete redis session by id func (rp *Provider) SessionDestroy(sid string) error { - c := rp.poollist.Get() - defer c.Close() + c := rp.poollist - c.Do("DEL", sid) + c.Del(sid) return nil } @@ -259,3 +249,4 @@ func (rp *Provider) SessionAll() int { func init() { session.Register("redis", redispder) } + diff --git a/pkg/session/redis/sess_redis_test.go b/pkg/session/redis/sess_redis_test.go new file mode 100644 index 00000000..db5bb2c7 --- /dev/null +++ b/pkg/session/redis/sess_redis_test.go @@ -0,0 +1,88 @@ +package redis + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/astaxie/beego/pkg/session" +) + +func TestRedis(t *testing.T) { + sessionConfig := &session.ManagerConfig{ + CookieName: "gosessionid", + EnableSetCookie: true, + Gclifetime: 3600, + Maxlifetime: 3600, + Secure: false, + CookieLifeTime: 3600, + ProviderConfig: "127.0.0.1:6379,100,,0,30", + } + globalSession, err := session.NewManager("redis", sessionConfig) + if err != nil { + t.Fatal("could not create manager:", err) + } + + go globalSession.GC() + + r, _ := http.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + + sess, err := globalSession.SessionStart(w, r) + if err != nil { + t.Fatal("session start failed:", err) + } + defer sess.SessionRelease(w) + + // SET AND GET + err = sess.Set("username", "astaxie") + if err != nil { + t.Fatal("set username failed:", err) + } + username := sess.Get("username") + if username != "astaxie" { + t.Fatal("get username failed") + } + + // DELETE + err = sess.Delete("username") + if err != nil { + t.Fatal("delete username failed:", err) + } + username = sess.Get("username") + if username != nil { + t.Fatal("delete username failed") + } + + // FLUSH + err = sess.Set("username", "astaxie") + if err != nil { + t.Fatal("set failed:", err) + } + err = sess.Set("password", "1qaz2wsx") + if err != nil { + t.Fatal("set failed:", err) + } + username = sess.Get("username") + if username != "astaxie" { + t.Fatal("get username failed") + } + password := sess.Get("password") + if password != "1qaz2wsx" { + t.Fatal("get password failed") + } + err = sess.Flush() + if err != nil { + t.Fatal("flush failed:", err) + } + username = sess.Get("username") + if username != nil { + t.Fatal("flush failed") + } + password = sess.Get("password") + if password != nil { + t.Fatal("flush failed") + } + + sess.SessionRelease(w) +} diff --git a/pkg/session/redis_cluster/redis_cluster.go b/pkg/session/redis_cluster/redis_cluster.go index 8b20ab19..75dc0e63 100644 --- a/pkg/session/redis_cluster/redis_cluster.go +++ b/pkg/session/redis_cluster/redis_cluster.go @@ -34,7 +34,7 @@ package redis_cluster import ( "github.com/astaxie/beego/pkg/session" - rediss "github.com/go-redis/redis" + rediss "github.com/go-redis/redis/v7" "net/http" "strconv" "strings" @@ -147,11 +147,35 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { } else { rp.dbNum = 0 } + var idleTimeout time.Duration = 0 + if len(configs) > 4 { + timeout, err := strconv.Atoi(configs[4]) + if err == nil && timeout > 0 { + idleTimeout = time.Duration(timeout) * time.Second + } + } + var idleCheckFrequency time.Duration = 0 + if len(configs) > 5 { + checkFrequency, err := strconv.Atoi(configs[5]) + if err == nil && checkFrequency > 0 { + idleCheckFrequency = time.Duration(checkFrequency) * time.Second + } + } + var maxRetries = 0 + if len(configs) > 6 { + retries, err := strconv.Atoi(configs[6]) + if err == nil && retries > 0 { + maxRetries = retries + } + } rp.poollist = rediss.NewClusterClient(&rediss.ClusterOptions{ Addrs: strings.Split(rp.savePath, ";"), Password: rp.password, PoolSize: rp.poolsize, + IdleTimeout: idleTimeout, + IdleCheckFrequency: idleCheckFrequency, + MaxRetries: maxRetries, }) return rp.poollist.Ping().Err() } diff --git a/pkg/session/redis_sentinel/sess_redis_sentinel.go b/pkg/session/redis_sentinel/sess_redis_sentinel.go index f78486be..da287b8d 100644 --- a/pkg/session/redis_sentinel/sess_redis_sentinel.go +++ b/pkg/session/redis_sentinel/sess_redis_sentinel.go @@ -34,7 +34,7 @@ package redis_sentinel import ( "github.com/astaxie/beego/pkg/session" - "github.com/go-redis/redis" + "github.com/go-redis/redis/v7" "net/http" "strconv" "strings" @@ -157,6 +157,27 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { } else { rp.masterName = "mymaster" } + var idleTimeout time.Duration = 0 + if len(configs) > 5 { + timeout, err := strconv.Atoi(configs[4]) + if err == nil && timeout > 0 { + idleTimeout = time.Duration(timeout) * time.Second + } + } + var idleCheckFrequency time.Duration = 0 + if len(configs) > 6 { + checkFrequency, err := strconv.Atoi(configs[5]) + if err == nil && checkFrequency > 0 { + idleCheckFrequency = time.Duration(checkFrequency) * time.Second + } + } + var maxRetries = 0 + if len(configs) > 7 { + retries, err := strconv.Atoi(configs[6]) + if err == nil && retries > 0 { + maxRetries = retries + } + } rp.poollist = redis.NewFailoverClient(&redis.FailoverOptions{ SentinelAddrs: strings.Split(rp.savePath, ";"), @@ -164,6 +185,9 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { PoolSize: rp.poolsize, DB: rp.dbNum, MasterName: rp.masterName, + IdleTimeout: idleTimeout, + IdleCheckFrequency: idleCheckFrequency, + MaxRetries: maxRetries, }) return rp.poollist.Ping().Err() From c22af4c61199ed1e6c664fbf3ff9919201d2c6fa Mon Sep 17 00:00:00 2001 From: Ming Deng Date: Mon, 10 Aug 2020 23:04:57 +0800 Subject: [PATCH 2/5] Fix Tracing and prometheus bug --- build_info.go | 8 +- config.go | 4 +- config/config.go | 6 +- config/fake.go | 16 +++ context/output.go | 1 - go.sum | 4 + pkg/admin_test.go | 18 +++- pkg/app.go | 1 + pkg/filter.go | 3 + pkg/filter_chain_test.go | 3 +- pkg/hooks.go | 2 +- pkg/httplib/filter.go | 2 +- pkg/httplib/filter/opentracing/filter.go | 40 ++++---- pkg/httplib/filter/opentracing/filter_test.go | 2 +- pkg/httplib/filter/prometheus/filter.go | 8 +- pkg/httplib/filter/prometheus/filter_test.go | 2 +- pkg/orm/db_alias.go | 3 +- pkg/orm/db_alias_test.go | 1 - pkg/orm/db_hints_test.go | 2 +- pkg/orm/do_nothing_orm.go | 11 ++- ...ing_omr_test.go => do_nothing_orm_test.go} | 2 +- pkg/orm/filter.go | 10 +- pkg/orm/filter/opentracing/filter.go | 38 ++++--- pkg/orm/filter/opentracing/filter_test.go | 4 +- pkg/orm/filter/prometheus/filter.go | 2 +- pkg/orm/filter/prometheus/filter_test.go | 2 +- pkg/orm/filter_orm_decorator.go | 98 ++++++++++--------- pkg/orm/filter_orm_decorator_test.go | 50 +++++----- pkg/orm/filter_test.go | 3 +- pkg/orm/invocation.go | 19 ++-- pkg/orm/model_utils_test.go | 2 +- pkg/orm/models_test.go | 1 - pkg/orm/orm.go | 38 +++---- pkg/orm/orm_test.go | 2 - pkg/orm/types.go | 8 +- pkg/router.go | 5 +- pkg/session/sess_file_test.go | 2 +- pkg/web/doc.go | 2 +- pkg/web/filter/opentracing/filter.go | 23 +++-- pkg/web/filter/opentracing/filter_test.go | 2 +- pkg/web/filter/prometheus/filter.go | 2 +- pkg/web/filter/prometheus/filter_test.go | 2 +- 42 files changed, 257 insertions(+), 197 deletions(-) rename pkg/orm/{do_nothing_omr_test.go => do_nothing_orm_test.go} (99%) diff --git a/build_info.go b/build_info.go index 896bbdf3..59e78127 100644 --- a/build_info.go +++ b/build_info.go @@ -16,15 +16,15 @@ package beego var ( // Deprecated: using pkg/, we will delete this in v2.1.0 - BuildVersion string + BuildVersion string // Deprecated: using pkg/, we will delete this in v2.1.0 BuildGitRevision string // Deprecated: using pkg/, we will delete this in v2.1.0 - BuildStatus string + BuildStatus string // Deprecated: using pkg/, we will delete this in v2.1.0 - BuildTag string + BuildTag string // Deprecated: using pkg/, we will delete this in v2.1.0 - BuildTime string + BuildTime string // Deprecated: using pkg/, we will delete this in v2.1.0 GoVersion string diff --git a/config.go b/config.go index d707542a..7917528e 100644 --- a/config.go +++ b/config.go @@ -15,13 +15,13 @@ package beego import ( + "crypto/tls" "fmt" "os" "path/filepath" "reflect" "runtime" "strings" - "crypto/tls" "github.com/astaxie/beego/config" "github.com/astaxie/beego/context" @@ -163,7 +163,7 @@ func init() { } appConfigPath = filepath.Join(WorkPath, "conf", filename) if configPath := os.Getenv("BEEGO_CONFIG_PATH"); configPath != "" { - appConfigPath = configPath + appConfigPath = configPath } if !utils.FileExists(appConfigPath) { appConfigPath = filepath.Join(AppPath, "conf", filename) diff --git a/config/config.go b/config/config.go index f46f862b..db2e96f6 100644 --- a/config/config.go +++ b/config/config.go @@ -51,9 +51,9 @@ import ( // Deprecated: using pkg/config, we will delete this in v2.1.0 type Configer interface { // Deprecated: using pkg/config, we will delete this in v2.1.0 - Set(key, val string) error //support section::key type in given key when using ini type. + Set(key, val string) error //support section::key type in given key when using ini type. // Deprecated: using pkg/config, we will delete this in v2.1.0 - String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. + String(key string) string //support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. // Deprecated: using pkg/config, we will delete this in v2.1.0 Strings(key string) []string //get string slice // Deprecated: using pkg/config, we will delete this in v2.1.0 @@ -65,7 +65,7 @@ type Configer interface { // Deprecated: using pkg/config, we will delete this in v2.1.0 Float(key string) (float64, error) // Deprecated: using pkg/config, we will delete this in v2.1.0 - DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. + DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same. // Deprecated: using pkg/config, we will delete this in v2.1.0 DefaultStrings(key string, defaultVal []string) []string //get string slice // Deprecated: using pkg/config, we will delete this in v2.1.0 diff --git a/config/fake.go b/config/fake.go index 07e56ce2..8093ad61 100644 --- a/config/fake.go +++ b/config/fake.go @@ -27,15 +27,18 @@ type fakeConfigContainer struct { func (c *fakeConfigContainer) getData(key string) string { return c.data[strings.ToLower(key)] } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Set(key, val string) error { c.data[strings.ToLower(key)] = val return nil } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) String(key string) string { return c.getData(key) } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultString(key string, defaultval string) string { v := c.String(key) @@ -44,6 +47,7 @@ func (c *fakeConfigContainer) DefaultString(key string, defaultval string) strin } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Strings(key string) []string { v := c.String(key) @@ -52,6 +56,7 @@ func (c *fakeConfigContainer) Strings(key string) []string { } return strings.Split(v, ";") } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) []string { v := c.Strings(key) @@ -60,10 +65,12 @@ func (c *fakeConfigContainer) DefaultStrings(key string, defaultval []string) [] } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Int(key string) (int, error) { return strconv.Atoi(c.getData(key)) } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int { v, err := c.Int(key) @@ -72,10 +79,12 @@ func (c *fakeConfigContainer) DefaultInt(key string, defaultval int) int { } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Int64(key string) (int64, error) { return strconv.ParseInt(c.getData(key), 10, 64) } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 { v, err := c.Int64(key) @@ -84,10 +93,12 @@ func (c *fakeConfigContainer) DefaultInt64(key string, defaultval int64) int64 { } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Bool(key string) (bool, error) { return ParseBool(c.getData(key)) } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool { v, err := c.Bool(key) @@ -96,10 +107,12 @@ func (c *fakeConfigContainer) DefaultBool(key string, defaultval bool) bool { } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) Float(key string) (float64, error) { return strconv.ParseFloat(c.getData(key), 64) } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float64 { v, err := c.Float(key) @@ -108,6 +121,7 @@ func (c *fakeConfigContainer) DefaultFloat(key string, defaultval float64) float } return v } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) DIY(key string) (interface{}, error) { if v, ok := c.data[strings.ToLower(key)]; ok { @@ -115,10 +129,12 @@ func (c *fakeConfigContainer) DIY(key string) (interface{}, error) { } return nil, errors.New("key not find") } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) GetSection(section string) (map[string]string, error) { return nil, errors.New("not implement in the fakeConfigContainer") } + // Deprecated: using pkg/config, we will delete this in v2.1.0 func (c *fakeConfigContainer) SaveConfigFile(filename string) error { return errors.New("not implement in the fakeConfigContainer") diff --git a/context/output.go b/context/output.go index eaa75720..7409e4e5 100644 --- a/context/output.go +++ b/context/output.go @@ -58,7 +58,6 @@ func (output *BeegoOutput) Clear() { output.Status = 0 } - // Header sets response header item string via given key. func (output *BeegoOutput) Header(key, val string) { output.Context.ResponseWriter.Header().Set(key, val) diff --git a/go.sum b/go.sum index 12b76333..75247943 100644 --- a/go.sum +++ b/go.sum @@ -185,6 +185,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -219,6 +220,9 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20200117065230-39095c1d176c h1:FodBYPZKH5tAN2O60HlglMwXGAeV/4k+NKbli79M/2c= +golang.org/x/tools v0.0.0-20200117065230-39095c1d176c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/pkg/admin_test.go b/pkg/admin_test.go index e7eae771..5094aeed 100644 --- a/pkg/admin_test.go +++ b/pkg/admin_test.go @@ -6,10 +6,11 @@ import ( "fmt" "net/http" "net/http/httptest" - "reflect" "strings" "testing" + "github.com/stretchr/testify/assert" + "github.com/astaxie/beego/pkg/toolbox" ) @@ -230,10 +231,19 @@ func TestHealthCheckHandlerReturnsJSON(t *testing.T) { t.Errorf("invalid response map length: got %d want %d", len(decodedResponseBody), len(expectedResponseBody)) } + assert.Equal(t, len(expectedResponseBody), len(decodedResponseBody)) + assert.Equal(t, 2, len(decodedResponseBody)) - if !reflect.DeepEqual(decodedResponseBody, expectedResponseBody) { - t.Errorf("handler returned unexpected body: got %v want %v", - decodedResponseBody, expectedResponseBody) + var database, cache map[string]interface{} + if decodedResponseBody[0]["message"] == "database" { + database = decodedResponseBody[0] + cache = decodedResponseBody[1] + } else { + database = decodedResponseBody[1] + cache = decodedResponseBody[0] } + assert.Equal(t, expectedResponseBody[0], database) + assert.Equal(t, expectedResponseBody[1], cache) + } diff --git a/pkg/app.go b/pkg/app.go index d94d56b5..ea71ce4e 100644 --- a/pkg/app.go +++ b/pkg/app.go @@ -498,6 +498,7 @@ func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *A // InsertFilterChain adds a FilterFunc built by filterChain. // This filter will be executed before all filters. +// the filter's behavior is like stack func InsertFilterChain(pattern string, filterChain FilterChain, params ...bool) *App { BeeApp.Handlers.InsertFilterChain(pattern, filterChain, params...) return BeeApp diff --git a/pkg/filter.go b/pkg/filter.go index 543d7901..911cb848 100644 --- a/pkg/filter.go +++ b/pkg/filter.go @@ -33,6 +33,7 @@ type FilterFunc func(ctx *context.Context) // when a request with a matching URL arrives. type FilterRouter struct { filterFunc FilterFunc + next *FilterRouter tree *Tree pattern string returnOnOutput bool @@ -81,6 +82,8 @@ func (f *FilterRouter) filter(ctx *context.Context, urlPath string, preFilterPar ctx.Input.SetParam(k, v) } } + } else if f.next != nil { + return f.next.filter(ctx, urlPath, preFilterParams) } if f.returnOnOutput && ctx.ResponseWriter.Started { return true, true diff --git a/pkg/filter_chain_test.go b/pkg/filter_chain_test.go index 42397a60..f1f86088 100644 --- a/pkg/filter_chain_test.go +++ b/pkg/filter_chain_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 +// Copyright 2020 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ func TestControllerRegister_InsertFilterChain(t *testing.T) { ctx.Output.Body([]byte("hello")) }) - r, _ := http.NewRequest("GET", "/chain/user", nil) w := httptest.NewRecorder() diff --git a/pkg/hooks.go b/pkg/hooks.go index f511e216..3f778cdc 100644 --- a/pkg/hooks.go +++ b/pkg/hooks.go @@ -111,4 +111,4 @@ func registerCommentRouter() error { } return nil -} \ No newline at end of file +} diff --git a/pkg/httplib/filter.go b/pkg/httplib/filter.go index 72a497d0..5daed64c 100644 --- a/pkg/httplib/filter.go +++ b/pkg/httplib/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/httplib/filter/opentracing/filter.go b/pkg/httplib/filter/opentracing/filter.go index 5f409c63..6cc4d6b0 100644 --- a/pkg/httplib/filter/opentracing/filter.go +++ b/pkg/httplib/filter/opentracing/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,14 +17,11 @@ package opentracing import ( "context" "net/http" - "strconv" + "github.com/astaxie/beego/pkg/httplib" logKit "github.com/go-kit/kit/log" opentracingKit "github.com/go-kit/kit/tracing/opentracing" "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/log" - - "github.com/astaxie/beego/pkg/httplib" ) type FilterChainBuilder struct { @@ -38,14 +35,8 @@ func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filt return func(ctx context.Context, req *httplib.BeegoHTTPRequest) (*http.Response, error) { method := req.GetRequest().Method - host := req.GetRequest().URL.Host - path := req.GetRequest().URL.Path - proto := req.GetRequest().Proto - - scheme := req.GetRequest().URL.Scheme - - operationName := host + path + "#" + method + operationName := method + "#" + req.GetRequest().URL.String() span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName) defer span.Finish() @@ -54,21 +45,24 @@ func (builder *FilterChainBuilder) FilterChain(next httplib.Filter) httplib.Filt resp, err := next(spanCtx, req) if resp != nil { - span.SetTag("status", strconv.Itoa(resp.StatusCode)) + span.SetTag("http.status_code", resp.StatusCode) } - - span.SetTag("method", method) - span.SetTag("host", host) - span.SetTag("path", path) - span.SetTag("proto", proto) - span.SetTag("scheme", scheme) - - span.LogFields(log.String("url", req.GetRequest().URL.String())) - + span.SetTag("http.method", method) + span.SetTag("peer.hostname", req.GetRequest().URL.Host) + span.SetTag("http.url", req.GetRequest().URL.String()) + span.SetTag("http.scheme", req.GetRequest().URL.Scheme) + span.SetTag("span.kind", "client") + span.SetTag("component", "beego") if err != nil { - span.LogFields(log.String("error", err.Error())) + span.SetTag("error", true) + span.SetTag("message", err.Error()) + } else if resp != nil && !(resp.StatusCode < 300 && resp.StatusCode >= 200) { + span.SetTag("error", true) } + span.SetTag("peer.address", req.GetRequest().RemoteAddr) + span.SetTag("http.proto", req.GetRequest().Proto) + if builder.CustomSpanFunc != nil { builder.CustomSpanFunc(span, ctx, req, resp, err) } diff --git a/pkg/httplib/filter/opentracing/filter_test.go b/pkg/httplib/filter/opentracing/filter_test.go index aa687541..8849a9ad 100644 --- a/pkg/httplib/filter/opentracing/filter_test.go +++ b/pkg/httplib/filter/opentracing/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/httplib/filter/prometheus/filter.go b/pkg/httplib/filter/prometheus/filter.go index a0b24d67..e7f7316f 100644 --- a/pkg/httplib/filter/prometheus/filter.go +++ b/pkg/httplib/filter/prometheus/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -63,11 +63,13 @@ func (builder *FilterChainBuilder) report(startTime time.Time, endTime time.Time host := req.GetRequest().URL.Host path := req.GetRequest().URL.Path - status := resp.StatusCode + status := -1 + if resp != nil { + status = resp.StatusCode + } dur := int(endTime.Sub(startTime) / time.Millisecond) - builder.summaryVec.WithLabelValues(proto, scheme, method, host, path, strconv.Itoa(status), strconv.Itoa(dur), strconv.FormatBool(err == nil)) } diff --git a/pkg/httplib/filter/prometheus/filter_test.go b/pkg/httplib/filter/prometheus/filter_test.go index e15d82e5..2964e6c5 100644 --- a/pkg/httplib/filter/prometheus/filter_test.go +++ b/pkg/httplib/filter/prometheus/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/orm/db_alias.go b/pkg/orm/db_alias.go index 5f1e3ea3..e9b39a3d 100644 --- a/pkg/orm/db_alias.go +++ b/pkg/orm/db_alias.go @@ -357,7 +357,7 @@ func addAliasWthDB(aliasName, driverName string, db *sql.DB, params ...common.KV return al, nil } -func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...common.KV)(*alias, error){ +func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...common.KV) (*alias, error) { kvs := common.NewKVs(params...) var stmtCache *lru.Cache @@ -429,7 +429,6 @@ func RegisterDataBase(aliasName, driverName, dataSource string, hints ...common. al *alias ) - db, err = sql.Open(driverName, dataSource) if err != nil { err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) diff --git a/pkg/orm/db_alias_test.go b/pkg/orm/db_alias_test.go index 111657d7..6275cb2a 100644 --- a/pkg/orm/db_alias_test.go +++ b/pkg/orm/db_alias_test.go @@ -75,7 +75,6 @@ func TestRegisterDataBase_MaxStmtCacheSize841(t *testing.T) { assert.Equal(t, al.DB.stmtDecoratorsLimit, 841) } - func TestDBCache(t *testing.T) { dataBaseCache.add("test1", &alias{}) dataBaseCache.add("default", &alias{}) diff --git a/pkg/orm/db_hints_test.go b/pkg/orm/db_hints_test.go index 13f8ccde..bb713171 100644 --- a/pkg/orm/db_hints_test.go +++ b/pkg/orm/db_hints_test.go @@ -73,4 +73,4 @@ func TestMaxStmtCacheSize(t *testing.T) { hint := MaxStmtCacheSize(i) assert.Equal(t, hint.GetValue(), i) assert.Equal(t, hint.GetKey(), maxStmtCacheSizeKey) -} \ No newline at end of file +} diff --git a/pkg/orm/do_nothing_orm.go b/pkg/orm/do_nothing_orm.go index 87b0a2ae..f460794c 100644 --- a/pkg/orm/do_nothing_orm.go +++ b/pkg/orm/do_nothing_orm.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import ( var _ Ormer = new(DoNothingOrm) type DoNothingOrm struct { + } func (d *DoNothingOrm) Read(md interface{}, cols ...string) error { @@ -148,19 +149,19 @@ func (d *DoNothingOrm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOpti return nil, nil } -func (d *DoNothingOrm) DoTx(task func(txOrm TxOrmer) error) error { +func (d *DoNothingOrm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error { return nil } -func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error { +func (d *DoNothingOrm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error { return nil } -func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (d *DoNothingOrm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { return nil } -func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (d *DoNothingOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { return nil } diff --git a/pkg/orm/do_nothing_omr_test.go b/pkg/orm/do_nothing_orm_test.go similarity index 99% rename from pkg/orm/do_nothing_omr_test.go rename to pkg/orm/do_nothing_orm_test.go index 92cde38b..4d477353 100644 --- a/pkg/orm/do_nothing_omr_test.go +++ b/pkg/orm/do_nothing_orm_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/orm/filter.go b/pkg/orm/filter.go index d04b8c42..03a30022 100644 --- a/pkg/orm/filter.go +++ b/pkg/orm/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import ( // don't forget to call next(...) inside your Filter type FilterChain func(next Filter) Filter -// Filter's behavior is a little big strang. +// Filter's behavior is a little big strange. // it's only be called when users call methods of Ormer type Filter func(ctx context.Context, inv *Invocation) @@ -31,6 +31,6 @@ var globalFilterChains = make([]FilterChain, 0, 4) // AddGlobalFilterChain adds a new FilterChain // All orm instances built after this invocation will use this filterChain, // but instances built before this invocation will not be affected -func AddGlobalFilterChain(filterChain FilterChain) { - globalFilterChains = append(globalFilterChains, filterChain) -} \ No newline at end of file +func AddGlobalFilterChain(filterChain ...FilterChain) { + globalFilterChains = append(globalFilterChains, filterChain...) +} diff --git a/pkg/orm/filter/opentracing/filter.go b/pkg/orm/filter/opentracing/filter.go index a55ae6d2..405e39ea 100644 --- a/pkg/orm/filter/opentracing/filter.go +++ b/pkg/orm/filter/opentracing/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package opentracing import ( "context" + "strings" "github.com/opentracing/opentracing-go" @@ -27,6 +28,8 @@ import ( // for example: // if we want to trace QuerySetter // actually we trace invoking "QueryTable" and "QueryTableWithCtx" +// the method Begin*, Commit and Rollback are ignored. +// When use using those methods, it means that they want to manager their transaction manually, so we won't handle them. type FilterChainBuilder struct { // CustomSpanFunc users are able to custom their span CustomSpanFunc func(span opentracing.Span, ctx context.Context, inv *orm.Invocation) @@ -35,25 +38,34 @@ type FilterChainBuilder struct { func (builder *FilterChainBuilder) FilterChain(next orm.Filter) orm.Filter { return func(ctx context.Context, inv *orm.Invocation) { operationName := builder.operationName(ctx, inv) - span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName) - defer span.Finish() - - next(spanCtx, inv) - span.SetTag("Method", inv.Method) - span.SetTag("Table", inv.GetTableName()) - span.SetTag("InsideTx", inv.InsideTx) - span.SetTag("TxName", spanCtx.Value(orm.TxNameKey)) - - if builder.CustomSpanFunc != nil { - builder.CustomSpanFunc(span, spanCtx, inv) + if strings.HasPrefix(inv.Method, "Begin") || inv.Method == "Commit" || inv.Method == "Rollback" { + next(ctx, inv) + return } + span, spanCtx := opentracing.StartSpanFromContext(ctx, operationName) + defer span.Finish() + next(spanCtx, inv) + builder.buildSpan(span, spanCtx, inv) + } +} + +func (builder *FilterChainBuilder) buildSpan(span opentracing.Span, ctx context.Context, inv *orm.Invocation) { + span.SetTag("orm.method", inv.Method) + span.SetTag("orm.table", inv.GetTableName()) + span.SetTag("orm.insideTx", inv.InsideTx) + span.SetTag("orm.txName", ctx.Value(orm.TxNameKey)) + span.SetTag("span.kind", "client") + span.SetTag("component", "beego") + + if builder.CustomSpanFunc != nil { + builder.CustomSpanFunc(span, ctx, inv) } } func (builder *FilterChainBuilder) operationName(ctx context.Context, inv *orm.Invocation) string { if n, ok := ctx.Value(orm.TxNameKey).(string); ok { - return inv.Method + "#" + n + return inv.Method + "#tx(" + n + ")" } return inv.Method + "#" + inv.GetTableName() } diff --git a/pkg/orm/filter/opentracing/filter_test.go b/pkg/orm/filter/opentracing/filter_test.go index 1428df8a..7df12a92 100644 --- a/pkg/orm/filter/opentracing/filter_test.go +++ b/pkg/orm/filter/opentracing/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -40,4 +40,4 @@ func TestFilterChainBuilder_FilterChain(t *testing.T) { TxStartTime: time.Now(), } builder.FilterChain(next)(context.Background(), inv) -} \ No newline at end of file +} diff --git a/pkg/orm/filter/prometheus/filter.go b/pkg/orm/filter/prometheus/filter.go index 33fdf78f..2e67d85c 100644 --- a/pkg/orm/filter/prometheus/filter.go +++ b/pkg/orm/filter/prometheus/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/orm/filter/prometheus/filter_test.go b/pkg/orm/filter/prometheus/filter_test.go index a71e8f50..34766fb4 100644 --- a/pkg/orm/filter/prometheus/filter_test.go +++ b/pkg/orm/filter/prometheus/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/orm/filter_orm_decorator.go b/pkg/orm/filter_orm_decorator.go index eb26ea68..279d299f 100644 --- a/pkg/orm/filter_orm_decorator.go +++ b/pkg/orm/filter_orm_decorator.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -21,7 +21,12 @@ import ( "time" ) -const TxNameKey = "TxName" +const ( + TxNameKey = "TxName" +) + +var _ Ormer = new(filterOrmDecorator) +var _ TxOrmer = new(filterOrmDecorator) type filterOrmDecorator struct { ormer @@ -40,7 +45,7 @@ func NewFilterOrmDecorator(delegate Ormer, filterChains ...FilterChain) Ormer { ormer: delegate, TxBeginner: delegate, root: func(ctx context.Context, inv *Invocation) { - inv.execute() + inv.execute(ctx) }, } @@ -58,7 +63,7 @@ func NewFilterTxOrmDecorator(delegate TxOrmer, root Filter, txName string) TxOrm root: root, insideTx: true, txStartTime: time.Now(), - txName: txName, + txName: txName, } return res } @@ -76,8 +81,8 @@ func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, co mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - err = f.ormer.ReadWithCtx(ctx, md, cols...) + f: func(c context.Context) { + err = f.ormer.ReadWithCtx(c, md, cols...) }, } f.root(ctx, inv) @@ -98,8 +103,8 @@ func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interf mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - err = f.ormer.ReadForUpdateWithCtx(ctx, md, cols...) + f: func(c context.Context) { + err = f.ormer.ReadForUpdateWithCtx(c, md, cols...) }, } f.root(ctx, inv) @@ -125,8 +130,8 @@ func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interfa mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - ok, res, err = f.ormer.ReadOrCreateWithCtx(ctx, md, col1, cols...) + f: func(c context.Context) { + ok, res, err = f.ormer.ReadOrCreateWithCtx(c, md, col1, cols...) }, } f.root(ctx, inv) @@ -151,8 +156,8 @@ func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interfac mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.LoadRelatedWithCtx(ctx, md, name, args...) + f: func(c context.Context) { + res, err = f.ormer.LoadRelatedWithCtx(c, md, name, args...) }, } f.root(ctx, inv) @@ -176,8 +181,8 @@ func (f *filterOrmDecorator) QueryM2MWithCtx(ctx context.Context, md interface{} mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res = f.ormer.QueryM2MWithCtx(ctx, md, name) + f: func(c context.Context) { + res = f.ormer.QueryM2MWithCtx(c, md, name) }, } f.root(ctx, inv) @@ -190,10 +195,10 @@ func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QueryS func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter { var ( - res QuerySeter + res QuerySeter name string - md interface{} - mi *modelInfo + md interface{} + mi *modelInfo ) if table, ok := ptrStructOrTableName.(string); ok { @@ -212,10 +217,10 @@ func (f *filterOrmDecorator) QueryTableWithCtx(ctx context.Context, ptrStructOrT Args: []interface{}{ptrStructOrTableName}, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - Md: md, - mi: mi, - f: func() { - res = f.ormer.QueryTableWithCtx(ctx, ptrStructOrTableName) + Md: md, + mi: mi, + f: func(c context.Context) { + res = f.ormer.QueryTableWithCtx(c, ptrStructOrTableName) }, } f.root(ctx, inv) @@ -230,7 +235,7 @@ func (f *filterOrmDecorator) DBStats() *sql.DBStats { Method: "DBStats", InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { + f: func(c context.Context) { res = f.ormer.DBStats() }, } @@ -255,8 +260,8 @@ func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.InsertWithCtx(ctx, md) + f: func(c context.Context) { + res, err = f.ormer.InsertWithCtx(c, md) }, } f.root(ctx, inv) @@ -280,8 +285,8 @@ func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md inter mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.InsertOrUpdateWithCtx(ctx, md, colConflitAndArgs...) + f: func(c context.Context) { + res, err = f.ormer.InsertOrUpdateWithCtx(c, md, colConflitAndArgs...) }, } f.root(ctx, inv) @@ -316,8 +321,8 @@ func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, m mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.InsertMultiWithCtx(ctx, bulk, mds) + f: func(c context.Context) { + res, err = f.ormer.InsertMultiWithCtx(c, bulk, mds) }, } f.root(ctx, inv) @@ -341,8 +346,8 @@ func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.UpdateWithCtx(ctx, md, cols...) + f: func(c context.Context) { + res, err = f.ormer.UpdateWithCtx(c, md, cols...) }, } f.root(ctx, inv) @@ -366,8 +371,8 @@ func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, mi: mi, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.ormer.DeleteWithCtx(ctx, md, cols...) + f: func(c context.Context) { + res, err = f.ormer.DeleteWithCtx(c, md, cols...) }, } f.root(ctx, inv) @@ -387,8 +392,8 @@ func (f *filterOrmDecorator) RawWithCtx(ctx context.Context, query string, args Args: []interface{}{query, args}, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res = f.ormer.RawWithCtx(ctx, query, args...) + f: func(c context.Context) { + res = f.ormer.RawWithCtx(c, query, args...) }, } f.root(ctx, inv) @@ -403,7 +408,7 @@ func (f *filterOrmDecorator) Driver() Driver { Method: "Driver", InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { + f: func(c context.Context) { res = f.ormer.Driver() }, } @@ -433,28 +438,28 @@ func (f *filterOrmDecorator) BeginWithCtxAndOpts(ctx context.Context, opts *sql. Args: []interface{}{opts}, InsideTx: f.insideTx, TxStartTime: f.txStartTime, - f: func() { - res, err = f.TxBeginner.BeginWithCtxAndOpts(ctx, opts) - res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(ctx)) + f: func(c context.Context) { + res, err = f.TxBeginner.BeginWithCtxAndOpts(c, opts) + res = NewFilterTxOrmDecorator(res, f.root, getTxNameFromCtx(c)) }, } f.root(ctx, inv) return res, err } -func (f *filterOrmDecorator) DoTx(task func(txOrm TxOrmer) error) error { +func (f *filterOrmDecorator) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error { return f.DoTxWithCtxAndOpts(context.Background(), nil, task) } -func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error { +func (f *filterOrmDecorator) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error { return f.DoTxWithCtxAndOpts(ctx, nil, task) } -func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (f *filterOrmDecorator) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { return f.DoTxWithCtxAndOpts(context.Background(), opts, task) } -func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { var ( err error ) @@ -465,8 +470,8 @@ func (f *filterOrmDecorator) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.T InsideTx: f.insideTx, TxStartTime: f.txStartTime, TxName: getTxNameFromCtx(ctx), - f: func() { - err = f.TxBeginner.DoTxWithCtxAndOpts(ctx, opts, task) + f: func(c context.Context) { + err = doTxTemplate(f, c, opts, task) }, } f.root(ctx, inv) @@ -483,7 +488,7 @@ func (f *filterOrmDecorator) Commit() error { InsideTx: f.insideTx, TxStartTime: f.txStartTime, TxName: f.txName, - f: func() { + f: func(c context.Context) { err = f.TxCommitter.Commit() }, } @@ -501,7 +506,7 @@ func (f *filterOrmDecorator) Rollback() error { InsideTx: f.insideTx, TxStartTime: f.txStartTime, TxName: f.txName, - f: func() { + f: func(c context.Context) { err = f.TxCommitter.Rollback() }, } @@ -516,4 +521,3 @@ func getTxNameFromCtx(ctx context.Context) string { } return txName } - diff --git a/pkg/orm/filter_orm_decorator_test.go b/pkg/orm/filter_orm_decorator_test.go index d1099eaf..4e837a4e 100644 --- a/pkg/orm/filter_orm_decorator_test.go +++ b/pkg/orm/filter_orm_decorator_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -130,49 +130,49 @@ func TestFilterOrmDecorator_DoTx(t *testing.T) { o := &filterMockOrm{} od := NewFilterOrmDecorator(o, func(next Filter) Filter { return func(ctx context.Context, inv *Invocation) { - assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method) - assert.Equal(t, 2, len(inv.Args)) - assert.Equal(t, "", inv.GetTableName()) - assert.False(t, inv.InsideTx) + if inv.Method == "DoTxWithCtxAndOpts" { + assert.Equal(t, 2, len(inv.Args)) + assert.Equal(t, "", inv.GetTableName()) + assert.False(t, inv.InsideTx) + } + next(ctx, inv) } }) - err := od.DoTx(func(txOrm TxOrmer) error { - return errors.New("tx error") + err := od.DoTx(func(c context.Context, txOrm TxOrmer) error { + return nil }) assert.NotNil(t, err) - assert.Equal(t, "tx error", err.Error()) - err = od.DoTxWithCtx(context.Background(), func(txOrm TxOrmer) error { - return errors.New("tx ctx error") + err = od.DoTxWithCtx(context.Background(), func(c context.Context, txOrm TxOrmer) error { + return nil }) assert.NotNil(t, err) - assert.Equal(t, "tx ctx error", err.Error()) - err = od.DoTxWithOpts(nil, func(txOrm TxOrmer) error { - return errors.New("tx opts error") + err = od.DoTxWithOpts(nil, func(c context.Context, txOrm TxOrmer) error { + return nil }) assert.NotNil(t, err) - assert.Equal(t, "tx opts error", err.Error()) + od = NewFilterOrmDecorator(o, func(next Filter) Filter { return func(ctx context.Context, inv *Invocation) { - assert.Equal(t, "DoTxWithCtxAndOpts", inv.Method) - assert.Equal(t, 2, len(inv.Args)) - assert.Equal(t, "", inv.GetTableName()) - assert.Equal(t, "do tx name", inv.TxName) - assert.False(t, inv.InsideTx) + if inv.Method == "DoTxWithCtxAndOpts" { + assert.Equal(t, 2, len(inv.Args)) + assert.Equal(t, "", inv.GetTableName()) + assert.Equal(t, "do tx name", inv.TxName) + assert.False(t, inv.InsideTx) + } next(ctx, inv) } }) ctx := context.WithValue(context.Background(), TxNameKey, "do tx name") - err = od.DoTxWithCtxAndOpts(ctx, nil, func(txOrm TxOrmer) error { - return errors.New("tx ctx opts error") + err = od.DoTxWithCtxAndOpts(ctx, nil, func(c context.Context, txOrm TxOrmer) error { + return nil }) assert.NotNil(t, err) - assert.Equal(t, "tx ctx opts error", err.Error()) } func TestFilterOrmDecorator_Driver(t *testing.T) { @@ -347,6 +347,8 @@ func TestFilterOrmDecorator_ReadOrCreate(t *testing.T) { assert.Equal(t, int64(13), i) } +var _ Ormer = new(filterMockOrm) + // filterMockOrm is only used in this test file type filterMockOrm struct { DoNothingOrm @@ -376,8 +378,8 @@ func (f *filterMockOrm) InsertWithCtx(ctx context.Context, md interface{}) (int6 return 100, errors.New("insert error") } -func (f *filterMockOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { - return task(nil) +func (f *filterMockOrm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(c context.Context, txOrm TxOrmer) error) error { + return task(ctx, nil) } func (f *filterMockOrm) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { diff --git a/pkg/orm/filter_test.go b/pkg/orm/filter_test.go index 0f2944c7..b2ca4ae1 100644 --- a/pkg/orm/filter_test.go +++ b/pkg/orm/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -28,4 +28,5 @@ func TestAddGlobalFilterChain(t *testing.T) { } }) assert.Equal(t, 1, len(globalFilterChains)) + globalFilterChains = nil } diff --git a/pkg/orm/invocation.go b/pkg/orm/invocation.go index 1c9fee09..e935b7ea 100644 --- a/pkg/orm/invocation.go +++ b/pkg/orm/invocation.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ package orm import ( + "context" "time" ) @@ -22,27 +23,27 @@ import ( type Invocation struct { Method string // Md may be nil in some cases. It depends on method - Md interface{} + Md interface{} // the args are all arguments except context.Context - Args []interface{} + Args []interface{} mi *modelInfo // f is the Orm operation - f func() + f func(ctx context.Context) // insideTx indicates whether this is inside a transaction - InsideTx bool + InsideTx bool TxStartTime time.Time - TxName string + TxName string } func (inv *Invocation) GetTableName() string { - if inv.mi != nil{ + if inv.mi != nil { return inv.mi.table } return "" } -func (inv *Invocation) execute() { - inv.f() +func (inv *Invocation) execute(ctx context.Context) { + inv.f(ctx) } diff --git a/pkg/orm/model_utils_test.go b/pkg/orm/model_utils_test.go index ea38d90a..b65aadcb 100644 --- a/pkg/orm/model_utils_test.go +++ b/pkg/orm/model_utils_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 +// Copyright 2020 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/orm/models_test.go b/pkg/orm/models_test.go index ae166dc7..09ef4f15 100644 --- a/pkg/orm/models_test.go +++ b/pkg/orm/models_test.go @@ -27,7 +27,6 @@ import ( _ "github.com/mattn/go-sqlite3" // As tidb can't use go get, so disable the tidb testing now // _ "github.com/pingcap/tidb" - ) // A slice string field. diff --git a/pkg/orm/orm.go b/pkg/orm/orm.go index d79053af..cc678fc8 100644 --- a/pkg/orm/orm.go +++ b/pkg/orm/orm.go @@ -522,19 +522,24 @@ func (o *orm) BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxO return taskTxOrm, nil } -func (o *orm) DoTx(task func(txOrm TxOrmer) error) error { +func (o *orm) DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error { return o.DoTxWithCtx(context.Background(), task) } -func (o *orm) DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error { +func (o *orm) DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error { return o.DoTxWithCtxAndOpts(ctx, nil, task) } -func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (o *orm) DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { return o.DoTxWithCtxAndOpts(context.Background(), opts, task) } -func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error { +func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error { + return doTxTemplate(o, ctx, opts, task) +} + +func doTxTemplate(o TxBeginner, ctx context.Context, opts *sql.TxOptions, + task func(ctx context.Context, txOrm TxOrmer) error) error { _txOrm, err := o.BeginWithCtxAndOpts(ctx, opts) if err != nil { return err @@ -553,9 +558,8 @@ func (o *orm) DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task } } }() - var taskTxOrm = _txOrm - err = task(taskTxOrm) + err = task(ctx, taskTxOrm) panicked = false return err } @@ -582,18 +586,11 @@ func NewOrm() Ormer { // NewOrmUsingDB create new orm with the name func NewOrmUsingDB(aliasName string) Ormer { - o := new(orm) if al, ok := dataBaseCache.get(aliasName); ok { - o.alias = al - if Debug { - o.db = newDbQueryLog(al, al.DB) - } else { - o.db = al.DB - } + return newDBWithAlias(al) } else { panic(fmt.Errorf(" unknown db alias name `%s`", aliasName)) } - return o } // NewOrmWithDB create a new ormer object with specify *sql.DB for query @@ -603,14 +600,21 @@ func NewOrmWithDB(driverName, aliasName string, db *sql.DB, params ...common.KV) return nil, err } + return newDBWithAlias(al), nil +} + +func newDBWithAlias(al *alias) Ormer { o := new(orm) o.alias = al if Debug { - o.db = newDbQueryLog(o.alias, db) + o.db = newDbQueryLog(al, al.DB) } else { - o.db = db + o.db = al.DB } - return o, nil + if len(globalFilterChains) > 0 { + return NewFilterOrmDecorator(o, globalFilterChains...) + } + return o } diff --git a/pkg/orm/orm_test.go b/pkg/orm/orm_test.go index f5242a46..e3dafecd 100644 --- a/pkg/orm/orm_test.go +++ b/pkg/orm/orm_test.go @@ -2486,5 +2486,3 @@ func TestInsertOrUpdate(t *testing.T) { throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status)) } } - - diff --git a/pkg/orm/types.go b/pkg/orm/types.go index 9624fd94..59688588 100644 --- a/pkg/orm/types.go +++ b/pkg/orm/types.go @@ -95,10 +95,10 @@ type TxBeginner interface { BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) //closure control transaction - DoTx(task func(txOrm TxOrmer) error) error - DoTxWithCtx(ctx context.Context, task func(txOrm TxOrmer) error) error - DoTxWithOpts(opts *sql.TxOptions, task func(txOrm TxOrmer) error) error - DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(txOrm TxOrmer) error) error + DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error + DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error + DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error + DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error } type TxCommitter interface { diff --git a/pkg/router.go b/pkg/router.go index 8caba94a..6b25d7e3 100644 --- a/pkg/router.go +++ b/pkg/router.go @@ -468,12 +468,13 @@ func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter Filter // // do something // } // } -func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, params...bool) { +func (p *ControllerRegister) InsertFilterChain(pattern string, chain FilterChain, params ...bool) { root := p.chainRoot filterFunc := chain(root.filterFunc) p.chainRoot = newFilterRouter(pattern, BConfig.RouterCaseSensitive, filterFunc, params...) -} + p.chainRoot.next = root +} // add Filter into func (p *ControllerRegister) insertFilterRouter(pos int, mr *FilterRouter) (err error) { diff --git a/pkg/session/sess_file_test.go b/pkg/session/sess_file_test.go index 64b8d94a..a27d30a6 100644 --- a/pkg/session/sess_file_test.go +++ b/pkg/session/sess_file_test.go @@ -57,7 +57,7 @@ func TestFileProvider_SessionExist(t *testing.T) { _ = fp.SessionInit(180, sessionPath) exists, err := fp.SessionExist(sid) - if err != nil{ + if err != nil { t.Error(err) } if exists { diff --git a/pkg/web/doc.go b/pkg/web/doc.go index 2001f4ca..1425a729 100644 --- a/pkg/web/doc.go +++ b/pkg/web/doc.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/web/filter/opentracing/filter.go b/pkg/web/filter/opentracing/filter.go index 822d5e4d..e6ee9150 100644 --- a/pkg/web/filter/opentracing/filter.go +++ b/pkg/web/filter/opentracing/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,7 +31,6 @@ type FilterChainBuilder struct { CustomSpanFunc func(span opentracing.Span, ctx *beegoCtx.Context) } - func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.FilterFunc { return func(ctx *beegoCtx.Context) { var ( @@ -55,9 +54,21 @@ func (builder *FilterChainBuilder) FilterChain(next beego.FilterFunc) beego.Filt next(ctx) // if you think we need to do more things, feel free to create an issue to tell us - span.SetTag("status", ctx.Output.Status) - span.SetTag("method", ctx.Input.Method()) - span.SetTag("route", ctx.Input.GetData("RouterPattern")) + span.SetTag("http.status_code", ctx.ResponseWriter.Status) + span.SetTag("http.method", ctx.Input.Method()) + span.SetTag("peer.hostname", ctx.Request.Host) + span.SetTag("http.url", ctx.Request.URL.String()) + span.SetTag("http.scheme", ctx.Request.URL.Scheme) + span.SetTag("span.kind", "server") + span.SetTag("component", "beego") + if ctx.Output.IsServerError() || ctx.Output.IsClientError() { + span.SetTag("error", true) + } + span.SetTag("peer.address", ctx.Request.RemoteAddr) + span.SetTag("http.proto", ctx.Request.Proto) + + span.SetTag("beego.route", ctx.Input.GetData("RouterPattern")) + if builder.CustomSpanFunc != nil { builder.CustomSpanFunc(span, ctx) } @@ -70,7 +81,7 @@ func (builder *FilterChainBuilder) operationName(ctx *beegoCtx.Context) string { // TODO, if we support multiple servers, this need to be changed route, found := beego.BeeApp.Handlers.FindRouter(ctx) if found { - operationName = route.GetPattern() + operationName = ctx.Input.Method() + "#" + route.GetPattern() } return operationName } diff --git a/pkg/web/filter/opentracing/filter_test.go b/pkg/web/filter/opentracing/filter_test.go index 65f1f24e..750ea7a9 100644 --- a/pkg/web/filter/opentracing/filter_test.go +++ b/pkg/web/filter/opentracing/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/web/filter/prometheus/filter.go b/pkg/web/filter/prometheus/filter.go index bd47dcec..8f4b46e3 100644 --- a/pkg/web/filter/prometheus/filter.go +++ b/pkg/web/filter/prometheus/filter.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/web/filter/prometheus/filter_test.go b/pkg/web/filter/prometheus/filter_test.go index 7d2e2acf..822892bc 100644 --- a/pkg/web/filter/prometheus/filter_test.go +++ b/pkg/web/filter/prometheus/filter_test.go @@ -1,4 +1,4 @@ -// Copyright 2020 beego +// Copyright 2020 beego // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 9ca9535c48b38387a7af5ff5d8c5235465ba7273 Mon Sep 17 00:00:00 2001 From: jianzhiyao Date: Tue, 11 Aug 2020 16:53:31 +0800 Subject: [PATCH 3/5] fix:return error after inserting data when primary key is string --- pkg/orm/db.go | 7 ++++++- pkg/orm/db_oracle.go | 7 ++++++- pkg/orm/models_test.go | 5 +++++ pkg/orm/orm_test.go | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/pkg/orm/db.go b/pkg/orm/db.go index 9a1827e8..9024cf01 100644 --- a/pkg/orm/db.go +++ b/pkg/orm/db.go @@ -484,7 +484,12 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s if isMulti { return res.RowsAffected() } - return res.LastInsertId() + + lastInsertId, err:=res.LastInsertId() + if err != nil { + DebugLog.Println("[WARN] return LastInsertId error:", err) + } + return lastInsertId, nil } return 0, err } diff --git a/pkg/orm/db_oracle.go b/pkg/orm/db_oracle.go index 5d121f83..c8e71849 100644 --- a/pkg/orm/db_oracle.go +++ b/pkg/orm/db_oracle.go @@ -126,7 +126,12 @@ func (d *dbBaseOracle) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, nam if isMulti { return res.RowsAffected() } - return res.LastInsertId() + + lastInsertId, err := res.LastInsertId() + if err != nil { + DebugLog.Println("[WARN] return LastInsertId error:", err) + } + return lastInsertId, nil } return 0, err } diff --git a/pkg/orm/models_test.go b/pkg/orm/models_test.go index ae166dc7..3c7bbbc8 100644 --- a/pkg/orm/models_test.go +++ b/pkg/orm/models_test.go @@ -412,6 +412,11 @@ type PtrPk struct { Positive bool } +type StrPk struct { + Id string `orm:"column(id);size(64);pk"` + Value string +} + var DBARGS = struct { Driver string Source string diff --git a/pkg/orm/orm_test.go b/pkg/orm/orm_test.go index f5242a46..1a8a88ea 100644 --- a/pkg/orm/orm_test.go +++ b/pkg/orm/orm_test.go @@ -200,6 +200,7 @@ func TestSyncDb(t *testing.T) { RegisterModel(new(IntegerPk)) RegisterModel(new(UintPk)) RegisterModel(new(PtrPk)) + RegisterModel(new(StrPk)) err := RunSyncdb("default", true, Debug) throwFail(t, err) @@ -224,6 +225,7 @@ func TestRegisterModels(t *testing.T) { RegisterModel(new(IntegerPk)) RegisterModel(new(UintPk)) RegisterModel(new(PtrPk)) + RegisterModel(new(StrPk)) BootStrap() @@ -2487,4 +2489,21 @@ func TestInsertOrUpdate(t *testing.T) { } } +func TestStrPkInsert(t *testing.T) { + RegisterModel(new(StrPk)) + value := `StrPkValues(*56` + strPk := &StrPk{ + Id: "1", + Value: value, + } + + var err error + _, err = dORM.Insert(strPk) + throwFailNow(t, AssertIs(err, nil)) + + var vForTesting StrPk + err = dORM.QueryTable(new(StrPk)).Filter(`id`, `1`).One(&vForTesting) + throwFailNow(t, AssertIs(err, nil)) + throwFailNow(t, AssertIs(vForTesting.Value, value)) +} From 7267f5e573daa593b48954acd6002cedce9467e3 Mon Sep 17 00:00:00 2001 From: Phillip Stagnet Date: Tue, 11 Aug 2020 16:09:29 +0200 Subject: [PATCH 4/5] Add new config option into provider struct --- pkg/session/redis/sess_redis.go | 31 +++++++------- pkg/session/redis_cluster/redis_cluster.go | 36 ++++++++-------- .../redis_sentinel/sess_redis_sentinel.go | 42 +++++++++---------- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/pkg/session/redis/sess_redis.go b/pkg/session/redis/sess_redis.go index 7e991ef5..100f9e1e 100644 --- a/pkg/session/redis/sess_redis.go +++ b/pkg/session/redis/sess_redis.go @@ -109,12 +109,15 @@ func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { // Provider redis session provider type Provider struct { - maxlifetime int64 - savePath string - poolsize int - password string - dbNum int - poollist *redis.Client + maxlifetime int64 + savePath string + poolsize int + password string + dbNum int + idleTimeout time.Duration + idleCheckFrequency time.Duration + maxRetries int + poollist *redis.Client } // SessionInit init redis session @@ -149,25 +152,22 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { } else { rp.dbNum = 0 } - var idleTimeout time.Duration = 0 if len(configs) > 4 { timeout, err := strconv.Atoi(configs[4]) if err == nil && timeout > 0 { - idleTimeout = time.Duration(timeout) * time.Second + rp.idleTimeout = time.Duration(timeout) * time.Second } } - var idleCheckFrequency time.Duration = 0 if len(configs) > 5 { checkFrequency, err := strconv.Atoi(configs[5]) if err == nil && checkFrequency > 0 { - idleCheckFrequency = time.Duration(checkFrequency) * time.Second + rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second } } - var maxRetries = 0 if len(configs) > 6 { retries, err := strconv.Atoi(configs[6]) if err == nil && retries > 0 { - maxRetries = retries + rp.maxRetries = retries } } @@ -176,9 +176,9 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { Password: rp.password, PoolSize: rp.poolsize, DB: rp.dbNum, - IdleTimeout: idleTimeout, - IdleCheckFrequency: idleCheckFrequency, - MaxRetries: maxRetries, + IdleTimeout: rp.idleTimeout, + IdleCheckFrequency: rp.idleCheckFrequency, + MaxRetries: rp.maxRetries, }) return rp.poollist.Ping().Err() @@ -249,4 +249,3 @@ func (rp *Provider) SessionAll() int { func init() { session.Register("redis", redispder) } - diff --git a/pkg/session/redis_cluster/redis_cluster.go b/pkg/session/redis_cluster/redis_cluster.go index 75dc0e63..d6f051c1 100644 --- a/pkg/session/redis_cluster/redis_cluster.go +++ b/pkg/session/redis_cluster/redis_cluster.go @@ -107,12 +107,15 @@ func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { // Provider redis_cluster session provider type Provider struct { - maxlifetime int64 - savePath string - poolsize int - password string - dbNum int - poollist *rediss.ClusterClient + maxlifetime int64 + savePath string + poolsize int + password string + dbNum int + idleTimeout time.Duration + idleCheckFrequency time.Duration + maxRetries int + poollist *rediss.ClusterClient } // SessionInit init redis_cluster session @@ -147,35 +150,32 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { } else { rp.dbNum = 0 } - var idleTimeout time.Duration = 0 if len(configs) > 4 { timeout, err := strconv.Atoi(configs[4]) if err == nil && timeout > 0 { - idleTimeout = time.Duration(timeout) * time.Second + rp.idleTimeout = time.Duration(timeout) * time.Second } } - var idleCheckFrequency time.Duration = 0 if len(configs) > 5 { checkFrequency, err := strconv.Atoi(configs[5]) if err == nil && checkFrequency > 0 { - idleCheckFrequency = time.Duration(checkFrequency) * time.Second + rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second } } - var maxRetries = 0 if len(configs) > 6 { retries, err := strconv.Atoi(configs[6]) if err == nil && retries > 0 { - maxRetries = retries + rp.maxRetries = retries } } rp.poollist = rediss.NewClusterClient(&rediss.ClusterOptions{ - Addrs: strings.Split(rp.savePath, ";"), - Password: rp.password, - PoolSize: rp.poolsize, - IdleTimeout: idleTimeout, - IdleCheckFrequency: idleCheckFrequency, - MaxRetries: maxRetries, + Addrs: strings.Split(rp.savePath, ";"), + Password: rp.password, + PoolSize: rp.poolsize, + IdleTimeout: rp.idleTimeout, + IdleCheckFrequency: rp.idleCheckFrequency, + MaxRetries: rp.maxRetries, }) return rp.poollist.Ping().Err() } diff --git a/pkg/session/redis_sentinel/sess_redis_sentinel.go b/pkg/session/redis_sentinel/sess_redis_sentinel.go index da287b8d..67790096 100644 --- a/pkg/session/redis_sentinel/sess_redis_sentinel.go +++ b/pkg/session/redis_sentinel/sess_redis_sentinel.go @@ -107,13 +107,16 @@ func (rs *SessionStore) SessionRelease(w http.ResponseWriter) { // Provider redis_sentinel session provider type Provider struct { - maxlifetime int64 - savePath string - poolsize int - password string - dbNum int - poollist *redis.Client - masterName string + maxlifetime int64 + savePath string + poolsize int + password string + dbNum int + idleTimeout time.Duration + idleCheckFrequency time.Duration + maxRetries int + poollist *redis.Client + masterName string } // SessionInit init redis_sentinel session @@ -157,37 +160,34 @@ func (rp *Provider) SessionInit(maxlifetime int64, savePath string) error { } else { rp.masterName = "mymaster" } - var idleTimeout time.Duration = 0 if len(configs) > 5 { timeout, err := strconv.Atoi(configs[4]) if err == nil && timeout > 0 { - idleTimeout = time.Duration(timeout) * time.Second + rp.idleTimeout = time.Duration(timeout) * time.Second } } - var idleCheckFrequency time.Duration = 0 if len(configs) > 6 { checkFrequency, err := strconv.Atoi(configs[5]) if err == nil && checkFrequency > 0 { - idleCheckFrequency = time.Duration(checkFrequency) * time.Second + rp.idleCheckFrequency = time.Duration(checkFrequency) * time.Second } } - var maxRetries = 0 if len(configs) > 7 { retries, err := strconv.Atoi(configs[6]) if err == nil && retries > 0 { - maxRetries = retries + rp.maxRetries = retries } } rp.poollist = redis.NewFailoverClient(&redis.FailoverOptions{ - SentinelAddrs: strings.Split(rp.savePath, ";"), - Password: rp.password, - PoolSize: rp.poolsize, - DB: rp.dbNum, - MasterName: rp.masterName, - IdleTimeout: idleTimeout, - IdleCheckFrequency: idleCheckFrequency, - MaxRetries: maxRetries, + SentinelAddrs: strings.Split(rp.savePath, ";"), + Password: rp.password, + PoolSize: rp.poolsize, + DB: rp.dbNum, + MasterName: rp.masterName, + IdleTimeout: rp.idleTimeout, + IdleCheckFrequency: rp.idleCheckFrequency, + MaxRetries: rp.maxRetries, }) return rp.poollist.Ping().Err() From 813a4df3c53b5f14453dec6753d121ddfb188f8a Mon Sep 17 00:00:00 2001 From: Phillip Stagnet Date: Tue, 11 Aug 2020 16:21:43 +0200 Subject: [PATCH 5/5] Make sure expiry time is in seconds --- pkg/session/redis/sess_redis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/session/redis/sess_redis.go b/pkg/session/redis/sess_redis.go index 100f9e1e..6e1fbae6 100644 --- a/pkg/session/redis/sess_redis.go +++ b/pkg/session/redis/sess_redis.go @@ -224,7 +224,7 @@ func (rp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) c.Do(c.Context(), "SET", sid, "", "EX", rp.maxlifetime) } else { c.Rename(oldsid, sid) - c.Expire(sid, time.Duration(rp.maxlifetime)) + c.Expire(sid, time.Duration(rp.maxlifetime) * time.Second) } return rp.SessionRead(sid) }