From 1de5d7c55d3e663a0696b0046c4922d6334908bc Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Fri, 10 May 2024 12:01:20 +0800 Subject: [PATCH] =?UTF-8?q?other:=20v2=20nexus=20=E5=8C=85=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20IndependentGoroutine=20=E7=9A=84=20broker=20?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E8=AF=A5=20broker=20=E4=B8=AD?= =?UTF-8?q?=E5=B0=86=E5=AF=B9=E6=AF=8F=E4=B8=AA=20topic=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=8D=95=E7=8B=AC=E7=9A=84=20goroutine=20=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E7=BB=B4=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 -- go.mod | 66 +----- go.sum | 224 ++---------------- rpc/{internal => }/discovery/nats.go | 2 +- rpc/{internal => }/discovery/nats_service.go | 2 +- rpc/{internal => }/registry/nats.go | 2 +- rpc/{internal => }/registry/nats_caller.go | 0 rpc/rpcbuiltin/discovery.go | 2 +- rpc/rpcbuiltin/registry.go | 2 +- rpc/{internal => }/utils/nats.go | 0 server/controller.go | 7 + server/events.go | 14 +- server/network/gnet.go | 3 +- server/network/gnet_logger.go | 31 +++ server/router/multistage.go | 4 +- server/router/type_fixed_multistage.go | 6 +- toolkit/balancer/balancer.go | 2 +- toolkit/balancer/consistent_hash.go | 1 + toolkit/buffer/errors.go | 2 +- toolkit/chrono/moment.go | 53 +---- toolkit/chrono/moment_test.go | 40 ++++ toolkit/chrono/period_test.go | 2 +- toolkit/chrono/scheduler.go | 10 +- toolkit/chrono/shceduler_test.go | 2 +- toolkit/chrono/state_line_test.go | 2 +- toolkit/collection/listings/priority_slice.go | 2 +- .../listings/priority_slice_test.go | 2 +- .../collection/topological_example_test.go | 6 +- toolkit/collection/topological_test.go | 4 +- toolkit/internal/ecs/ecs_types_test.go | 4 +- toolkit/internal/ecs/entity_pool.go | 2 +- toolkit/internal/ecs/world_test.go | 4 +- toolkit/log/defines.go | 10 +- toolkit/mask/dynamic_mask.go | 6 +- .../nexus/brokers/independent_goroutine.go | 195 +++++++++++++++ .../brokers/independent_goroutine_options.go | 49 ++++ .../brokers/independent_goroutine_test.go | 135 +++++++++++ toolkit/nexus/brokers/sparse_goroutine.go | 2 +- toolkit/nexus/events/asynchronous.go | 3 +- toolkit/nexus/queue.go | 2 +- toolkit/nexus/queues/non_blocking_rw.go | 4 +- toolkit/random/probabillity_test.go | 2 +- toolkit/ranking/binary_search.go | 10 +- toolkit/ranking/binary_search_events.go | 8 +- toolkit/ranking/binary_search_options.go | 8 +- 45 files changed, 556 insertions(+), 397 deletions(-) rename rpc/{internal => }/discovery/nats.go (97%) rename rpc/{internal => }/discovery/nats_service.go (97%) rename rpc/{internal => }/registry/nats.go (97%) rename rpc/{internal => }/registry/nats_caller.go (100%) rename rpc/{internal => }/utils/nats.go (100%) create mode 100644 server/network/gnet_logger.go create mode 100644 toolkit/chrono/moment_test.go create mode 100644 toolkit/nexus/brokers/independent_goroutine.go create mode 100644 toolkit/nexus/brokers/independent_goroutine_options.go create mode 100644 toolkit/nexus/brokers/independent_goroutine_test.go diff --git a/README.md b/README.md index f4045efc..266a4fac 100644 --- a/README.md +++ b/README.md @@ -19,22 +19,6 @@ Minotaur 是一个用于服务端开发的支持库,其中采用了大量泛 > - 网络传输基于 [`panjf2000/gnet`](https://github.com/panjf2000/gnet)、[`xtaci/kcp-go`](https://github.com/xtaci/kcp-go) 构建; > - 该项目的目标是提供一个简单、高效、可扩展的游戏服务器框架,让开发者可以专注于游戏逻辑的开发,而不用花费大量时间在网络传输、配置导表、日志、监控等基础功能的开发上; -#### v0.5.X 之后的版本为重构后的版本,重构后的版本主要有以下特点: -- 移除了大量的无用或不合理的实现,减少了代码的复杂度; -- 所有设计均优先考虑了泛型的使用,提高了代码的复用性; -- 关于 `server` 包,对于整体进行了重构,具体如下: - - 移除了对于 `gRPC` 的支持及依赖; - - 移除了对于 `gin` 的依赖,默认的 HTTP 服务将采用 `http.ServeMux` 进行处理,支持使用自定义 `http.Handler`; - - 关于 `WebSocket` 更改为使用 `gnet` 和 `github.com/gobwas/ws` 进行处理; - - 开放 `server.Network` 接口,支持自定义网络协议; - - `pprof` 支持运行时动态开关; - - 基于 `shunt` 分流概念的 `actor` 模型整体重构、解耦,并将名称调整为 `queue`,连接所在队列不再与连接绑定,现在支持直接向特定队列发送消息; - - 对外开放服务器消息驱动模型接口,支持自定义消息驱动模型; - - 将 `utils` 包更名为 `toolkit`,并对其中的大量函数、设计、目录结构进行了调整; - - 内置了基于 `nats.io` 的 `rpc` 支持; - -*** - ## 特色内容 ```mermaid mindmap diff --git a/go.mod b/go.mod index 86ce8f53..cf67bd76 100644 --- a/go.mod +++ b/go.mod @@ -4,85 +4,45 @@ go 1.22.0 require ( github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108 - github.com/alphadose/haxmap v1.3.1 - github.com/gin-contrib/pprof v1.4.0 - github.com/gin-gonic/gin v1.9.1 - github.com/go-resty/resty/v2 v2.11.0 + github.com/fatih/color v1.16.0 + github.com/gobwas/ws v1.4.0 github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 - github.com/gorilla/websocket v1.5.1 github.com/json-iterator/go v1.1.12 - github.com/panjf2000/ants/v2 v2.9.0 - github.com/panjf2000/gnet v1.6.7 - github.com/panjf2000/gnet/v2 v2.3.6 + github.com/nats-io/nats.go v1.34.1 + github.com/panjf2000/ants/v2 v2.9.1 + github.com/panjf2000/gnet/v2 v2.5.2 github.com/pkg/errors v0.9.1 - github.com/smartystreets/goconvey v1.8.1 - github.com/sony/sonyflake v1.2.0 - github.com/spf13/cobra v1.8.0 - github.com/stretchr/testify v1.8.4 + github.com/samber/do/v2 v2.0.0-beta.5 github.com/tealeg/xlsx v1.0.5 - github.com/tidwall/gjson v1.17.0 github.com/xtaci/kcp-go/v5 v5.6.8 - go.uber.org/atomic v1.11.0 - golang.org/x/crypto v0.23.0 - google.golang.org/grpc v1.60.1 + golang.org/x/net v0.25.0 ) require ( - github.com/bytedance/gopkg v0.0.0-20240315062850-21fc7a1671a8 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/dave/jennifer v1.7.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect - github.com/gobwas/ws v1.3.2 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/gopherjs/gopherjs v1.17.2 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/klauspost/reedsolomon v1.12.1 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nats-io/nats.go v1.34.1 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/samber/do/v2 v2.0.0-beta.5 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/samber/go-type-to-string v1.2.0 // indirect - github.com/smarty/assertions v1.15.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/templexxx/cpu v0.1.0 // indirect github.com/templexxx/xorsimd v0.4.2 // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect - github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.6.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect - google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e8016d39..705dc164 100644 --- a/go.sum +++ b/go.sum @@ -2,24 +2,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108 h1:iPugyBI7oFtbDZXC4dnY093M1kZx6k/95sen92gafbY= github.com/RussellLuo/timingwheel v0.0.0-20220218152713-54845bda3108/go.mod h1:WAMLHwunr1hi3u7OjGV6/VWG9QbdMhGpEKjROiSFd10= -github.com/alphadose/haxmap v1.3.1 h1:KmZh75duO1tC8pt3LmUwoTYiZ9sh4K52FX8p7/yrlqU= -github.com/alphadose/haxmap v1.3.1/go.mod h1:rjHw1IAqbxm0S3U5tD16GoKsiAd8FWx5BJ2IYqXwgmM= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/bytedance/gopkg v0.0.0-20240315062850-21fc7a1671a8 h1:8LX2T6XzOOPvVMS8RH0sY4+QFmO5XyFUnrmwVbtD13k= -github.com/bytedance/gopkg v0.0.0-20240315062850-21fc7a1671a8/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE= -github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -28,38 +14,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg= -github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8= -github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.3.2 h1:zlnbNHxumkRvfPWgfXu8RBwyNR1x8wh9cf5PTOCqs9Q= -github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= 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= @@ -71,57 +31,34 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= -github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY= github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= -github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/klauspost/reedsolomon v1.12.0 h1:I5FEp3xSwVCcEh3F5A7dofEfhXdF/bWhQWPH+XwBFno= -github.com/klauspost/reedsolomon v1.12.0/go.mod h1:EPLZJeh4l27pUGC3aXOjheaoh1I9yut7xTURiW3LQ9Y= github.com/klauspost/reedsolomon v1.12.1 h1:NhWgum1efX1x58daOBGCFWcxtEhOhXKKl1HAPQUp03Q= github.com/klauspost/reedsolomon v1.12.1/go.mod h1:nEi5Kjb6QqtbofI6s+cbG/j1da11c96IBYBSnVGtuBs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -135,18 +72,11 @@ github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/panjf2000/ants/v2 v2.4.7/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= -github.com/panjf2000/ants/v2 v2.9.0 h1:SztCLkVxBRigbg+vt0S5QvF5vxAbxbKt09/YfAJ0tEo= -github.com/panjf2000/ants/v2 v2.9.0/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= -github.com/panjf2000/gnet v1.6.7 h1:zv1k6kw80sG5ZQrLpbbFDheNCm50zm3z2e3ck5GwMOM= -github.com/panjf2000/gnet v1.6.7/go.mod h1:KcOU7QsCaCBjeD5kyshBIamG3d9kAQtlob4Y0v0E+sc= -github.com/panjf2000/gnet/v2 v2.3.6 h1:BUHjMPJaNO8N5rQZmhKce9/Iu2ryeMjhKPEOi+ecisQ= -github.com/panjf2000/gnet/v2 v2.3.6/go.mod h1:R+X5M5YBpOGMVP/92OJ02P35SbmoHjiL7GnaBhht6GE= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/panjf2000/ants/v2 v2.9.1 h1:Q5vh5xohbsZXGcD6hhszzGqB7jSSc2/CRr3QKIga8Kw= +github.com/panjf2000/ants/v2 v2.9.1/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= +github.com/panjf2000/gnet/v2 v2.5.2 h1:ctslzTSO77beWighLbLL9zsO7wmh5pYkomuWctO9+MY= +github.com/panjf2000/gnet/v2 v2.5.2/go.mod h1:cm9AIICvZSrQllpQG5u5st56VMJCAWbB9/qdNKlrpKM= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -155,33 +85,21 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/samber/do/v2 v2.0.0-beta.5 h1:KpQhVkkzDlsLSDC5WXgyCL8Q3SqOYoInFJIbvntPazM= github.com/samber/do/v2 v2.0.0-beta.5/go.mod h1:FNMy1RSKMX11Ag8v4KW95n9k+ZkCXn8GuvDKufVKN9E= github.com/samber/go-type-to-string v1.2.0 h1:Pvdqx3r/EHn9/DTKoW6RoHz/850s5yV1vA6MqKKG5Ys= github.com/samber/go-type-to-string v1.2.0/go.mod h1:jpU77vIDoIxkahknKDoEx9C8bQ1ADnh2sotZ8I4QqBU= -github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= -github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= -github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= -github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= -github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ= -github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -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/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE= @@ -190,199 +108,85 @@ github.com/templexxx/cpu v0.1.0 h1:wVM+WIJP2nYaxVxqgHPD4wGA2aJ9rvrQRV8CvFzNb40= github.com/templexxx/cpu v0.1.0/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk= github.com/templexxx/xorsimd v0.4.2 h1:ocZZ+Nvu65LGHmCLZ7OoCtg8Fx8jnHKK37SjvngUoVI= github.com/templexxx/xorsimd v0.4.2/go.mod h1:HgwaPoDREdi6OnULpSfxhzaiiSUY4Fi3JPn1wpt28NI= -github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= -github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/xtaci/kcp-go/v5 v5.6.7 h1:7+rnxNFIsjEwTXQk4cSZpXM4pO0hqtpwE1UFFoJBffA= -github.com/xtaci/kcp-go/v5 v5.6.7/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM= github.com/xtaci/kcp-go/v5 v5.6.8 h1:jlI/0jAyjoOjT/SaGB58s4bQMJiNS41A2RKzR6TMWeI= github.com/xtaci/kcp-go/v5 v5.6.8/go.mod h1:oE9j2NVqAkuKO5o8ByKGch3vgVX3BNf8zqP8JiGq0bM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE= -golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211204120058-94396e421777/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= 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/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= 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= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/rpc/internal/discovery/nats.go b/rpc/discovery/nats.go similarity index 97% rename from rpc/internal/discovery/nats.go rename to rpc/discovery/nats.go index 5a9a0b82..494354ff 100644 --- a/rpc/internal/discovery/nats.go +++ b/rpc/discovery/nats.go @@ -3,7 +3,7 @@ package discovery import ( "context" "github.com/kercylan98/minotaur/rpc" - "github.com/kercylan98/minotaur/rpc/internal/utils" + "github.com/kercylan98/minotaur/rpc/utils" "github.com/kercylan98/minotaur/toolkit" "github.com/nats-io/nats.go" "time" diff --git a/rpc/internal/discovery/nats_service.go b/rpc/discovery/nats_service.go similarity index 97% rename from rpc/internal/discovery/nats_service.go rename to rpc/discovery/nats_service.go index aee54755..308c7931 100644 --- a/rpc/internal/discovery/nats_service.go +++ b/rpc/discovery/nats_service.go @@ -3,7 +3,7 @@ package discovery import ( "context" "github.com/kercylan98/minotaur/rpc" - "github.com/kercylan98/minotaur/rpc/internal/registry" + "github.com/kercylan98/minotaur/rpc/registry" "github.com/kercylan98/minotaur/toolkit" "github.com/nats-io/nats.go" ) diff --git a/rpc/internal/registry/nats.go b/rpc/registry/nats.go similarity index 97% rename from rpc/internal/registry/nats.go rename to rpc/registry/nats.go index 9e3155bd..4d4f6b0b 100644 --- a/rpc/internal/registry/nats.go +++ b/rpc/registry/nats.go @@ -3,7 +3,7 @@ package registry import ( "context" "github.com/kercylan98/minotaur/rpc" - "github.com/kercylan98/minotaur/rpc/internal/utils" + "github.com/kercylan98/minotaur/rpc/utils" "github.com/kercylan98/minotaur/toolkit" "github.com/nats-io/nats.go" "time" diff --git a/rpc/internal/registry/nats_caller.go b/rpc/registry/nats_caller.go similarity index 100% rename from rpc/internal/registry/nats_caller.go rename to rpc/registry/nats_caller.go diff --git a/rpc/rpcbuiltin/discovery.go b/rpc/rpcbuiltin/discovery.go index 39039d00..6cc94b39 100644 --- a/rpc/rpcbuiltin/discovery.go +++ b/rpc/rpcbuiltin/discovery.go @@ -2,7 +2,7 @@ package rpcbuiltin import ( "github.com/kercylan98/minotaur/rpc" - "github.com/kercylan98/minotaur/rpc/internal/discovery" + "github.com/kercylan98/minotaur/rpc/discovery" "github.com/nats-io/nats.go" ) diff --git a/rpc/rpcbuiltin/registry.go b/rpc/rpcbuiltin/registry.go index 045c95e8..bd83d0c2 100644 --- a/rpc/rpcbuiltin/registry.go +++ b/rpc/rpcbuiltin/registry.go @@ -2,7 +2,7 @@ package rpcbuiltin import ( "github.com/kercylan98/minotaur/rpc" - "github.com/kercylan98/minotaur/rpc/internal/registry" + "github.com/kercylan98/minotaur/rpc/registry" "github.com/nats-io/nats.go" ) diff --git a/rpc/internal/utils/nats.go b/rpc/utils/nats.go similarity index 100% rename from rpc/internal/utils/nats.go rename to rpc/utils/nats.go diff --git a/server/controller.go b/server/controller.go index 8e59d1ac..e3b85f4b 100644 --- a/server/controller.go +++ b/server/controller.go @@ -2,6 +2,7 @@ package server import ( "context" + "github.com/kercylan98/minotaur/toolkit/log" "github.com/panjf2000/ants/v2" "net" ) @@ -20,6 +21,8 @@ type Controller interface { GetAnts() *ants.Pool // OnConnectionAsyncWriteError 注册连接异步写入数据错误事件 OnConnectionAsyncWriteError(conn Conn, packet Packet, err error) + // GetServerLogger 获取服务器日志记录器 + GetServerLogger() *log.Logger } type controller struct { @@ -75,3 +78,7 @@ func (s *controller) ReactPacket(conn net.Conn, packet Packet) { }) }) } + +func (s *controller) GetServerLogger() *log.Logger { + return s.server.Options.GetLogger() +} diff --git a/server/events.go b/server/events.go index 9326fa23..2ace3ffa 100644 --- a/server/events.go +++ b/server/events.go @@ -7,13 +7,13 @@ import ( ) type ( - LaunchedEventHandler func(srv Server, ip string, t time.Time) - ShutdownEventHandler func(srv Server) - ConnectionOpenedEventHandler func(srv Server, conn Conn) - ConnectionOpenedAfterEventHandler func(srv Server, conn Conn) - ConnectionClosedEventHandler func(srv Server, conn Conn, err error) - ConnectionReceivePacketEventHandler func(srv Server, conn Conn, packet Packet) - ConnectionAsyncWriteErrorEventHandler func(srv Server, conn Conn, packet Packet, err error) + LaunchedEventHandler func(srv Server, ip string, t time.Time) // 服务器启动事件 + ShutdownEventHandler func(srv Server) // 服务器关闭事件 + ConnectionOpenedEventHandler func(srv Server, conn Conn) // 连接打开事件 + ConnectionOpenedAfterEventHandler func(srv Server, conn Conn) // 连接打开后事件 + ConnectionClosedEventHandler func(srv Server, conn Conn, err error) // 连接关闭事件 + ConnectionReceivePacketEventHandler func(srv Server, conn Conn, packet Packet) // 连接接收数据包事件 + ConnectionAsyncWriteErrorEventHandler func(srv Server, conn Conn, packet Packet, err error) // 连接异步写入数据错误事件 ) type Events interface { diff --git a/server/network/gnet.go b/server/network/gnet.go index 469f8b65..c5c71227 100644 --- a/server/network/gnet.go +++ b/server/network/gnet.go @@ -73,7 +73,8 @@ func (w *gNetCore) OnRun() (err error) { default: return fmt.Errorf("unsupported schema: %s", w.schema) } - err = gnet.Run(w.handler, addr) + + err = gnet.Run(w.handler, addr, gnet.WithLogger(&gNetLogger{w.controller})) return } diff --git a/server/network/gnet_logger.go b/server/network/gnet_logger.go new file mode 100644 index 00000000..7bd9c6a9 --- /dev/null +++ b/server/network/gnet_logger.go @@ -0,0 +1,31 @@ +package network + +import ( + "fmt" + "github.com/kercylan98/minotaur/server" + "github.com/kercylan98/minotaur/toolkit/log" +) + +type gNetLogger struct { + server.Controller +} + +func (l *gNetLogger) Debugf(format string, args ...interface{}) { + l.GetServerLogger().Debug("gnet", log.String("message", fmt.Sprintf(format, args...))) +} + +func (l *gNetLogger) Infof(format string, args ...interface{}) { + l.GetServerLogger().Info("gnet", log.String("message", fmt.Sprintf(format, args...))) +} + +func (l *gNetLogger) Warnf(format string, args ...interface{}) { + l.GetServerLogger().Warn("gnet", log.String("message", fmt.Sprintf(format, args...))) +} + +func (l *gNetLogger) Errorf(format string, args ...interface{}) { + l.GetServerLogger().Error("gnet", log.String("message", fmt.Sprintf(format, args...))) +} + +func (l *gNetLogger) Fatalf(format string, args ...interface{}) { + l.GetServerLogger().Error("gnet fatal:", log.String("message", fmt.Sprintf(format, args...))) +} diff --git a/server/router/multistage.go b/server/router/multistage.go index 53318fa1..f16252ec 100644 --- a/server/router/multistage.go +++ b/server/router/multistage.go @@ -21,8 +21,8 @@ func NewMultistage[HandleFunc any](options ...MultistageOption[HandleFunc]) *Mul type MultistageBind[HandleFunc any] func(HandleFunc) // Bind 将处理函数绑定到预设的路由中 -func (slf MultistageBind[HandleFunc]) Bind(handleFunc HandleFunc) { - slf(handleFunc) +func (b MultistageBind[HandleFunc]) Bind(handleFunc HandleFunc) { + b(handleFunc) } // Multistage 支持多级分类的路由器 diff --git a/server/router/type_fixed_multistage.go b/server/router/type_fixed_multistage.go index a7b35aee..9df07303 100644 --- a/server/router/type_fixed_multistage.go +++ b/server/router/type_fixed_multistage.go @@ -15,12 +15,12 @@ func NewTypeFixedMultistage[T constraints.Ordered, HandleFunc any]() *TypeFixedM return r } -// TypeFixedMultistageBind 多级分类路由绑定函数 +// TypeFixedMultistageBind 多级分类路由绑定函数,该路由器与 Multistage 的区别在于仅支持固定类型的路由 type TypeFixedMultistageBind[HandleFunc any] func(HandleFunc) // Bind 将处理函数绑定到预设的路由中 -func (slf TypeFixedMultistageBind[HandleFunc]) Bind(handleFunc HandleFunc) { - slf(handleFunc) +func (b TypeFixedMultistageBind[HandleFunc]) Bind(handleFunc HandleFunc) { + b(handleFunc) } // TypeFixedMultistage 支持多级分类的路由器 diff --git a/toolkit/balancer/balancer.go b/toolkit/balancer/balancer.go index 129d9cc1..cfc801b1 100644 --- a/toolkit/balancer/balancer.go +++ b/toolkit/balancer/balancer.go @@ -6,7 +6,7 @@ import ( ) var ( - ErrNoInstance = errors.New("no instance") + ErrNoInstance = errors.New("no instance") // 没有实例 ) type Balancer[I constraints.Ordered, T Item[I]] interface { diff --git a/toolkit/balancer/consistent_hash.go b/toolkit/balancer/consistent_hash.go index b84267af..49c98ce9 100644 --- a/toolkit/balancer/consistent_hash.go +++ b/toolkit/balancer/consistent_hash.go @@ -7,6 +7,7 @@ import ( "sort" ) +// NewConsistentHash 创建一个一致性哈希负载均衡器 func NewConsistentHash[I constraints.Ordered, T Item[I]]() *ConsistentHash[I, T] { return &ConsistentHash[I, T]{} } diff --git a/toolkit/buffer/errors.go b/toolkit/buffer/errors.go index 0ea881e9..4e3f0be1 100644 --- a/toolkit/buffer/errors.go +++ b/toolkit/buffer/errors.go @@ -3,5 +3,5 @@ package buffer import "errors" var ( - ErrBufferIsEmpty = errors.New("buffer is empty") + ErrBufferIsEmpty = errors.New("buffer is empty") // 缓冲区为空 ) diff --git a/toolkit/chrono/moment.go b/toolkit/chrono/moment.go index 8de9ad58..26fa75cd 100644 --- a/toolkit/chrono/moment.go +++ b/toolkit/chrono/moment.go @@ -8,74 +8,25 @@ import ( var zero = time.Time{} -// IsMomentReached 检查指定时刻是否已到达且未发生过 -// - now: 当前时间 -// - last: 上次发生的时间 -// - hour: 要检查的时刻的小时数 -// - min: 要检查的时刻的分钟数 -// - sec: 要检查的时刻的秒数 -func IsMomentReached(now time.Time, last time.Time, hour, min, sec int) bool { - moment := time.Date(last.Year(), last.Month(), last.Day(), hour, min, sec, 0, time.Local) - if !moment.Before(now) { - return false - } else if moment.After(last) { - return true - } - - // 如果要检查的时刻在上次发生的时间和当前时间之间,并且已经过了一天,说明已经发生 - nextDayMoment := moment.AddDate(0, 0, 1) - return !nextDayMoment.After(now) -} - // GetNextMoment 获取下一个指定时刻发生的时间。 func GetNextMoment(now time.Time, hour, min, sec int) time.Time { moment := time.Date(now.Year(), now.Month(), now.Day(), hour, min, sec, 0, time.Local) // 如果要检查的时刻已经过了,则返回明天的这个时刻 - if moment.Before(now) { + if now.After(moment) || now.Equal(moment) { moment = moment.AddDate(0, 0, 1) } return moment } -// IsMomentInDays 检查指定时刻是否在给定的天数内发生。 -// - now: 当前时间 -// - hour: 要检查的时刻的小时数 -// - min: 要检查的时刻的分钟数 -// - sec: 要检查的时刻的秒数 -// - days: 表示要偏移的天数。正数表示未来,负数表示过去,0 即今天 -func IsMomentInDays(now time.Time, hour, min, sec, days int) bool { - offsetTime := now.AddDate(0, 0, days) - moment := time.Date(offsetTime.Year(), offsetTime.Month(), offsetTime.Day(), hour, min, sec, 0, time.Local) - return now.Before(moment.AddDate(0, 0, 1)) && now.After(moment) -} - -// IsMomentYesterday 检查指定时刻是否在昨天发生 -func IsMomentYesterday(now time.Time, hour, min, sec int) bool { - return IsMomentInDays(now, hour, min, sec, -1) -} - -// IsMomentToday 检查指定时刻是否在今天发生 -func IsMomentToday(now time.Time, hour, min, sec int) bool { - return IsMomentInDays(now, hour, min, sec, 0) -} - -// IsMomentTomorrow 检查指定时刻是否在明天发生 -func IsMomentTomorrow(now time.Time, hour, min, sec int) bool { - return IsMomentInDays(now, hour, min, sec, 1) -} - // IsMomentPassed 检查指定时刻是否已经过去 func IsMomentPassed(now time.Time, hour, min, sec int) bool { - // 构建要检查的时刻 moment := time.Date(now.Year(), now.Month(), now.Day(), hour, min, sec, 0, time.Local) return now.After(moment) } // IsMomentFuture 检查指定时刻是否在未来 func IsMomentFuture(now time.Time, hour, min, sec int) bool { - // 构建要检查的时刻 - moment := time.Date(now.Year(), now.Month(), now.Day(), hour, min, sec, 0, time.Local) - return now.Before(moment) + return !IsMomentPassed(now, hour, min, sec) } // GetStartOfDay 获取指定时间的当天第一刻,即 00:00:00 diff --git a/toolkit/chrono/moment_test.go b/toolkit/chrono/moment_test.go new file mode 100644 index 00000000..743e77e5 --- /dev/null +++ b/toolkit/chrono/moment_test.go @@ -0,0 +1,40 @@ +package chrono_test + +import ( + "github.com/kercylan98/minotaur/toolkit/chrono" + "testing" + "time" +) + +func TestGetNextMoment(t *testing.T) { + var cases = []struct { + name string + now time.Time + hour int + min int + sec int + want time.Time + }{ + { + name: "today 00:00:00, next should be today 12:00:00", + now: time.Date(2021, 1, 1, 0, 0, 0, 0, time.Local), + hour: 12, min: 0, sec: 0, + want: time.Date(2021, 1, 1, 12, 0, 0, 0, time.Local), + }, + { + name: "today 12:00:00, next should be tomorrow 12:00:00", + now: time.Date(2021, 1, 1, 12, 0, 0, 0, time.Local), + hour: 12, min: 0, sec: 0, + want: time.Date(2021, 1, 2, 12, 0, 0, 0, time.Local), + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + got := chrono.GetNextMoment(c.now, c.hour, c.min, c.sec) + if got != c.want { + t.Errorf("GetNextMoment(%v, %d, %d, %d) = %v, want %v", c.now, c.hour, c.min, c.sec, got, c.want) + } + }) + } +} diff --git a/toolkit/chrono/period_test.go b/toolkit/chrono/period_test.go index 8e8aaaa8..fb707ef7 100644 --- a/toolkit/chrono/period_test.go +++ b/toolkit/chrono/period_test.go @@ -2,7 +2,7 @@ package chrono_test import ( "fmt" - "github.com/kercylan98/minotaur/utils/chrono" + "github.com/kercylan98/minotaur/toolkit/chrono" "testing" "time" ) diff --git a/toolkit/chrono/scheduler.go b/toolkit/chrono/scheduler.go index 1a0d8e98..938370ab 100644 --- a/toolkit/chrono/scheduler.go +++ b/toolkit/chrono/scheduler.go @@ -3,10 +3,10 @@ package chrono import ( "github.com/RussellLuo/timingwheel" "github.com/gorhill/cronexpr" -"github.com/kercylan98/minotaur/toolkit/collection" -"reflect" -"sync" -"time" + "github.com/kercylan98/minotaur/toolkit/collection" + "reflect" + "sync" + "time" ) const ( @@ -145,7 +145,7 @@ func (s *Scheduler) RegisterRepeatedTask(name string, after, interval time.Durat // - 当上次执行时间被错过时,将会立即执行一次 func (s *Scheduler) RegisterDayMomentTask(name string, lastExecuted time.Time, offset time.Duration, hour, min, sec int, function interface{}, args ...interface{}) { now := time.Now().Add(offset) - if IsMomentReached(now, lastExecuted, hour, min, sec) { + if lastExecuted.Before(now) && now.Sub(lastExecuted) > Day { s.call(name, function, args...) } diff --git a/toolkit/chrono/shceduler_test.go b/toolkit/chrono/shceduler_test.go index 9ecba82c..26dd80f5 100644 --- a/toolkit/chrono/shceduler_test.go +++ b/toolkit/chrono/shceduler_test.go @@ -2,7 +2,7 @@ package chrono_test import ( "fmt" - "github.com/kercylan98/minotaur/utils/chrono" + "github.com/kercylan98/minotaur/toolkit/chrono" "testing" "time" ) diff --git a/toolkit/chrono/state_line_test.go b/toolkit/chrono/state_line_test.go index df228950..8e655c9c 100644 --- a/toolkit/chrono/state_line_test.go +++ b/toolkit/chrono/state_line_test.go @@ -1,7 +1,7 @@ package chrono_test import ( - "github.com/kercylan98/minotaur/utils/chrono" + "github.com/kercylan98/minotaur/toolkit/chrono" "testing" "time" ) diff --git a/toolkit/collection/listings/priority_slice.go b/toolkit/collection/listings/priority_slice.go index fe70d991..3254773c 100644 --- a/toolkit/collection/listings/priority_slice.go +++ b/toolkit/collection/listings/priority_slice.go @@ -138,7 +138,7 @@ func (slf *PrioritySlice[V]) RangePriority(action func(index int, priority int) }) } -// SyncSlice 返回切片 +// Slice 返回切片 func (slf *PrioritySlice[V]) Slice() []V { var vs []V for _, item := range slf.items { diff --git a/toolkit/collection/listings/priority_slice_test.go b/toolkit/collection/listings/priority_slice_test.go index c8d3ac86..659512ce 100644 --- a/toolkit/collection/listings/priority_slice_test.go +++ b/toolkit/collection/listings/priority_slice_test.go @@ -2,7 +2,7 @@ package listings_test import ( "fmt" - "github.com/kercylan98/minotaur/utils/collection/listings" + "github.com/kercylan98/minotaur/toolkit/collection/listings" "testing" ) diff --git a/toolkit/collection/topological_example_test.go b/toolkit/collection/topological_example_test.go index d41ff73a..93e091f0 100644 --- a/toolkit/collection/topological_example_test.go +++ b/toolkit/collection/topological_example_test.go @@ -2,10 +2,10 @@ package collection_test import ( "fmt" - "github.com/kercylan98/minotaur/utils/sorts" + "github.com/kercylan98/minotaur/toolkit/collection" ) -func ExampleTopological() { +func ExampleTopologicalSort() { type Item struct { ID int Depends []int @@ -19,7 +19,7 @@ func ExampleTopological() { {ID: 5, Depends: []int{}}, } - var sorted, err = sorts.Topological(items, func(item Item) int { + var sorted, err = collection.TopologicalSort(items, func(item Item) int { return item.ID }, func(item Item) []int { return item.Depends diff --git a/toolkit/collection/topological_test.go b/toolkit/collection/topological_test.go index e8302958..64b3a334 100644 --- a/toolkit/collection/topological_test.go +++ b/toolkit/collection/topological_test.go @@ -1,7 +1,7 @@ package collection_test import ( - "github.com/kercylan98/minotaur/utils/sorts" + "github.com/kercylan98/minotaur/toolkit/collection" "testing" ) @@ -19,7 +19,7 @@ func TestTopological(t *testing.T) { {ID: 5, Depends: []int{}}, } - var sorted, err = sorts.Topological(items, func(item Item) int { + var sorted, err = collection.TopologicalSort(items, func(item Item) int { return item.ID }, func(item Item) []int { return item.Depends diff --git a/toolkit/internal/ecs/ecs_types_test.go b/toolkit/internal/ecs/ecs_types_test.go index 01d5d0e6..2c738697 100644 --- a/toolkit/internal/ecs/ecs_types_test.go +++ b/toolkit/internal/ecs/ecs_types_test.go @@ -1,7 +1,7 @@ package ecs import ( - "github.com/kercylan98/minotaur/utils/generic" + "github.com/kercylan98/minotaur/toolkit/constraints" "testing" ) @@ -272,7 +272,7 @@ type Component254 struct{ X int } type Component255 struct{ X int } type Component256 struct{ X int } -func ExceptNum[V generic.Number](t *testing.T, got, expect V) { +func ExceptNum[V constraints.Number](t *testing.T, got, expect V) { if got != expect { t.Fatalf("got %v, expect %v", got, expect) } diff --git a/toolkit/internal/ecs/entity_pool.go b/toolkit/internal/ecs/entity_pool.go index d135de2e..ce7558fa 100644 --- a/toolkit/internal/ecs/entity_pool.go +++ b/toolkit/internal/ecs/entity_pool.go @@ -1,6 +1,6 @@ package ecs -import "github.com/kercylan98/minotaur/utils/collection/listings" +import "github.com/kercylan98/minotaur/toolkit/collection/listings" type entityPool struct { entities *listings.PagedSlice[EntityId] // 所有的实体 diff --git a/toolkit/internal/ecs/world_test.go b/toolkit/internal/ecs/world_test.go index 9e836eb5..a6ff61ba 100644 --- a/toolkit/internal/ecs/world_test.go +++ b/toolkit/internal/ecs/world_test.go @@ -2,7 +2,7 @@ package ecs import ( "fmt" - "github.com/kercylan98/minotaur/utils/super" + "github.com/kercylan98/minotaur/toolkit" "testing" ) @@ -27,5 +27,5 @@ func TestWorld_AddComponent(t *testing.T) { t.Log(QueryComponent[Position](&w, e)) t.Log(QueryComponent[Velocity](&w, e)) - fmt.Println(string(super.MarshalIndentJSON(NewStatus(&w), "", " "))) + fmt.Println(string(toolkit.MarshalIndentJSON(NewStatus(&w), "", " "))) } diff --git a/toolkit/log/defines.go b/toolkit/log/defines.go index 445a863e..e6cda461 100644 --- a/toolkit/log/defines.go +++ b/toolkit/log/defines.go @@ -32,11 +32,11 @@ const ( ) const ( - levelNone Level = slog.LevelDebug - 1 - LevelDebug Level = slog.LevelDebug - LevelInfo Level = slog.LevelInfo - LevelWarn Level = slog.LevelWarn - LevelError Level = slog.LevelError + levelNone = slog.LevelDebug - 1 + LevelDebug = slog.LevelDebug + LevelInfo = slog.LevelInfo + LevelWarn = slog.LevelWarn + LevelError = slog.LevelError ) var levels = []Level{LevelDebug, LevelInfo, LevelWarn, LevelError} diff --git a/toolkit/mask/dynamic_mask.go b/toolkit/mask/dynamic_mask.go index a6d83610..8982c885 100644 --- a/toolkit/mask/dynamic_mask.go +++ b/toolkit/mask/dynamic_mask.go @@ -1,8 +1,8 @@ package mask import ( + "github.com/kercylan98/minotaur/toolkit" "github.com/kercylan98/minotaur/toolkit/ident" - "github.com/kercylan98/minotaur/utils/super" "strconv" "strings" "unsafe" @@ -190,12 +190,12 @@ func (m *DynamicMask) StringIdentical() string { func (m *DynamicMask) MarshalJSON() ([]byte, error) { slice := (*[1 << 30]uint64)(m.data)[:m.length] - return super.MarshalJSONE(slice) + return toolkit.MarshalJSONE(slice) } func (m *DynamicMask) UnmarshalJSON(data []byte) error { var slice []uint64 - err := super.UnmarshalJSON(data, &slice) + err := toolkit.UnmarshalJSONE(data, &slice) if err != nil { return err } diff --git a/toolkit/nexus/brokers/independent_goroutine.go b/toolkit/nexus/brokers/independent_goroutine.go new file mode 100644 index 00000000..60bec611 --- /dev/null +++ b/toolkit/nexus/brokers/independent_goroutine.go @@ -0,0 +1,195 @@ +package brokers + +import ( + "fmt" + "github.com/kercylan98/minotaur/toolkit/constraints" + "github.com/kercylan98/minotaur/toolkit/nexus" + "sync" + "sync/atomic" +) + +const ( + independentGoroutineStatusNone = iota // 未运行 + independentGoroutineStatusRunning // 运行中 + independentGoroutineStatusClosing // 关闭中 + independentGoroutineStatusClosed // 已关闭 +) + +type ( + IndependentGoroutineBinder[T comparable] func(topic T) + IndependentGoroutineUnBinder[T comparable] func(topic T) + IndependentGoroutineMessageHandler func(handler nexus.EventExecutor) +) + +// NewIndependentGoroutine 创建一个 IndependentGoroutine,该 IndependentGoroutine 支持通过 queueFactory 指定队列工厂函数 +// - 为避免队列高频创建和销毁,创建该队列将返回一个绑定函数和解绑函数,当不再使用时,调用解绑函数,解绑函数会在队列为空时关闭队列 +func NewIndependentGoroutine[I constraints.Ordered, T comparable](queueFactory func(index int) nexus.Queue[I, T], handler IndependentGoroutineMessageHandler, options ...*IndependentGoroutineOptions[I, T]) (nexus.Broker[I, T], IndependentGoroutineBinder[T], IndependentGoroutineUnBinder[T]) { + i := &IndependentGoroutine[I, T]{ + opts: NewIndependentGoroutineOptions[I, T]().Apply(options...), + queues: make(map[T]nexus.Queue[I, T]), + queueFactory: queueFactory, + bindCounter: make(map[T]int), + handler: handler, + closed: make(chan struct{}), + } + + return i, i.bind, i.unBind +} + +// IndependentGoroutine 每个队列都使用独立的 goroutine 来处理消息 +type IndependentGoroutine[I constraints.Ordered, T comparable] struct { + state int32 // 状态 + closed chan struct{} // 关闭信号 + opts *IndependentGoroutineOptions[I, T] + + guid int // 队列唯一标识 + queues map[T]nexus.Queue[I, T] // 所有使用的队列 + queueRW sync.RWMutex // 队列读写锁 + queueFactory func(index int) nexus.Queue[I, T] // 队列工厂函数 + bindCounter map[T]int // 绑定计数器 + handler IndependentGoroutineMessageHandler // 消息处理器 +} + +func (i *IndependentGoroutine[I, T]) bind(topic T) { + i.queueRW.Lock() + curr := i.bindCounter[topic] + 1 + i.bindCounter[topic] = curr + i.queueRW.Unlock() + + if i.opts.queueBindCounterChangedHook != nil { + i.opts.queueBindCounterChangedHook(topic, curr) + } +} + +func (i *IndependentGoroutine[I, T]) unBind(topic T) { + i.queueRW.Lock() + curr := i.bindCounter[topic] - 1 + if curr <= 0 { + queue, exist := i.queues[topic] + delete(i.bindCounter, topic) + delete(i.queues, topic) + if exist { + // 尝试关闭 + queue.Close() + if i.opts.queueClosedHook != nil { + i.opts.queueClosedHook(topic, queue, len(i.queues)) + } + } + + } else { + i.bindCounter[topic] = curr + } + i.queueRW.Unlock() + + if i.opts.queueBindCounterChangedHook != nil { + i.opts.queueBindCounterChangedHook(topic, curr) + } +} + +func (i *IndependentGoroutine[I, T]) runQueue(topic T, queue nexus.Queue[I, T], num int) { + go queue.Run() + if i.opts.queueCreatedHook != nil { + i.opts.queueCreatedHook(topic, queue, num) + } + for h := range queue.Consume() { + h.Exec( + // onProcess + func(topic T, event nexus.EventExecutor) { + i.handler(event) + }, + // onFinish + func(topic T, last bool) { + if !last { + return + } + // 为最后一条消息时,检查队列绑定计数器,如果为 0 则关闭队列 + i.queueRW.Lock() + defer i.queueRW.Unlock() + if i.bindCounter[topic] <= 0 && i.queues[topic] != nil { // 防止重复关闭 + queue.Close() + delete(i.queues, topic) + if i.opts.queueClosedHook != nil { + i.opts.queueClosedHook(topic, queue, len(i.queues)) + } + } + }, + ) + } +} + +func (i *IndependentGoroutine[I, T]) Run() { + if !atomic.CompareAndSwapInt32(&i.state, independentGoroutineStatusNone, independentGoroutineStatusRunning) { + return + } + + <-i.closed +} + +func (i *IndependentGoroutine[I, T]) Close() { + if !atomic.CompareAndSwapInt32(&i.state, independentGoroutineStatusRunning, independentGoroutineStatusClosing) { + return + } + + // 由于关闭中也可以产生新队列,关闭时需多轮检查 + defer close(i.closed) + for { + var wg = new(sync.WaitGroup) + i.queueRW.RLock() + if len(i.queues) == 0 { + atomic.StoreInt32(&i.state, independentGoroutineStatusClosed) + i.queueRW.RUnlock() + break + } + + // 向所有队列发送关闭信号,异步等待关闭,释放锁,避免新消息无法进入 + for key, queue := range i.queues { + count := i.bindCounter[key] + if count > 0 { + continue + } + + wg.Add(1) + go func(wg *sync.WaitGroup, queue nexus.Queue[I, T]) { + defer wg.Done() + queue.Close() + + i.queueRW.Lock() + defer i.queueRW.Unlock() + + delete(i.queues, key) + if i.opts.queueClosedHook != nil { + i.opts.queueClosedHook(key, queue, len(i.queues)) + } + }(wg, queue) + } + + i.queueRW.RUnlock() + + // 等待本轮关闭进入下一轮 + wg.Wait() + } +} + +func (i *IndependentGoroutine[I, T]) Publish(topic T, event nexus.Event[I, T]) error { + if atomic.LoadInt32(&i.state) > independentGoroutineStatusClosing { + return fmt.Errorf("broker closed") + } + + i.queueRW.RLock() + queue, exist := i.queues[topic] + i.queueRW.RUnlock() + if !exist { + // 双重检查确保锁粒度最小 + i.queueRW.Lock() + if queue, exist = i.queues[topic]; !exist { + // 创建新队列 + i.guid++ + queue = i.queueFactory(i.guid) + go i.runQueue(topic, queue, len(i.queues)+1) + i.queues[topic] = queue + } + i.queueRW.Unlock() + } + + return queue.Publish(topic, event) +} diff --git a/toolkit/nexus/brokers/independent_goroutine_options.go b/toolkit/nexus/brokers/independent_goroutine_options.go new file mode 100644 index 00000000..08c8d76e --- /dev/null +++ b/toolkit/nexus/brokers/independent_goroutine_options.go @@ -0,0 +1,49 @@ +package brokers + +import ( + "github.com/kercylan98/minotaur/toolkit/constraints" + "github.com/kercylan98/minotaur/toolkit/nexus" +) + +func NewIndependentGoroutineOptions[I constraints.Ordered, T comparable]() *IndependentGoroutineOptions[I, T] { + return &IndependentGoroutineOptions[I, T]{ + queueCreatedHook: nil, + queueClosedHook: nil, + queueBindCounterChangedHook: nil, + } +} + +type IndependentGoroutineOptions[I constraints.Ordered, T comparable] struct { + queueCreatedHook func(topic T, queue nexus.Queue[I, T], queueNum int) // 队列创建回调 + queueClosedHook func(topic T, queue nexus.Queue[I, T], queueNum int) // 队列关闭回调 + queueBindCounterChangedHook func(topic T, count int) // 队列绑定计数变更回调 +} + +// Apply 应用配置 +func (i *IndependentGoroutineOptions[I, T]) Apply(options ...*IndependentGoroutineOptions[I, T]) *IndependentGoroutineOptions[I, T] { + for _, o := range options { + i.queueCreatedHook = o.queueCreatedHook + i.queueClosedHook = o.queueClosedHook + i.queueBindCounterChangedHook = o.queueBindCounterChangedHook + } + + return i +} + +// WithQueueCreatedHook 设置队列创建回调 +func (i *IndependentGoroutineOptions[I, T]) WithQueueCreatedHook(hook func(topic T, queue nexus.Queue[I, T], queueNum int)) *IndependentGoroutineOptions[I, T] { + i.queueCreatedHook = hook + return i +} + +// WithQueueClosedHook 设置队列关闭回调 +func (i *IndependentGoroutineOptions[I, T]) WithQueueClosedHook(hook func(topic T, queue nexus.Queue[I, T], queueNum int)) *IndependentGoroutineOptions[I, T] { + i.queueClosedHook = hook + return i +} + +// WithQueueBindCounterChangedHook 设置队列绑定计数变更回调 +func (i *IndependentGoroutineOptions[I, T]) WithQueueBindCounterChangedHook(hook func(topic T, count int)) *IndependentGoroutineOptions[I, T] { + i.queueBindCounterChangedHook = hook + return i +} diff --git a/toolkit/nexus/brokers/independent_goroutine_test.go b/toolkit/nexus/brokers/independent_goroutine_test.go new file mode 100644 index 00000000..e401de71 --- /dev/null +++ b/toolkit/nexus/brokers/independent_goroutine_test.go @@ -0,0 +1,135 @@ +package brokers_test + +import ( + "context" + "github.com/kercylan98/minotaur/toolkit/nexus" + "github.com/kercylan98/minotaur/toolkit/nexus/brokers" + "github.com/kercylan98/minotaur/toolkit/nexus/events" + "github.com/kercylan98/minotaur/toolkit/nexus/queues" + "os" + "testing" + "time" +) + +func TestIndependentGoroutine_NotBindAndUnBind(t *testing.T) { + ig, _, _ := brokers.NewIndependentGoroutine[int, string]( + func(index int) nexus.Queue[int, string] { + return queues.NewNonBlockingRW[int, string](index, 1024, 1024) + }, func(handler nexus.EventExecutor) { + handler.Exec() + }, + brokers.NewIndependentGoroutineOptions[int, string](). + WithQueueCreatedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue created", topic, "queue num", queueNum) + }). + WithQueueClosedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue closed", topic, "queue num", queueNum) + }). + WithQueueBindCounterChangedHook(func(topic string, count int) { + t.Log("queue bind counter changed", topic, count) + }), + ) + + // 没有使用 bind 和 unBind 的情况下,每一个消息执行完成后且没有消息时,队列会自动关闭 + + go func() { + time.Sleep(time.Second) + if err := ig.Publish("test", events.Synchronous[int, string](func(ctx context.Context) { + t.Log("test") + })); err != nil { + panic(err) + } + + ig.Close() + }() + + ig.Run() + + t.Log("done") +} + +func TestIndependentGoroutine_BindButNotUnBind(t *testing.T) { + ig, bind, _ := brokers.NewIndependentGoroutine[int, string]( + func(index int) nexus.Queue[int, string] { + return queues.NewNonBlockingRW[int, string](index, 1024, 1024) + }, func(handler nexus.EventExecutor) { + handler.Exec() + }, + brokers.NewIndependentGoroutineOptions[int, string](). + WithQueueCreatedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue created", topic, "queue num", queueNum) + }). + WithQueueClosedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue closed", topic, "queue num", queueNum) + }). + WithQueueBindCounterChangedHook(func(topic string, count int) { + t.Log("queue bind counter changed", topic, count) + }), + ) + + // 使用 bind 但是没有使用 unBind 的情况下,每一个消息执行完成后且没有消息时,队列不会自动关闭,由于关闭 broker 时会等待所有队列关闭,所以会一直阻塞 + bind("test") + go func() { + time.Sleep(time.Second) + if err := ig.Publish("test", events.Synchronous[int, string](func(ctx context.Context) { + t.Log("test") + })); err != nil { + panic(err) + } + + go func() { + time.Sleep(time.Second * 3) + t.Log("timeout, exit") + os.Exit(0) + }() + ig.Close() + }() + + ig.Run() + + t.Fatal("not should be here") +} + +func TestIndependentGoroutine_BindAndUnBind(t *testing.T) { + ig, bind, unBind := brokers.NewIndependentGoroutine[int, string]( + func(index int) nexus.Queue[int, string] { + return queues.NewNonBlockingRW[int, string](index, 1024, 1024) + }, func(handler nexus.EventExecutor) { + handler.Exec() + }, + brokers.NewIndependentGoroutineOptions[int, string](). + WithQueueCreatedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue created", topic, "queue num", queueNum, queue.GetId()) + }). + WithQueueClosedHook(func(topic string, queue nexus.Queue[int, string], queueNum int) { + t.Log("queue closed", topic, "queue num", queueNum, queue.GetId()) + }). + WithQueueBindCounterChangedHook(func(topic string, count int) { + t.Log("queue bind counter changed", topic, count) + }), + ) + + // 使用 bind 和 unBind 的情况下,每一个消息执行完成后且没有消息时,队列会自动关闭 + bind("test") + go func() { + time.Sleep(time.Second) + if err := ig.Publish("test", events.Synchronous[int, string](func(ctx context.Context) { + })); err != nil { + panic(err) + } + + unBind("test") + + time.Sleep(time.Second) + if err := ig.Publish("test", events.Synchronous[int, string](func(ctx context.Context) { + })); err != nil { + panic(err) + } + + ig.Close() + }() + + ig.Run() + + t.Log("done") +} diff --git a/toolkit/nexus/brokers/sparse_goroutine.go b/toolkit/nexus/brokers/sparse_goroutine.go index b4621d95..a98224ac 100644 --- a/toolkit/nexus/brokers/sparse_goroutine.go +++ b/toolkit/nexus/brokers/sparse_goroutine.go @@ -126,7 +126,7 @@ func (s *SparseGoroutine[I, T]) Publish(topic T, event nexus.Event[I, T]) (err e s.queueRW.RLock() if atomic.LoadInt32(&s.state) > sparseGoroutineStatusClosing { s.queueRW.RUnlock() - return fmt.Errorf("broker closing or closed") + return fmt.Errorf("broker closed") } var next nexus.Queue[I, T] diff --git a/toolkit/nexus/events/asynchronous.go b/toolkit/nexus/events/asynchronous.go index e7bc76af..15999fa7 100644 --- a/toolkit/nexus/events/asynchronous.go +++ b/toolkit/nexus/events/asynchronous.go @@ -126,7 +126,8 @@ func (s *asynchronous[I, T]) OnProcess(topic T, queue nexus.Queue[I, T], startAt } } - s.broker.Publish(topic, Synchronous[I, T]( + // 忽略该错误,错误由于消息队列已关闭而导致,消息队列关闭时会等候所有消息处理完成,异步消息由于额外的占用计数,未执行完毕消息队列不会关闭,因此不应出现该错误 + _ = s.broker.Publish(topic, Synchronous[I, T]( func(ctx context.Context) { if s.callback != nil { s.callback(ctx, err) diff --git a/toolkit/nexus/queue.go b/toolkit/nexus/queue.go index 753baa6a..6316b5e1 100644 --- a/toolkit/nexus/queue.go +++ b/toolkit/nexus/queue.go @@ -16,7 +16,7 @@ type Queue[I constraints.Ordered, T comparable] interface { Run() // Consume 消费消息 Consume() <-chan EventInfo[I, T] - // Close 关闭队列 + // Close 关闭队列,关闭后依旧持续接收消息,待所有消息处理完毕后关闭,整个过程为同步的 Close() balancer.Item[I] diff --git a/toolkit/nexus/queues/non_blocking_rw.go b/toolkit/nexus/queues/non_blocking_rw.go index bc0e2a3f..fa100434 100644 --- a/toolkit/nexus/queues/non_blocking_rw.go +++ b/toolkit/nexus/queues/non_blocking_rw.go @@ -89,10 +89,10 @@ func (n *NonBlockingRW[I, T]) Run() { if n.buf.IsEmpty() { // 当队列为空时检查是否需要关闭队列,如果不需要关闭则等待新消息 if atomic.LoadInt32(&n.status) >= NonBlockingRWStatusClosing && n.total == 0 { - n.cond.L.Unlock() atomic.StoreInt32(&n.status, NonBlockingRWStatusClosed) close(n.c) close(n.cs) + n.cond.L.Unlock() return } n.cond.Wait() @@ -154,11 +154,11 @@ func (n *NonBlockingRW[I, T]) Publish(topic T, event nexus.Event[I, T]) error { } else { delete(n.topics, topic) } + n.cond.L.Unlock() if finisher != nil { finisher(topic, curr == 0) } n.cond.Signal() - n.cond.L.Unlock() }() handler(topic, func() { diff --git a/toolkit/random/probabillity_test.go b/toolkit/random/probabillity_test.go index 243c100d..1515a49f 100644 --- a/toolkit/random/probabillity_test.go +++ b/toolkit/random/probabillity_test.go @@ -1,7 +1,7 @@ package random_test import ( - "github.com/kercylan98/minotaur/utils/random" + "github.com/kercylan98/minotaur/toolkit/random" "testing" ) diff --git a/toolkit/ranking/binary_search.go b/toolkit/ranking/binary_search.go index 013c360d..4c85bf05 100644 --- a/toolkit/ranking/binary_search.go +++ b/toolkit/ranking/binary_search.go @@ -2,12 +2,12 @@ package ranking import ( "encoding/json" - "github.com/kercylan98/minotaur/utils/collection/mappings" - "github.com/kercylan98/minotaur/utils/generic" + "github.com/kercylan98/minotaur/toolkit/collection/mappings" + "github.com/kercylan98/minotaur/toolkit/constraints" ) // NewBinarySearch 创建一个基于内存的二分查找排行榜 -func NewBinarySearch[CompetitorID comparable, Score generic.Ordered](options ...BinarySearchOption[CompetitorID, Score]) *BinarySearch[CompetitorID, Score] { +func NewBinarySearch[CompetitorID comparable, Score constraints.Ordered](options ...BinarySearchOption[CompetitorID, Score]) *BinarySearch[CompetitorID, Score] { r := &BinarySearch[CompetitorID, Score]{ binarySearchEvent: new(binarySearchEvent[CompetitorID, Score]), rankCount: 100, @@ -19,7 +19,7 @@ func NewBinarySearch[CompetitorID comparable, Score generic.Ordered](options ... return r } -type BinarySearch[CompetitorID comparable, Score generic.Ordered] struct { +type BinarySearch[CompetitorID comparable, Score constraints.Ordered] struct { *binarySearchEvent[CompetitorID, Score] asc bool rankCount int @@ -30,7 +30,7 @@ type BinarySearch[CompetitorID comparable, Score generic.Ordered] struct { rankClearBeforeEventHandles []BinarySearchRankClearBeforeEventHandle[CompetitorID, Score] } -type scoreItem[CompetitorID comparable, Score generic.Ordered] struct { +type scoreItem[CompetitorID comparable, Score constraints.Ordered] struct { CompetitorId CompetitorID `json:"competitor_id,omitempty"` Score Score `json:"score,omitempty"` } diff --git a/toolkit/ranking/binary_search_events.go b/toolkit/ranking/binary_search_events.go index a5c51e5a..be7b3ecd 100644 --- a/toolkit/ranking/binary_search_events.go +++ b/toolkit/ranking/binary_search_events.go @@ -1,13 +1,13 @@ package ranking -import "github.com/kercylan98/minotaur/utils/generic" +import "github.com/kercylan98/minotaur/toolkit/constraints" type ( - BinarySearchRankChangeEventHandle[CompetitorID comparable, Score generic.Ordered] func(ranking *BinarySearch[CompetitorID, Score], competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score) - BinarySearchRankClearBeforeEventHandle[CompetitorID comparable, Score generic.Ordered] func(ranking *BinarySearch[CompetitorID, Score]) + BinarySearchRankChangeEventHandle[CompetitorID comparable, Score constraints.Ordered] func(ranking *BinarySearch[CompetitorID, Score], competitorId CompetitorID, oldRank, newRank int, oldScore, newScore Score) + BinarySearchRankClearBeforeEventHandle[CompetitorID comparable, Score constraints.Ordered] func(ranking *BinarySearch[CompetitorID, Score]) ) -type binarySearchEvent[CompetitorID comparable, Score generic.Ordered] struct { +type binarySearchEvent[CompetitorID comparable, Score constraints.Ordered] struct { rankChangeEventHandles []BinarySearchRankChangeEventHandle[CompetitorID, Score] rankClearBeforeEventHandles []BinarySearchRankClearBeforeEventHandle[CompetitorID, Score] } diff --git a/toolkit/ranking/binary_search_options.go b/toolkit/ranking/binary_search_options.go index 1cbbc365..9fc6c081 100644 --- a/toolkit/ranking/binary_search_options.go +++ b/toolkit/ranking/binary_search_options.go @@ -1,12 +1,12 @@ package ranking -import "github.com/kercylan98/minotaur/utils/generic" +import "github.com/kercylan98/minotaur/toolkit/constraints" -type BinarySearchOption[CompetitorID comparable, Score generic.Ordered] func(list *BinarySearch[CompetitorID, Score]) +type BinarySearchOption[CompetitorID comparable, Score constraints.Ordered] func(list *BinarySearch[CompetitorID, Score]) // WithBinarySearchCount 通过限制排行榜竞争者数量来创建排行榜 // - 默认情况下允许100位竞争者 -func WithBinarySearchCount[CompetitorID comparable, Score generic.Ordered](rankCount int) BinarySearchOption[CompetitorID, Score] { +func WithBinarySearchCount[CompetitorID comparable, Score constraints.Ordered](rankCount int) BinarySearchOption[CompetitorID, Score] { return func(bs *BinarySearch[CompetitorID, Score]) { if rankCount <= 0 { rankCount = 1 @@ -17,7 +17,7 @@ func WithBinarySearchCount[CompetitorID comparable, Score generic.Ordered](rankC // WithBinarySearchASC 通过升序的方式创建排行榜 // - 默认情况下为降序 -func WithBinarySearchASC[CompetitorID comparable, Score generic.Ordered]() BinarySearchOption[CompetitorID, Score] { +func WithBinarySearchASC[CompetitorID comparable, Score constraints.Ordered]() BinarySearchOption[CompetitorID, Score] { return func(bs *BinarySearch[CompetitorID, Score]) { bs.asc = true }