mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-29 06:49:19 +08:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a13017665 | |||
| e4f3e34249 | |||
| 6ffcfbe68e | |||
| b1415473ff | |||
| ba190fde13 | |||
| 088b143300 | |||
| 9cd8fb2b01 |
+2
-2
@@ -171,7 +171,7 @@ linters-settings:
|
||||
# exclude_godoc_examples: false
|
||||
funlen:
|
||||
lines: 150
|
||||
statements: 50
|
||||
statements: 80
|
||||
gci:
|
||||
# put imports beginning with prefix after 3rd-party packages;
|
||||
# only support one prefix
|
||||
@@ -510,7 +510,7 @@ linters-settings:
|
||||
|
||||
nestif:
|
||||
# minimal complexity of if statements to report, 5 by default
|
||||
min-complexity: 4
|
||||
min-complexity: 6
|
||||
|
||||
nilnil:
|
||||
# By default, nilnil checks all returned types below.
|
||||
|
||||
@@ -26,13 +26,13 @@ import (
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/internal/api"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||
)
|
||||
|
||||
|
||||
func main() {
|
||||
apiCmd := cmd.NewApiCmd()
|
||||
apiCmd.AddPortFlag()
|
||||
|
||||
@@ -25,7 +25,7 @@ require (
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.mongodb.org/mongo-driver v1.12.1
|
||||
golang.org/x/image v0.13.0
|
||||
google.golang.org/api v0.147.0
|
||||
google.golang.org/api v0.148.0
|
||||
google.golang.org/grpc v1.59.0
|
||||
google.golang.org/protobuf v1.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@@ -37,7 +37,7 @@ require github.com/google/uuid v1.3.1
|
||||
|
||||
require (
|
||||
github.com/IBM/sarama v1.41.3
|
||||
github.com/OpenIMSDK/protocol v0.0.27
|
||||
github.com/OpenIMSDK/protocol v0.0.30
|
||||
github.com/OpenIMSDK/tools v0.0.14
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible
|
||||
github.com/go-redis/redis v6.15.9+incompatible
|
||||
@@ -128,7 +128,7 @@ require (
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -18,8 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
|
||||
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
|
||||
github.com/OpenIMSDK/protocol v0.0.27 h1:ee1Y6idLahgJrTHkgWPboKIvCT9zvf7jitavVpffpPw=
|
||||
github.com/OpenIMSDK/protocol v0.0.27/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/protocol v0.0.30 h1:MiHO6PyQMR9ojBHNnSFxCHLmsoE2xZqaiYj975JiZnM=
|
||||
github.com/OpenIMSDK/protocol v0.0.30/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.14 h1:WLof/+WxyPyRST+QkoTKubYCiV73uCLiL8pgnpH/yKQ=
|
||||
github.com/OpenIMSDK/tools v0.0.14/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||
@@ -44,21 +44,14 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583j
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y=
|
||||
github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs=
|
||||
github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=
|
||||
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
|
||||
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/cosiner/argv v0.1.0 h1:BVDiEL32lwHukgJKP87btEPenzrrHUjajs/8yzaqcXg=
|
||||
github.com/cosiner/argv v0.1.0/go.mod h1:EusR6TucWKX+zFgtdUsKT2Cvg45K5rtpCcWz4hK06d8=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
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=
|
||||
github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 h1:atN94qKNhLpy+9BwbE5nxvFj4rScJi6W3x/NfFmMDg4=
|
||||
github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4/go.mod h1:C7Es+DLenIpPc9J6IYw4jrK0h7S9bKj4DNl8+KxGEXU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
@@ -86,10 +79,6 @@ 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.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-delve/delve v1.21.1 h1:oDpED8gvXPLS1VKSYzaMH/ihZtyk04H9jqQ9xpyFXl0=
|
||||
github.com/go-delve/delve v1.21.1/go.mod h1:FgTAiRUe43RS5EexL06RPyMtP8AMZVL/t9Qqgy3qUe4=
|
||||
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d h1:pxjSLshkZJGLVm0wv20f/H0oTWiq/egkoJQ2ja6LEvo=
|
||||
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d/go.mod h1:biJCRbqp51wS+I92HMqn5H8/A0PAhxn2vyOT+JqhiGI=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
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=
|
||||
@@ -139,13 +128,10 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/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-dap v0.9.1 h1:d8dETjgHMR9/xs+Xza+NrZmB7jxIS5OtM2uRsyJVA/c=
|
||||
github.com/google/go-dap v0.9.1/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
@@ -175,8 +161,6 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@@ -223,13 +207,8 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5nwm/V115vj2YXfhS0w=
|
||||
github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w=
|
||||
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
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-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
@@ -288,14 +267,11 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg=
|
||||
github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
@@ -340,8 +316,6 @@ go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecq
|
||||
go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.starlark.net v0.0.0-20220816155156-cfacd8902214 h1:MqijAN3S61c7KWasOk+zIqIjHQPN6WUra/X3+YAkQxQ=
|
||||
go.starlark.net v0.0.0-20220816155156-cfacd8902214/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
@@ -361,8 +335,6 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI=
|
||||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
|
||||
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -418,12 +390,10 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/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-20220715151400-c0bba94af5f8/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-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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
@@ -458,8 +428,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.147.0 h1:Can3FaQo9LlVqxJCodNmeZW/ib3/qKAY3rFeXiHo5gc=
|
||||
google.golang.org/api v0.147.0/go.mod h1:pQ/9j83DcmPd/5C9e2nFOdjjNkDZ1G+zkbK2uvdkJMs=
|
||||
google.golang.org/api v0.148.0 h1:HBq4TZlN4/1pNcu0geJZ/Q50vIwIXT532UIMYoo0vOs=
|
||||
google.golang.org/api v0.148.0/go.mod h1:8/TBgwaKjfqTdacOJrOv2+2Q6fBDU1uHKK06oGSkxzU=
|
||||
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/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
@@ -471,8 +441,8 @@ google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA
|
||||
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
|
||||
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=
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
go 1.19
|
||||
|
||||
|
||||
use (
|
||||
.
|
||||
./test/typecheck
|
||||
./tools/changelog
|
||||
./tools/component
|
||||
./tools/data-conversion
|
||||
./tools/imctl
|
||||
//./tools/imctl
|
||||
./tools/infra
|
||||
./tools/ncpu
|
||||
./tools/openim-web
|
||||
./tools/url2im
|
||||
./tools/versionchecker
|
||||
./tools/yamlfmt
|
||||
./tools/component
|
||||
./tools/url2im
|
||||
./tools/data-conversion
|
||||
)
|
||||
|
||||
+8
-24
@@ -57,6 +57,10 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg)
|
||||
var newContent string
|
||||
options := make(map[string]bool, 5)
|
||||
switch params.ContentType {
|
||||
case constant.OANotification:
|
||||
notification := sdkws.NotificationElem{}
|
||||
notification.Detail = utils.StructToJsonString(params.Content)
|
||||
newContent = utils.StructToJsonString(¬ification)
|
||||
case constant.Text:
|
||||
fallthrough
|
||||
case constant.Picture:
|
||||
@@ -69,10 +73,6 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg)
|
||||
fallthrough
|
||||
case constant.File:
|
||||
fallthrough
|
||||
case constant.CustomNotTriggerConversation:
|
||||
fallthrough
|
||||
case constant.CustomOnlineOnly:
|
||||
fallthrough
|
||||
default:
|
||||
newContent = utils.StructToJsonString(params.Content)
|
||||
}
|
||||
@@ -82,11 +82,6 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg)
|
||||
if params.NotOfflinePush {
|
||||
utils.SetSwitchFromOptions(options, constant.IsOfflinePush, false)
|
||||
}
|
||||
if params.ContentType == constant.CustomOnlineOnly {
|
||||
m.SetOptions(options, false)
|
||||
} else if params.ContentType == constant.CustomNotTriggerConversation {
|
||||
utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, false)
|
||||
}
|
||||
pbData := msg.SendMsgReq{
|
||||
MsgData: &sdkws.MsgData{
|
||||
SendID: params.SendID,
|
||||
@@ -105,14 +100,6 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg)
|
||||
OfflinePushInfo: params.OfflinePushInfo,
|
||||
},
|
||||
}
|
||||
//if params.ContentType == constant.OANotification {
|
||||
// var tips sdkws.TipsComm
|
||||
// tips.JsonDetail = utils.StructToJsonString(params.Content)
|
||||
// pbData.MsgData.Content, err = proto.Marshal(&tips)
|
||||
// if err != nil {
|
||||
// log.ZError(c, "Marshal failed ", err, "tips", tips.String())
|
||||
// }
|
||||
//}
|
||||
return &pbData
|
||||
}
|
||||
|
||||
@@ -180,15 +167,13 @@ func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendM
|
||||
data = apistruct.FileElem{}
|
||||
case constant.Custom:
|
||||
data = apistruct.CustomElem{}
|
||||
case constant.Revoke:
|
||||
data = apistruct.RevokeElem{}
|
||||
case constant.OANotification:
|
||||
data = apistruct.OANotificationElem{}
|
||||
req.SessionType = constant.NotificationChatType
|
||||
case constant.CustomNotTriggerConversation:
|
||||
data = apistruct.CustomElem{}
|
||||
case constant.CustomOnlineOnly:
|
||||
data = apistruct.CustomElem{}
|
||||
if !authverify.IsManagerUserID(req.SendID) {
|
||||
return nil, errs.ErrNoPermission.
|
||||
Wrap("only app manager can as sender send OANotificationElem")
|
||||
}
|
||||
default:
|
||||
return nil, errs.ErrArgs.WithDetail("not support err contentType")
|
||||
}
|
||||
@@ -212,7 +197,6 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||
return
|
||||
}
|
||||
|
||||
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
|
||||
if err != nil {
|
||||
log.ZError(c, "decodeData failed", err)
|
||||
|
||||
@@ -83,7 +83,6 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
||||
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
|
||||
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
|
||||
userRouterGroup.POST("/subscribe_users_status", ParseToken, u.SubscriberStatus)
|
||||
userRouterGroup.POST("/unsubscribe_users_status", ParseToken, u.UnSubscriberStatus)
|
||||
userRouterGroup.POST("/get_users_status", ParseToken, u.GetUserStatus)
|
||||
userRouterGroup.POST("/get_subscribe_users_status", ParseToken, u.GetSubscribeUsersStatus)
|
||||
}
|
||||
|
||||
@@ -190,11 +190,6 @@ func (u *UserApi) SubscriberStatus(c *gin.Context) {
|
||||
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
||||
}
|
||||
|
||||
// UnSubscriberStatus Unsubscribe a user's presence.
|
||||
func (u *UserApi) UnSubscriberStatus(c *gin.Context) {
|
||||
a2r.Call(user.UserClient.SubscribeOrCancelUsersStatus, u.Client, c)
|
||||
}
|
||||
|
||||
// GetUserStatus Get the online status of the user.
|
||||
func (u *UserApi) GetUserStatus(c *gin.Context) {
|
||||
a2r.Call(user.UserClient.GetUserStatus, u.Client, c)
|
||||
|
||||
@@ -18,9 +18,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
// RunWsAndServer run ws server
|
||||
func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
||||
fmt.Println(
|
||||
"start rpc/msg_gateway server, port: ",
|
||||
@@ -42,7 +45,7 @@ func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
||||
go func() {
|
||||
err := hubServer.Start()
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
panic(utils.Wrap1(err))
|
||||
}
|
||||
}()
|
||||
return hubServer.LongConnServer.Run()
|
||||
|
||||
@@ -16,10 +16,12 @@ package msgtransfer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"sync"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
|
||||
"github.com/OpenIMSDK/tools/mw"
|
||||
|
||||
@@ -63,8 +65,7 @@ func StartTransfer(prometheusPort int) error {
|
||||
/*
|
||||
client, err := openkeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema,
|
||||
openkeeper.WithFreq(time.Hour), openkeeper.WithRoundRobin(), openkeeper.WithUserNameAndPassword(config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))*/
|
||||
if err != nil {
|
||||
config.Config.Zookeeper.Password), openkeeper.WithTimeout(10), openkeeper.WithLogger(log.NewZkLogger()))*/if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
||||
|
||||
@@ -283,20 +283,30 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(
|
||||
return
|
||||
}
|
||||
if isNewConversation {
|
||||
if storageList[0].SessionType == constant.SuperGroupChatType {
|
||||
log.ZInfo(ctx, "group chat first create conversation", "conversationID", conversationID)
|
||||
switch storageList[0].SessionType {
|
||||
case constant.SuperGroupChatType:
|
||||
log.ZInfo(ctx, "group chat first create conversation", "conversationID",
|
||||
conversationID)
|
||||
userIDs, err := och.groupRpcClient.GetGroupMemberIDs(ctx, storageList[0].GroupID)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "get group member ids error", err, "conversationID", conversationID)
|
||||
log.ZWarn(ctx, "get group member ids error", err, "conversationID",
|
||||
conversationID)
|
||||
} else {
|
||||
if err := och.conversationRpcClient.GroupChatFirstCreateConversation(ctx, storageList[0].GroupID, userIDs); err != nil {
|
||||
log.ZWarn(ctx, "single chat first create conversation error", err, "conversationID", conversationID)
|
||||
if err := och.conversationRpcClient.GroupChatFirstCreateConversation(ctx,
|
||||
storageList[0].GroupID, userIDs); err != nil {
|
||||
log.ZWarn(ctx, "single chat first create conversation error", err,
|
||||
"conversationID", conversationID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := och.conversationRpcClient.SingleChatFirstCreateConversation(ctx, storageList[0].RecvID, storageList[0].SendID); err != nil {
|
||||
log.ZWarn(ctx, "single chat first create conversation error", err, "conversationID", conversationID)
|
||||
case constant.SingleChatType, constant.NotificationChatType:
|
||||
if err := och.conversationRpcClient.SingleChatFirstCreateConversation(ctx, storageList[0].RecvID,
|
||||
storageList[0].SendID, conversationID, storageList[0].SessionType); err != nil {
|
||||
log.ZWarn(ctx, "single chat or notification first create conversation error", err,
|
||||
"conversationID", conversationID, "sessionType", storageList[0].SessionType)
|
||||
}
|
||||
default:
|
||||
log.ZWarn(ctx, "unknown session type", nil, "sessionType",
|
||||
storageList[0].SessionType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func (mc *OnlineHistoryMongoConsumerHandler) handleChatWs2Mongo(
|
||||
log.ZError(ctx, "msgFromMQ.MsgData is empty", nil, "cMsg", cMsg)
|
||||
return
|
||||
}
|
||||
log.ZInfo(ctx, "mongo consumer recv msg", "msgs", msgFromMQ.MsgData)
|
||||
log.ZInfo(ctx, "mongo consumer recv msg", "msgs", msgFromMQ.String())
|
||||
err = mc.msgDatabase.BatchInsertChat2DB(ctx, msgFromMQ.ConversationID, msgFromMQ.MsgData, msgFromMQ.LastSeq)
|
||||
if err != nil {
|
||||
log.ZError(
|
||||
|
||||
@@ -58,6 +58,7 @@ func (c *ConsumerHandler) handleMs2PsChat(ctx context.Context, msg []byte) {
|
||||
}
|
||||
sec := msgFromMQ.MsgData.SendTime / 1000
|
||||
nowSec := utils.GetCurrentTimestampBySecond()
|
||||
log.ZDebug(ctx, "push msg", "msg", pbData.String(), "sec", sec, "nowSec", nowSec)
|
||||
if nowSec-sec > 10 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -126,13 +126,12 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
||||
}
|
||||
|
||||
func (p *Pusher) UnmarshalNotificationElem(bytes []byte, t interface{}) error {
|
||||
var notificationElem struct {
|
||||
Detail string `json:"detail,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(bytes, ¬ificationElem); err != nil {
|
||||
var notification sdkws.NotificationElem
|
||||
if err := json.Unmarshal(bytes, ¬ification); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal([]byte(notificationElem.Detail), t)
|
||||
|
||||
return json.Unmarshal([]byte(notification.Detail), t)
|
||||
}
|
||||
|
||||
func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
|
||||
|
||||
@@ -17,8 +17,6 @@ package conversation
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
@@ -114,7 +112,10 @@ func (c *conversationServer) SetConversation(ctx context.Context, req *pbconvers
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c *conversationServer) SetConversations(ctx context.Context, req *pbconversation.SetConversationsReq) (*pbconversation.SetConversationsResp, error) {
|
||||
//nolint
|
||||
func (c *conversationServer) SetConversations(ctx context.Context,
|
||||
req *pbconversation.SetConversationsReq,
|
||||
) (*pbconversation.SetConversationsResp, error) {
|
||||
if req.Conversation == nil {
|
||||
return nil, errs.ErrArgs.Wrap("conversation must not be nil")
|
||||
}
|
||||
@@ -124,14 +125,8 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
|
||||
return nil, err
|
||||
}
|
||||
if groupInfo.Status == constant.GroupStatusDismissed {
|
||||
return nil, err
|
||||
return nil, errs.ErrDismissedAlready.Wrap("group dismissed")
|
||||
}
|
||||
// for _, userID := range req.UserIDs {
|
||||
// if _, err := c.groupRpcClient.GetGroupMemberCache(ctx, req.Conversation.GroupID, userID); err != nil {
|
||||
// log.ZError(ctx, "user not in group", err, "userID", userID, "groupID", req.Conversation.GroupID)
|
||||
// return nil, err
|
||||
// }
|
||||
// }
|
||||
}
|
||||
var unequal int
|
||||
var conv tablerelation.ConversationModel
|
||||
@@ -205,7 +200,14 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
|
||||
return nil, err
|
||||
}
|
||||
for _, userID := range req.UserIDs {
|
||||
c.conversationNotificationSender.ConversationSetPrivateNotification(ctx, userID, req.Conversation.UserID, req.Conversation.IsPrivateChat.Value, req.Conversation.ConversationID)
|
||||
err := c.conversationNotificationSender.ConversationSetPrivateNotification(ctx, userID, req.Conversation.UserID,
|
||||
req.Conversation.IsPrivateChat.Value, req.Conversation.ConversationID)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "send conversation set private notification failed", err,
|
||||
"userID", userID, "conversationID", req.Conversation.ConversationID)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if req.Conversation.BurnDuration != nil {
|
||||
@@ -235,24 +237,40 @@ func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req
|
||||
}
|
||||
|
||||
// create conversation without notification for msg redis transfer.
|
||||
func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, req *pbconversation.CreateSingleChatConversationsReq) (*pbconversation.CreateSingleChatConversationsResp, error) {
|
||||
var conversation tablerelation.ConversationModel
|
||||
conversation.ConversationID = msgprocessor.GetConversationIDBySessionType(constant.SingleChatType, req.RecvID, req.SendID)
|
||||
conversation.ConversationType = constant.SingleChatType
|
||||
conversation.OwnerUserID = req.SendID
|
||||
conversation.UserID = req.RecvID
|
||||
err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "create conversation failed", err, "conversation", conversation)
|
||||
func (c *conversationServer) CreateSingleChatConversations(ctx context.Context,
|
||||
req *pbconversation.CreateSingleChatConversationsReq,
|
||||
) (*pbconversation.CreateSingleChatConversationsResp, error) {
|
||||
switch req.ConversationType {
|
||||
case constant.SingleChatType:
|
||||
var conversation tablerelation.ConversationModel
|
||||
conversation.ConversationID = req.ConversationID
|
||||
conversation.ConversationType = req.ConversationType
|
||||
conversation.OwnerUserID = req.SendID
|
||||
conversation.UserID = req.RecvID
|
||||
err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "create conversation failed", err, "conversation", conversation)
|
||||
}
|
||||
|
||||
conversation2 := conversation
|
||||
conversation2.OwnerUserID = req.RecvID
|
||||
conversation2.UserID = req.SendID
|
||||
err = c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation2})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation)
|
||||
}
|
||||
case constant.NotificationChatType:
|
||||
var conversation tablerelation.ConversationModel
|
||||
conversation.ConversationID = req.ConversationID
|
||||
conversation.ConversationType = req.ConversationType
|
||||
conversation.OwnerUserID = req.RecvID
|
||||
conversation.UserID = req.SendID
|
||||
err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation)
|
||||
}
|
||||
}
|
||||
|
||||
conversation2 := conversation
|
||||
conversation2.OwnerUserID = req.RecvID
|
||||
conversation2.UserID = req.SendID
|
||||
err = c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation2})
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation)
|
||||
}
|
||||
return &pbconversation.CreateSingleChatConversationsResp{}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -252,7 +252,8 @@ func (s *friendServer) GetDesignatedFriends(
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, req *pbfriend.GetDesignatedFriendsApplyReq) (resp *pbfriend.GetDesignatedFriendsApplyResp, err error) {
|
||||
func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context,
|
||||
req *pbfriend.GetDesignatedFriendsApplyReq) (resp *pbfriend.GetDesignatedFriendsApplyResp, err error) {
|
||||
friendRequests, err := s.friendDatabase.FindBothFriendRequests(ctx, req.FromUserID, req.ToUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+33
-18
@@ -154,16 +154,16 @@ func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *groupServer) GetUsernameMap(ctx context.Context, userIDs []string, complete bool) (map[string]string, error) {
|
||||
func (s *groupServer) GetPublicUserInfoMap(ctx context.Context, userIDs []string, complete bool) (map[string]*sdkws.PublicUserInfo, error) {
|
||||
if len(userIDs) == 0 {
|
||||
return map[string]string{}, nil
|
||||
return map[string]*sdkws.PublicUserInfo{}, nil
|
||||
}
|
||||
users, err := s.User.GetPublicUserInfos(ctx, userIDs, complete)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return utils.SliceToMapAny(users, func(e *sdkws.PublicUserInfo) (string, string) {
|
||||
return e.UserID, e.Nickname
|
||||
return utils.SliceToMapAny(users, func(e *sdkws.PublicUserInfo) (string, *sdkws.PublicUserInfo) {
|
||||
return e.UserID, e
|
||||
}), nil
|
||||
}
|
||||
|
||||
@@ -468,15 +468,18 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == ""
|
||||
publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == "" || e.FaceURL == ""
|
||||
}), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo {
|
||||
if e.Nickname == "" {
|
||||
e.Nickname = nameMap[e.UserID]
|
||||
e.Nickname = publicUserInfoMap[e.UserID].Nickname
|
||||
}
|
||||
if e.FaceURL == "" {
|
||||
e.FaceURL = publicUserInfoMap[e.UserID].FaceURL
|
||||
}
|
||||
return convert.Db2PbGroupMember(e)
|
||||
})
|
||||
@@ -616,15 +619,18 @@ func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == ""
|
||||
publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == "" || e.FaceURL == ""
|
||||
}), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo {
|
||||
if e.Nickname == "" {
|
||||
e.Nickname = nameMap[e.UserID]
|
||||
e.Nickname = publicUserInfoMap[e.UserID].Nickname
|
||||
}
|
||||
if e.FaceURL == "" {
|
||||
e.FaceURL = publicUserInfoMap[e.UserID].FaceURL
|
||||
}
|
||||
return convert.Db2PbGroupMember(e)
|
||||
})
|
||||
@@ -1067,15 +1073,18 @@ func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGr
|
||||
return nil, err
|
||||
}
|
||||
resp.Total = total
|
||||
nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == ""
|
||||
nameMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == "" || e.FaceURL == ""
|
||||
}), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo {
|
||||
if e.Nickname == "" {
|
||||
e.Nickname = nameMap[e.UserID]
|
||||
e.Nickname = nameMap[e.UserID].Nickname
|
||||
}
|
||||
if e.FaceURL == "" {
|
||||
e.FaceURL = nameMap[e.UserID].FaceURL
|
||||
}
|
||||
return convert.Db2PbGroupMember(e)
|
||||
})
|
||||
@@ -1461,7 +1470,7 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == ""
|
||||
}), true)
|
||||
if err != nil {
|
||||
@@ -1469,7 +1478,10 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge
|
||||
}
|
||||
resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo {
|
||||
if e.Nickname == "" {
|
||||
e.Nickname = nameMap[e.UserID]
|
||||
e.Nickname = publicUserInfoMap[e.UserID].Nickname
|
||||
}
|
||||
if e.FaceURL == "" {
|
||||
e.FaceURL = publicUserInfoMap[e.UserID].FaceURL
|
||||
}
|
||||
return convert.Db2PbGroupMember(e)
|
||||
})
|
||||
@@ -1494,15 +1506,18 @@ func (s *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nameMap, err := s.GetUsernameMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == ""
|
||||
publicUserInfoMap, err := s.GetPublicUserInfoMap(ctx, utils.Filter(members, func(e *relationtb.GroupMemberModel) (string, bool) {
|
||||
return e.UserID, e.Nickname == "" || e.FaceURL == ""
|
||||
}), true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Members = utils.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo {
|
||||
if e.Nickname == "" {
|
||||
e.Nickname = nameMap[e.UserID]
|
||||
e.Nickname = publicUserInfoMap[e.UserID].Nickname
|
||||
}
|
||||
if e.FaceURL == "" {
|
||||
e.FaceURL = publicUserInfoMap[e.UserID].FaceURL
|
||||
}
|
||||
return convert.Db2PbGroupMember(e)
|
||||
})
|
||||
|
||||
@@ -147,7 +147,6 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
for i := hasReadSeq + 1; i <= req.HasReadSeq; i++ {
|
||||
seqs = append(seqs, i)
|
||||
}
|
||||
|
||||
if len(seqs) > 0 {
|
||||
log.ZDebug(ctx, "MarkConversationAsRead", "seqs", seqs, "conversationID", req.ConversationID)
|
||||
if err = m.MsgDatabase.MarkSingleChatMsgsAsRead(ctx, req.UserID, req.ConversationID, seqs); err != nil {
|
||||
@@ -166,7 +165,8 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if conversation.ConversationType == constant.SuperGroupChatType {
|
||||
} else if conversation.ConversationType == constant.SuperGroupChatType ||
|
||||
conversation.ConversationType == constant.NotificationChatType {
|
||||
if req.HasReadSeq > hasReadSeq {
|
||||
err = m.MsgDatabase.SetHasReadSeq(ctx, req.UserID, req.ConversationID, req.HasReadSeq)
|
||||
if err != nil {
|
||||
@@ -178,7 +178,6 @@ func (m *msgServer) MarkConversationAsRead(
|
||||
req.UserID, seqs, hasReadSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return &msg.MarkConversationAsReadResp{}, nil
|
||||
|
||||
@@ -290,7 +290,8 @@ func (s *userServer) SubscribeOrCancelUsersStatus(ctx context.Context, req *pbus
|
||||
|
||||
// GetUserStatus Get the online status of the user.
|
||||
func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatusReq) (resp *pbuser.GetUserStatusResp,
|
||||
err error) {
|
||||
err error,
|
||||
) {
|
||||
onlineStatusList, err := s.UserDatabase.GetUserStatus(ctx, req.UserIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -300,7 +301,8 @@ func (s *userServer) GetUserStatus(ctx context.Context, req *pbuser.GetUserStatu
|
||||
|
||||
// SetUserStatus Synchronize user's online status.
|
||||
func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatusReq) (resp *pbuser.SetUserStatusResp,
|
||||
err error) {
|
||||
err error,
|
||||
) {
|
||||
err = s.UserDatabase.SetUserStatus(ctx, req.UserID, req.Status, req.PlatformID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -324,7 +326,8 @@ func (s *userServer) SetUserStatus(ctx context.Context, req *pbuser.SetUserStatu
|
||||
|
||||
// GetSubscribeUsersStatus Get the online status of subscribers.
|
||||
func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
|
||||
req *pbuser.GetSubscribeUsersStatusReq) (*pbuser.GetSubscribeUsersStatusResp, error) {
|
||||
req *pbuser.GetSubscribeUsersStatusReq,
|
||||
) (*pbuser.GetSubscribeUsersStatusResp, error) {
|
||||
userList, err := s.UserDatabase.GetAllSubscribeList(ctx, req.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -17,11 +17,13 @@ package tools
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
"math"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"math"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
@@ -41,7 +41,7 @@ type SendMsgReq struct {
|
||||
type BatchSendMsgReq struct {
|
||||
SendMsg
|
||||
IsSendAll bool `json:"isSendAll"`
|
||||
RecvIDs []string `json:"recvIDs"`
|
||||
RecvIDs []string `json:"recvIDs" binding:"required"`
|
||||
}
|
||||
|
||||
type BatchSendMsgResp struct {
|
||||
|
||||
@@ -41,6 +41,7 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
|
||||
if opUserID == ownerUserID {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errs.ErrNoPermission.Wrap(utils.GetSelfFuncName())
|
||||
}
|
||||
|
||||
@@ -52,6 +53,7 @@ func CheckAdmin(ctx context.Context) error {
|
||||
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||
}
|
||||
|
||||
@@ -74,5 +76,6 @@ func WsVerifyToken(token, userID string, platformID int) error {
|
||||
if claim.PlatformID != platformID {
|
||||
return errs.ErrTokenInvalid.Wrap(fmt.Sprintf("token platform %d != %d", claim.PlatformID, platformID))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ func (c CommonCallbackResp) Parse() error {
|
||||
if c.ActionCode != errs.NoError || c.ErrCode != errs.NoError {
|
||||
return errs.NewCodeError(int(c.ErrCode), c.ErrMsg).WithDetail(c.ErrDlt)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
type ApiCmd struct {
|
||||
@@ -42,8 +44,7 @@ func (a *ApiCmd) GetPortFromConfig(portType string) int {
|
||||
fmt.Println("GetPortFromConfig:", portType)
|
||||
if portType == constant.FlagPort {
|
||||
return config2.Config.Api.OpenImApiPort[0]
|
||||
} else {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type CronTaskCmd struct {
|
||||
func NewCronTaskCmd() *CronTaskCmd {
|
||||
ret := &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
|
||||
ret.SetRootCmdPt(ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -34,5 +35,6 @@ func (c *CronTaskCmd) addRunE(f func() error) {
|
||||
|
||||
func (c *CronTaskCmd) Exec(f func() error) error {
|
||||
c.addRunE(f)
|
||||
|
||||
return c.Execute()
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ type MsgGatewayCmd struct {
|
||||
func NewMsgGatewayCmd() *MsgGatewayCmd {
|
||||
ret := &MsgGatewayCmd{NewRootCmd("msgGateway")}
|
||||
ret.SetRootCmdPt(ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -43,6 +44,7 @@ func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) int {
|
||||
if port == 0 {
|
||||
port = m.PortFromConfig(constant.FlagWsPort)
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
@@ -54,8 +56,10 @@ func (m *MsgGatewayCmd) addRunE() {
|
||||
|
||||
func (m *MsgGatewayCmd) Exec() error {
|
||||
m.addRunE()
|
||||
|
||||
return m.Execute()
|
||||
}
|
||||
|
||||
func (m *MsgGatewayCmd) GetPortFromConfig(portType string) int {
|
||||
if portType == constant.FlagWsPort {
|
||||
return config2.Config.LongConnSvr.OpenImWsPort[0]
|
||||
|
||||
@@ -27,6 +27,7 @@ type MsgTransferCmd struct {
|
||||
func NewMsgTransferCmd() *MsgTransferCmd {
|
||||
ret := &MsgTransferCmd{NewRootCmd("msgTransfer")}
|
||||
ret.SetRootCmdPt(ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -38,5 +39,6 @@ func (m *MsgTransferCmd) addRunE() {
|
||||
|
||||
func (m *MsgTransferCmd) Exec() error {
|
||||
m.addRunE()
|
||||
|
||||
return m.Execute()
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
type MsgUtilsCmd struct {
|
||||
cobra.Command
|
||||
msgTool *tools.MsgTool
|
||||
// msgTool *tools.MsgTool
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) AddUserIDFlag() {
|
||||
@@ -31,6 +31,7 @@ func (m *MsgUtilsCmd) AddUserIDFlag() {
|
||||
|
||||
func (m *MsgUtilsCmd) getUserIDFlag(cmdLines *cobra.Command) string {
|
||||
userID, _ := cmdLines.Flags().GetString("userID")
|
||||
|
||||
return userID
|
||||
}
|
||||
|
||||
@@ -38,26 +39,17 @@ func (m *MsgUtilsCmd) AddFixAllFlag() {
|
||||
m.Command.PersistentFlags().BoolP("fixAll", "f", false, "openIM fix all seqs")
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) getFixAllFlag(cmdLines *cobra.Command) bool {
|
||||
fixAll, _ := cmdLines.Flags().GetBool("fixAll")
|
||||
return fixAll
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) AddClearAllFlag() {
|
||||
m.Command.PersistentFlags().BoolP("clearAll", "c", false, "openIM clear all seqs")
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) getClearAllFlag(cmdLines *cobra.Command) bool {
|
||||
clearAll, _ := cmdLines.Flags().GetBool("clearAll")
|
||||
return clearAll
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) AddSuperGroupIDFlag() {
|
||||
m.Command.PersistentFlags().StringP("superGroupID", "g", "", "openIM superGroupID")
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) getSuperGroupIDFlag(cmdLines *cobra.Command) string {
|
||||
superGroupID, _ := cmdLines.Flags().GetString("superGroupID")
|
||||
|
||||
return superGroupID
|
||||
}
|
||||
|
||||
@@ -65,20 +57,10 @@ func (m *MsgUtilsCmd) AddBeginSeqFlag() {
|
||||
m.Command.PersistentFlags().Int64P("beginSeq", "b", 0, "openIM beginSeq")
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) getBeginSeqFlag(cmdLines *cobra.Command) int64 {
|
||||
beginSeq, _ := cmdLines.Flags().GetInt64("beginSeq")
|
||||
return beginSeq
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) AddLimitFlag() {
|
||||
m.Command.PersistentFlags().Int64P("limit", "l", 0, "openIM limit")
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) getLimitFlag(cmdLines *cobra.Command) int64 {
|
||||
limit, _ := cmdLines.Flags().GetInt64("limit")
|
||||
return limit
|
||||
}
|
||||
|
||||
func (m *MsgUtilsCmd) Execute() error {
|
||||
return m.Command.Execute()
|
||||
}
|
||||
@@ -131,6 +113,7 @@ func NewSeqCmd() *SeqCmd {
|
||||
seqCmd := &SeqCmd{
|
||||
NewMsgUtilsCmd("seq", "seq", nil),
|
||||
}
|
||||
|
||||
return seqCmd
|
||||
}
|
||||
|
||||
@@ -158,6 +141,7 @@ func (s *SeqCmd) GetSeqCmd() *cobra.Command {
|
||||
// println(seq)
|
||||
}
|
||||
}
|
||||
|
||||
return &s.Command
|
||||
}
|
||||
|
||||
@@ -173,6 +157,7 @@ func NewMsgCmd() *MsgCmd {
|
||||
msgCmd := &MsgCmd{
|
||||
NewMsgUtilsCmd("msg", "msg", nil),
|
||||
}
|
||||
|
||||
return msgCmd
|
||||
}
|
||||
|
||||
|
||||
+65
-41
@@ -17,12 +17,11 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
@@ -60,62 +59,81 @@ func NewRootCmd(name string, opts ...func(*CmdOpts)) *RootCmd {
|
||||
Short: fmt.Sprintf(`Start %s `, name),
|
||||
Long: fmt.Sprintf(`Start %s `, name),
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return rootCmd.persistentPreRun(cmd, opts...)
|
||||
if err := rootCmd.getConfFromCmdAndInit(cmd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cmdOpts := &CmdOpts{}
|
||||
for _, opt := range opts {
|
||||
opt(cmdOpts)
|
||||
}
|
||||
if cmdOpts.loggerPrefixName == "" {
|
||||
cmdOpts.loggerPrefixName = "OpenIM.log.all"
|
||||
}
|
||||
err := log.InitFromConfig(cmdOpts.loggerPrefixName, name, config.Config.Log.RemainLogLevel,
|
||||
config.Config.Log.IsStdout, config.Config.Log.IsJson, config.Config.Log.StorageLocation,
|
||||
config.Config.Log.RemainRotationCount, config.Config.Log.RotationTime)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
rootCmd.Command = cmd
|
||||
rootCmd.addConfFlag()
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
func (rc *RootCmd) persistentPreRun(cmd *cobra.Command, opts ...func(*CmdOpts)) error {
|
||||
if err := rc.initializeConfiguration(cmd); err != nil {
|
||||
return fmt.Errorf("failed to get configuration from command: %w", err)
|
||||
}
|
||||
// func (rc *RootCmd) persistentPreRun(cmd *cobra.Command, opts ...func(*CmdOpts)) error {
|
||||
// if err := rc.initializeConfiguration(cmd); err != nil {
|
||||
// return fmt.Errorf("failed to get configuration from command: %w", err)
|
||||
// }
|
||||
|
||||
cmdOpts := rc.applyOptions(opts...)
|
||||
// cmdOpts := rc.applyOptions(opts...)
|
||||
|
||||
if err := rc.initializeLogger(cmdOpts); err != nil {
|
||||
return fmt.Errorf("failed to initialize from config: %w", err)
|
||||
}
|
||||
// if err := rc.initializeLogger(cmdOpts); err != nil {
|
||||
// return fmt.Errorf("failed to initialize from config: %w", err)
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
// return nil
|
||||
// }
|
||||
|
||||
//nolint:unused //unused work wrongly
|
||||
func (rc *RootCmd) initializeConfiguration(cmd *cobra.Command) error {
|
||||
return rc.getConfFromCmdAndInit(cmd)
|
||||
}
|
||||
|
||||
func (rc *RootCmd) applyOptions(opts ...func(*CmdOpts)) *CmdOpts {
|
||||
cmdOpts := defaultCmdOpts()
|
||||
for _, opt := range opts {
|
||||
opt(cmdOpts)
|
||||
}
|
||||
// func (rc *RootCmd) applyOptions(opts ...func(*CmdOpts)) *CmdOpts {
|
||||
// cmdOpts := defaultCmdOpts()
|
||||
// for _, opt := range opts {
|
||||
// opt(cmdOpts)
|
||||
// }
|
||||
|
||||
return cmdOpts
|
||||
}
|
||||
// return cmdOpts
|
||||
// }
|
||||
|
||||
func (rc *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
|
||||
logConfig := config.Config.Log
|
||||
|
||||
return log.InitFromConfig(
|
||||
|
||||
cmdOpts.loggerPrefixName,
|
||||
rc.Name,
|
||||
logConfig.RemainLogLevel,
|
||||
logConfig.IsStdout,
|
||||
logConfig.IsJson,
|
||||
logConfig.StorageLocation,
|
||||
logConfig.RemainRotationCount,
|
||||
logConfig.RotationTime,
|
||||
)
|
||||
}
|
||||
// func (rc *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
|
||||
// logConfig := config.Config.Log
|
||||
|
||||
func defaultCmdOpts() *CmdOpts {
|
||||
return &CmdOpts{
|
||||
loggerPrefixName: "OpenIM.log.all",
|
||||
}
|
||||
}
|
||||
// return log.InitFromConfig(
|
||||
|
||||
// cmdOpts.loggerPrefixName,
|
||||
// rc.Name,
|
||||
// logConfig.RemainLogLevel,
|
||||
// logConfig.IsStdout,
|
||||
// logConfig.IsJson,
|
||||
// logConfig.StorageLocation,
|
||||
// logConfig.RemainRotationCount,
|
||||
// logConfig.RotationTime,
|
||||
// )
|
||||
// }
|
||||
|
||||
// func defaultCmdOpts() *CmdOpts {
|
||||
// return &CmdOpts{
|
||||
// loggerPrefixName: "OpenIM.log.all",
|
||||
// }
|
||||
// }
|
||||
|
||||
func (r *RootCmd) SetRootCmdPt(cmdItf RootCmdPt) {
|
||||
r.cmdItf = cmdItf
|
||||
@@ -134,6 +152,7 @@ func (r *RootCmd) getPortFlag(cmd *cobra.Command) int {
|
||||
if port == 0 {
|
||||
port = r.PortFromConfig(constant.FlagPort)
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
@@ -150,6 +169,7 @@ func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
|
||||
if port == 0 {
|
||||
port = r.PortFromConfig(constant.FlagPrometheusPort)
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
@@ -160,7 +180,8 @@ func (r *RootCmd) GetPrometheusPortFlag() int {
|
||||
func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error {
|
||||
configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf)
|
||||
fmt.Println("configFolderPath:", configFolderPath)
|
||||
return config2.InitConfig(configFolderPath)
|
||||
|
||||
return config.InitConfig(configFolderPath)
|
||||
}
|
||||
|
||||
func (r *RootCmd) Execute() error {
|
||||
@@ -173,9 +194,12 @@ func (r *RootCmd) AddCommand(cmds ...*cobra.Command) {
|
||||
|
||||
func (r *RootCmd) GetPortFromConfig(portType string) int {
|
||||
fmt.Println("RootCmd.GetPortFromConfig:", portType)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (r *RootCmd) PortFromConfig(portType string) int {
|
||||
fmt.Println("PortFromConfig:", portType)
|
||||
|
||||
return r.cmdItf.GetPortFromConfig(portType)
|
||||
}
|
||||
|
||||
@@ -16,11 +16,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||
@@ -33,6 +35,7 @@ type RpcCmd struct {
|
||||
func NewRpcCmd(name string) *RpcCmd {
|
||||
ret := &RpcCmd{NewRootCmd(name)}
|
||||
ret.SetRootCmdPt(ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -41,6 +44,7 @@ func (a *RpcCmd) Exec() error {
|
||||
a.port = a.getPortFlag(cmd)
|
||||
a.prometheusPort = a.getPrometheusPortFlag(cmd)
|
||||
}
|
||||
|
||||
return a.Execute()
|
||||
}
|
||||
|
||||
@@ -51,8 +55,10 @@ func (a *RpcCmd) StartSvr(
|
||||
if a.GetPortFlag() == 0 {
|
||||
return errors.New("port is required")
|
||||
}
|
||||
|
||||
return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), rpcFn)
|
||||
}
|
||||
|
||||
func (a *RpcCmd) GetPortFromConfig(portType string) int {
|
||||
switch a.Name {
|
||||
case RpcPushServer:
|
||||
@@ -88,5 +94,6 @@ func (a *RpcCmd) GetPortFromConfig(portType string) int {
|
||||
return config2.Config.RpcPort.OpenImUserPort[0]
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -336,6 +336,7 @@ func (c *configStruct) RegisterConf2Registry(registry discoveryregistry.SvcDisco
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return registry.RegisterConf2Registry(ConfKey, data)
|
||||
}
|
||||
|
||||
@@ -348,5 +349,6 @@ func (c *configStruct) EncodeConfig() []byte {
|
||||
if err := yaml.NewEncoder(buf).Encode(c); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
)
|
||||
|
||||
//go:embed version
|
||||
@@ -34,7 +35,7 @@ const (
|
||||
DefaultFolderPath = "../config/"
|
||||
)
|
||||
|
||||
// getProjectRoot returns the absolute path of the project root directory
|
||||
// getProjectRoot returns the absolute path of the project root directory.
|
||||
func GetProjectRoot() string {
|
||||
b, _ := filepath.Abs(os.Args[0])
|
||||
|
||||
@@ -56,6 +57,7 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
||||
opts = msgprocessor.WithOptions(opts, msgprocessor.WithHistory(true), msgprocessor.WithPersistent())
|
||||
}
|
||||
opts = msgprocessor.WithOptions(opts, msgprocessor.WithSendMsg(cfg.IsSendMsg))
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
@@ -76,6 +78,7 @@ func initConfig(config interface{}, configName, configFolderPath string) error {
|
||||
return fmt.Errorf("unmarshal yaml error: %w", err)
|
||||
}
|
||||
fmt.Println("use config", configFolderPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -92,6 +95,6 @@ func InitConfig(configFolderPath string) error {
|
||||
if err := initConfig(&Config, FileName, configFolderPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return initConfig(&Config.Notification, NotificationFileName, configFolderPath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
sdk "github.com/OpenIMSDK/protocol/sdkws"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
)
|
||||
@@ -27,11 +26,11 @@ func BlackDB2Pb(
|
||||
ctx context.Context,
|
||||
blackDBs []*relation.BlackModel,
|
||||
f func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
|
||||
) (blackPbs []*sdk.BlackInfo, err error) {
|
||||
) (blackPbs []*sdkws.BlackInfo, err error) {
|
||||
if len(blackDBs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var userIDs []string
|
||||
userIDs := make([]string, 0, len(blackDBs))
|
||||
for _, blackDB := range blackDBs {
|
||||
userIDs = append(userIDs, blackDB.BlockUserID)
|
||||
}
|
||||
@@ -40,7 +39,7 @@ func BlackDB2Pb(
|
||||
return nil, err
|
||||
}
|
||||
for _, blackDB := range blackDBs {
|
||||
blackPb := &sdk.BlackInfo{
|
||||
blackPb := &sdkws.BlackInfo{
|
||||
OwnerUserID: blackDB.OwnerUserID,
|
||||
CreateTime: blackDB.CreateTime.Unix(),
|
||||
AddSource: blackDB.AddSource,
|
||||
@@ -55,5 +54,6 @@ func BlackDB2Pb(
|
||||
}
|
||||
blackPbs = append(blackPbs, blackPb)
|
||||
}
|
||||
|
||||
return blackPbs, nil
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ func ConversationDB2Pb(conversationDB *relation.ConversationModel) *conversation
|
||||
if err := utils.CopyStructFields(conversationPB, conversationDB); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return conversationPB
|
||||
}
|
||||
|
||||
@@ -39,6 +40,7 @@ func ConversationsDB2Pb(conversationsDB []*relation.ConversationModel) (conversa
|
||||
conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.Unix()
|
||||
conversationsPB = append(conversationsPB, conversationPB)
|
||||
}
|
||||
|
||||
return conversationsPB
|
||||
}
|
||||
|
||||
@@ -47,6 +49,7 @@ func ConversationPb2DB(conversationPB *conversation.Conversation) *relation.Conv
|
||||
if err := utils.CopyStructFields(conversationDB, conversationPB); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return conversationDB
|
||||
}
|
||||
|
||||
@@ -58,5 +61,6 @@ func ConversationsPb2DB(conversationsPB []*conversation.Conversation) (conversat
|
||||
}
|
||||
conversationsDB = append(conversationsDB, conversationDB)
|
||||
}
|
||||
|
||||
return conversationsDB
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package convert
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenIMSDK/protocol/sdkws"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -25,9 +26,13 @@ import (
|
||||
|
||||
func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel {
|
||||
dbFriend := &relation.FriendModel{}
|
||||
utils.CopyStructFields(dbFriend, friend)
|
||||
err := utils.CopyStructFields(dbFriend, friend)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dbFriend.FriendUserID = friend.FriendUser.UserID
|
||||
dbFriend.CreateTime = utils.UnixSecondToTime(friend.CreateTime)
|
||||
|
||||
return dbFriend
|
||||
}
|
||||
|
||||
@@ -37,7 +42,10 @@ func FriendDB2Pb(
|
||||
getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error),
|
||||
) (*sdkws.FriendInfo, error) {
|
||||
pbfriend := &sdkws.FriendInfo{FriendUser: &sdkws.UserInfo{}}
|
||||
utils.CopyStructFields(pbfriend, friendDB)
|
||||
err := utils.CopyStructFields(pbfriend, friendDB)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
users, err := getUsers(ctx, []string{friendDB.FriendUserID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -47,6 +55,7 @@ func FriendDB2Pb(
|
||||
pbfriend.FriendUser.FaceURL = users[friendDB.FriendUserID].FaceURL
|
||||
pbfriend.FriendUser.Ex = users[friendDB.FriendUserID].Ex
|
||||
pbfriend.CreateTime = friendDB.CreateTime.Unix()
|
||||
|
||||
return pbfriend, nil
|
||||
}
|
||||
|
||||
@@ -58,7 +67,7 @@ func FriendsDB2Pb(
|
||||
if len(friendsDB) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var userID []string
|
||||
userID := make([]string, 0, len(friendsDB))
|
||||
for _, friendDB := range friendsDB {
|
||||
userID = append(userID, friendDB.FriendUserID)
|
||||
}
|
||||
@@ -68,7 +77,8 @@ func FriendsDB2Pb(
|
||||
}
|
||||
for _, friend := range friendsDB {
|
||||
friendPb := &sdkws.FriendInfo{FriendUser: &sdkws.UserInfo{}}
|
||||
utils.CopyStructFields(friendPb, friend)
|
||||
err2 := utils.CopyStructFields(friendPb, friend)
|
||||
err = fmt.Errorf("%w, %w", err, err2)
|
||||
friendPb.FriendUser.UserID = users[friend.FriendUserID].UserID
|
||||
friendPb.FriendUser.Nickname = users[friend.FriendUserID].Nickname
|
||||
friendPb.FriendUser.FaceURL = users[friend.FriendUserID].FaceURL
|
||||
@@ -76,7 +86,8 @@ func FriendsDB2Pb(
|
||||
friendPb.CreateTime = friend.CreateTime.Unix()
|
||||
friendsPb = append(friendsPb, friendPb)
|
||||
}
|
||||
return friendsPb, nil
|
||||
|
||||
return friendsPb, err
|
||||
}
|
||||
|
||||
func FriendRequestDB2Pb(
|
||||
@@ -116,5 +127,6 @@ func FriendRequestDB2Pb(
|
||||
Ex: friendRequest.Ex,
|
||||
})
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ func MsgPb2DB(msg *sdkws.MsgData) *unrelation.MsgDataModel {
|
||||
msgDataModel.AtUserIDList = msg.AtUserIDList
|
||||
msgDataModel.AttachedInfo = msg.AttachedInfo
|
||||
msgDataModel.Ex = msg.Ex
|
||||
|
||||
return &msgDataModel
|
||||
}
|
||||
|
||||
@@ -95,5 +96,6 @@ func MsgDB2Pb(msgModel *unrelation.MsgDataModel) *sdkws.MsgData {
|
||||
msg.AtUserIDList = msgModel.AtUserIDList
|
||||
msg.AttachedInfo = msgModel.AttachedInfo
|
||||
msg.Ex = msgModel.Ex
|
||||
|
||||
return &msg
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ func UsersDB2Pb(users []*relationtb.UserModel) (result []*sdkws.UserInfo) {
|
||||
userPb.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
result = append(result, &userPb)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -46,5 +47,6 @@ func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel {
|
||||
userDB.CreateTime = time.UnixMilli(user.CreateTime)
|
||||
userDB.AppMangerLevel = user.AppMangerLevel
|
||||
userDB.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt
|
||||
|
||||
return &userDB
|
||||
}
|
||||
|
||||
Vendored
+6
-15
@@ -52,6 +52,7 @@ func NewBlackCacheRedis(
|
||||
options rockscache.Options,
|
||||
) BlackCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &BlackCacheRedis{
|
||||
expireTime: blackExpireTime,
|
||||
rcClient: rcClient,
|
||||
@@ -61,12 +62,7 @@ func NewBlackCacheRedis(
|
||||
}
|
||||
|
||||
func (b *BlackCacheRedis) NewCache() BlackCache {
|
||||
return &BlackCacheRedis{
|
||||
expireTime: b.expireTime,
|
||||
rcClient: b.rcClient,
|
||||
blackDB: b.blackDB,
|
||||
metaCache: NewMetaCacheRedis(b.rcClient, b.metaCache.GetPreDelKeys()...),
|
||||
}
|
||||
return &BlackCacheRedis{expireTime: b.expireTime, rcClient: b.rcClient, blackDB: b.blackDB, metaCache: NewMetaCacheRedis(b.rcClient, b.metaCache.GetPreDelKeys()...)}
|
||||
}
|
||||
|
||||
func (b *BlackCacheRedis) getBlackIDsKey(ownerUserID string) string {
|
||||
@@ -74,19 +70,14 @@ func (b *BlackCacheRedis) getBlackIDsKey(ownerUserID string) string {
|
||||
}
|
||||
|
||||
func (b *BlackCacheRedis) GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
b.rcClient,
|
||||
b.getBlackIDsKey(userID),
|
||||
b.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return b.blackDB.FindBlackUserIDs(ctx, userID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, b.rcClient, b.getBlackIDsKey(userID), b.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return b.blackDB.FindBlackUserIDs(ctx, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BlackCacheRedis) DelBlackIDs(ctx context.Context, userID string) BlackCache {
|
||||
cache := b.NewCache()
|
||||
cache.AddKeys(b.getBlackIDsKey(userID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
Vendored
+102
-166
@@ -73,7 +73,7 @@ type ConversationCache interface {
|
||||
GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error)
|
||||
DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache
|
||||
|
||||
GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) ConversationCache
|
||||
|
||||
GetConversationsByConversationID(ctx context.Context,
|
||||
@@ -83,12 +83,9 @@ type ConversationCache interface {
|
||||
DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache
|
||||
}
|
||||
|
||||
func NewConversationRedis(
|
||||
rdb redis.UniversalClient,
|
||||
opts rockscache.Options,
|
||||
db relationtb.ConversationModelInterface,
|
||||
) ConversationCache {
|
||||
func NewConversationRedis(rdb redis.UniversalClient, opts rockscache.Options, db relationtb.ConversationModelInterface) ConversationCache {
|
||||
rcClient := rockscache.NewClient(rdb, opts)
|
||||
|
||||
return &ConversationRedisCache{
|
||||
rcClient: rcClient,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
@@ -110,6 +107,7 @@ func NewNewConversationRedis(
|
||||
options rockscache.Options,
|
||||
) ConversationCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &ConversationRedisCache{
|
||||
rcClient: rcClient,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
@@ -156,24 +154,19 @@ func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conv
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getConversationIDsKey(ownerUserID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, c.rcClient, c.getConversationIDsKey(ownerUserID), c.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) ConversationCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, c.getConversationIDsKey(userID))
|
||||
}
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
@@ -181,10 +174,7 @@ func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUserID strin
|
||||
return conversationIDsHashKey + ownerUserID
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetUserConversationIDsHash(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) (hash uint64, err error) {
|
||||
func (c *ConversationRedisCache) GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
@@ -204,229 +194,180 @@ func (c *ConversationRedisCache) GetUserConversationIDsHash(
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelUserConversationIDsHash(ownerUserIDs ...string) ConversationCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
for _, ownerUserID := range ownerUserIDs {
|
||||
keys = append(keys, c.getUserConversationIDsHashKey(ownerUserID))
|
||||
}
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetConversation(
|
||||
ctx context.Context,
|
||||
ownerUserID, conversationID string,
|
||||
) (*relationtb.ConversationModel, error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getConversationKey(ownerUserID, conversationID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) (*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.Take(ctx, ownerUserID, conversationID)
|
||||
},
|
||||
)
|
||||
func (c *ConversationRedisCache) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationtb.ConversationModel, error) {
|
||||
return getCache(ctx, c.rcClient, c.getConversationKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.Take(ctx, ownerUserID, conversationID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(conversationIDs))
|
||||
for _, conversationID := range conversationIDs {
|
||||
keys = append(keys, c.getConversationKey(ownerUserID, conversationID))
|
||||
}
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) getConversationIndex(
|
||||
convsation *relationtb.ConversationModel,
|
||||
keys []string,
|
||||
) (int, error) {
|
||||
func (c *ConversationRedisCache) getConversationIndex(convsation *relationtb.ConversationModel, keys []string) (int, error) {
|
||||
key := c.getConversationKey(convsation.OwnerUserID, convsation.ConversationID)
|
||||
for _i, _key := range keys {
|
||||
if _key == key {
|
||||
return _i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, errors.New("not found key:" + key + " in keys")
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetConversations(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
conversationIDs []string,
|
||||
) ([]*relationtb.ConversationModel, error) {
|
||||
var keys []string
|
||||
for _, conversarionID := range conversationIDs {
|
||||
keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
keys,
|
||||
c.expireTime,
|
||||
c.getConversationIndex,
|
||||
func(ctx context.Context) ([]*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
|
||||
},
|
||||
)
|
||||
func (c *ConversationRedisCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
//var keys []string
|
||||
//for _, conversarionID := range conversationIDs {
|
||||
// keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
|
||||
//}
|
||||
//return batchGetCache(
|
||||
// ctx,
|
||||
// c.rcClient,
|
||||
// keys,
|
||||
// c.expireTime,
|
||||
// c.getConversationIndex,
|
||||
// func(ctx context.Context) ([]*relationtb.ConversationModel, error) {
|
||||
// return c.conversationDB.Find(ctx, ownerUserID, conversationIDs)
|
||||
// },
|
||||
//)
|
||||
return batchGetCache2(ctx, c.rcClient, c.expireTime, conversationIDs, func(conversationID string) string {
|
||||
return c.getConversationKey(ownerUserID, conversationID)
|
||||
}, func(ctx context.Context, conversationID string) (*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.Take(ctx, ownerUserID, conversationID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetUserAllConversations(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) ([]*relationtb.ConversationModel, error) {
|
||||
func (c *ConversationRedisCache) GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) {
|
||||
conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var keys []string
|
||||
for _, conversarionID := range conversationIDs {
|
||||
keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
keys,
|
||||
c.expireTime,
|
||||
c.getConversationIndex,
|
||||
func(ctx context.Context) ([]*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.FindUserIDAllConversations(ctx, ownerUserID)
|
||||
},
|
||||
)
|
||||
//var keys []string
|
||||
//for _, conversarionID := range conversationIDs {
|
||||
// keys = append(keys, c.getConversationKey(ownerUserID, conversarionID))
|
||||
//}
|
||||
//return batchGetCache(
|
||||
// ctx,
|
||||
// c.rcClient,
|
||||
// keys,
|
||||
// c.expireTime,
|
||||
// c.getConversationIndex,
|
||||
// func(ctx context.Context) ([]*relationtb.ConversationModel, error) {
|
||||
// return c.conversationDB.FindUserIDAllConversations(ctx, ownerUserID)
|
||||
// },
|
||||
//)
|
||||
return c.GetConversations(ctx, ownerUserID, conversationIDs)
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetUserRecvMsgOpt(
|
||||
ctx context.Context,
|
||||
ownerUserID, conversationID string,
|
||||
) (opt int, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getRecvMsgOptKey(ownerUserID, conversationID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) (opt int, err error) {
|
||||
return c.conversationDB.GetUserRecvMsgOpt(ctx, ownerUserID, conversationID)
|
||||
},
|
||||
)
|
||||
func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getRecvMsgOptKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (opt int, err error) {
|
||||
return c.conversationDB.GetUserRecvMsgOpt(ctx, ownerUserID, conversationID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) (userIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getSuperGroupRecvNotNotifyUserIDsKey(groupID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) (userIDs []string, err error) {
|
||||
return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
},
|
||||
)
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) {
|
||||
return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
for _, ownerUserID := range ownerUserIDs {
|
||||
keys = append(keys, c.getConversationKey(ownerUserID, conversationID))
|
||||
}
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(c.getRecvMsgOptKey(ownerUserID, conversationID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsKey(groupID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) (hash uint64, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) (hash uint64, err error) {
|
||||
userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
utils.Sort(userIDs, true)
|
||||
bi := big.NewInt(0)
|
||||
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
return bi.Uint64(), nil
|
||||
},
|
||||
func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) {
|
||||
return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) {
|
||||
userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
utils.Sort(userIDs, true)
|
||||
bi := big.NewInt(0)
|
||||
bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16)
|
||||
return bi.Uint64(), nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) getUserAllHasReadSeqsIndex(
|
||||
conversationID string,
|
||||
conversationIDs []string,
|
||||
) (int, error) {
|
||||
func (c *ConversationRedisCache) getUserAllHasReadSeqsIndex(conversationID string, conversationIDs []string) (int, error) {
|
||||
for _i, _conversationID := range conversationIDs {
|
||||
if _conversationID == conversationID {
|
||||
return _i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, errors.New("not found key:" + conversationID + " in keys")
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetUserAllHasReadSeqs(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) (map[string]int64, error) {
|
||||
conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var keys []string
|
||||
for _, conversarionID := range conversationIDs {
|
||||
keys = append(keys, c.getConversationHasReadSeqKey(ownerUserID, conversarionID))
|
||||
}
|
||||
return batchGetCacheMap(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
keys,
|
||||
conversationIDs,
|
||||
c.expireTime,
|
||||
c.getUserAllHasReadSeqsIndex,
|
||||
func(ctx context.Context) (map[string]int64, error) {
|
||||
return c.conversationDB.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
},
|
||||
)
|
||||
}
|
||||
//func (c *ConversationRedisCache) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) {
|
||||
// conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// var keys []string
|
||||
// for _, conversarionID := range conversationIDs {
|
||||
// keys = append(keys, c.getConversationHasReadSeqKey(ownerUserID, conversarionID))
|
||||
// }
|
||||
// return batchGetCacheMap(ctx, c.rcClient, keys, conversationIDs, c.expireTime, c.getUserAllHasReadSeqsIndex, func(ctx context.Context) (map[string]int64, error) {
|
||||
// return c.conversationDB.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
// })
|
||||
//}
|
||||
|
||||
func (c *ConversationRedisCache) DelUserAllHasReadSeqs(ownerUserID string,
|
||||
conversationIDs ...string,
|
||||
) ConversationCache {
|
||||
func (c *ConversationRedisCache) DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) ConversationCache {
|
||||
cache := c.NewCache()
|
||||
for _, conversationID := range conversationIDs {
|
||||
cache.AddKeys(c.getConversationHasReadSeqKey(ownerUserID, conversationID))
|
||||
}
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetConversationsByConversationID(
|
||||
ctx context.Context,
|
||||
conversationIDs []string,
|
||||
) ([]*relationtb.ConversationModel, error) {
|
||||
func (c *ConversationRedisCache) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
@@ -435,15 +376,9 @@ func (c *ConversationRedisCache) DelConversationByConversationID(conversationIDs
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
c.rcClient,
|
||||
c.getConversationNotReceiveMessageUserIDsKey(conversationID),
|
||||
c.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return c.conversationDB.GetConversationNotReceiveMessageUserIDs(ctx, conversationID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, c.rcClient, c.getConversationNotReceiveMessageUserIDsKey(conversationID), c.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return c.conversationDB.GetConversationNotReceiveMessageUserIDs(ctx, conversationID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache {
|
||||
@@ -451,5 +386,6 @@ func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(convers
|
||||
for _, conversationID := range conversationIDs {
|
||||
cache.AddKeys(c.getConversationNotReceiveMessageUserIDsKey(conversationID))
|
||||
}
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
Vendored
+26
-43
@@ -53,12 +53,9 @@ type FriendCacheRedis struct {
|
||||
rcClient *rockscache.Client
|
||||
}
|
||||
|
||||
func NewFriendCacheRedis(
|
||||
rdb redis.UniversalClient,
|
||||
friendDB relationtb.FriendModelInterface,
|
||||
options rockscache.Options,
|
||||
) FriendCache {
|
||||
func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface, options rockscache.Options) FriendCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &FriendCacheRedis{
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
friendDB: friendDB,
|
||||
@@ -89,32 +86,24 @@ func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
f.rcClient,
|
||||
f.getFriendIDsKey(ownerUserID),
|
||||
f.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return f.friendDB.FindFriendUserIDs(ctx, ownerUserID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, f.rcClient, f.getFriendIDsKey(ownerUserID), f.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return f.friendDB.FindFriendUserIDs(ctx, ownerUserID)
|
||||
})
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) DelFriendIDs(ownerUserID ...string) FriendCache {
|
||||
new := f.NewCache()
|
||||
var keys []string
|
||||
for _, userID := range ownerUserID {
|
||||
func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache {
|
||||
newGroupCache := f.NewCache()
|
||||
keys := make([]string, 0, len(ownerUserIDs))
|
||||
for _, userID := range ownerUserIDs {
|
||||
keys = append(keys, f.getFriendIDsKey(userID))
|
||||
}
|
||||
new.AddKeys(keys...)
|
||||
return new
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// todo.
|
||||
func (f *FriendCacheRedis) GetTwoWayFriendIDs(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
) (twoWayFriendIDs []string, err error) {
|
||||
func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID string) (twoWayFriendIDs []string, err error) {
|
||||
friendIDs, err := f.GetFriendIDs(ctx, ownerUserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -128,32 +117,26 @@ func (f *FriendCacheRedis) GetTwoWayFriendIDs(
|
||||
twoWayFriendIDs = append(twoWayFriendIDs, ownerUserID)
|
||||
}
|
||||
}
|
||||
|
||||
return twoWayFriendIDs, nil
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) FriendCache {
|
||||
new := f.NewCache()
|
||||
new.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID))
|
||||
return new
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID))
|
||||
|
||||
return newFriendCache
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) GetFriend(
|
||||
ctx context.Context,
|
||||
ownerUserID, friendUserID string,
|
||||
) (friend *relationtb.FriendModel, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
f.rcClient,
|
||||
f.getFriendKey(ownerUserID, friendUserID),
|
||||
f.expireTime,
|
||||
func(ctx context.Context) (*relationtb.FriendModel, error) {
|
||||
return f.friendDB.Take(ctx, ownerUserID, friendUserID)
|
||||
},
|
||||
)
|
||||
func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) {
|
||||
return getCache(ctx, f.rcClient, f.getFriendKey(ownerUserID, friendUserID), f.expireTime, func(ctx context.Context) (*relationtb.FriendModel, error) {
|
||||
return f.friendDB.Take(ctx, ownerUserID, friendUserID)
|
||||
})
|
||||
}
|
||||
|
||||
func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCache {
|
||||
new := f.NewCache()
|
||||
new.AddKeys(f.getFriendKey(ownerUserID, friendUserID))
|
||||
return new
|
||||
newFriendCache := f.NewCache()
|
||||
newFriendCache.AddKeys(f.getFriendKey(ownerUserID, friendUserID))
|
||||
|
||||
return newFriendCache
|
||||
}
|
||||
|
||||
Vendored
+116
-189
@@ -65,22 +65,10 @@ type GroupCache interface {
|
||||
GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error)
|
||||
DelJoinedGroupID(userID ...string) GroupCache
|
||||
|
||||
GetGroupMemberInfo(
|
||||
ctx context.Context,
|
||||
groupID, userID string,
|
||||
) (groupMember *relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersInfo(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID []string,
|
||||
) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersPage(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userID []string,
|
||||
showNumber, pageNumber int32,
|
||||
) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error)
|
||||
|
||||
DelGroupMembersInfo(groupID string, userID ...string) GroupCache
|
||||
|
||||
@@ -109,6 +97,7 @@ func NewGroupCacheRedis(
|
||||
opts rockscache.Options,
|
||||
) GroupCache {
|
||||
rcClient := rockscache.NewClient(rdb, opts)
|
||||
|
||||
return &GroupCacheRedis{
|
||||
rcClient: rcClient, expireTime: groupExpireTime,
|
||||
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
|
||||
@@ -169,6 +158,7 @@ func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []str
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, errIndex
|
||||
}
|
||||
|
||||
@@ -179,117 +169,98 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, errIndex
|
||||
}
|
||||
|
||||
// / groupInfo.
|
||||
func (g *GroupCacheRedis) GetGroupsInfo(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (groups []*relationtb.GroupModel, err error) {
|
||||
var keys []string
|
||||
for _, group := range groupIDs {
|
||||
keys = append(keys, g.getGroupInfoKey(group))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
keys,
|
||||
g.expireTime,
|
||||
g.GetGroupIndex,
|
||||
func(ctx context.Context) ([]*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Find(ctx, groupIDs)
|
||||
},
|
||||
)
|
||||
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getGroupInfoKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupIndex, func(ctx context.Context) ([]*relationtb.GroupModel, error) {
|
||||
// return g.groupDB.Find(ctx, groupIDs)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getGroupInfoKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Take(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getGroupInfoKey(groupID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) (*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Take(ctx, groupID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*relationtb.GroupModel, error) {
|
||||
return g.groupDB.Take(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache {
|
||||
new := g.NewCache()
|
||||
var keys []string
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
keys = append(keys, g.getGroupInfoKey(groupID))
|
||||
}
|
||||
new.AddKeys(keys...)
|
||||
return new
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
) (joinedSuperGroupIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getJoinedSuperGroupsIDKey(userID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userGroup.GroupIDs, nil
|
||||
},
|
||||
func (g *GroupCacheRedis) GetJoinedSuperGroupIDs(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getJoinedSuperGroupsIDKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
userGroup, err := g.mongoDB.GetSuperGroupByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userGroup.GroupIDs, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetSuperGroupMemberIDs(
|
||||
ctx context.Context,
|
||||
groupIDs ...string,
|
||||
) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
var keys []string
|
||||
for _, group := range groupIDs {
|
||||
keys = append(keys, g.getSuperGroupMemberIDsKey(group))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
keys,
|
||||
g.expireTime,
|
||||
func(model *unrelationtb.SuperGroupModel, keys []string) (int, error) {
|
||||
for i, key := range keys {
|
||||
if g.getSuperGroupMemberIDsKey(model.GroupID) == key {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return 0, errIndex
|
||||
},
|
||||
func(ctx context.Context) ([]*unrelationtb.SuperGroupModel, error) {
|
||||
return g.mongoDB.FindSuperGroup(ctx, groupIDs)
|
||||
},
|
||||
)
|
||||
func (g *GroupCacheRedis) GetSuperGroupMemberIDs(ctx context.Context, groupIDs ...string) (models []*unrelationtb.SuperGroupModel, err error) {
|
||||
//var keys []string
|
||||
//for _, group := range groupIDs {
|
||||
// keys = append(keys, g.getSuperGroupMemberIDsKey(group))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, func(model *unrelationtb.SuperGroupModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if g.getSuperGroupMemberIDsKey(model.GroupID) == key {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
//},
|
||||
// func(ctx context.Context) ([]*unrelationtb.SuperGroupModel, error) {
|
||||
// return g.mongoDB.FindSuperGroup(ctx, groupIDs)
|
||||
// })
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string {
|
||||
return g.getSuperGroupMemberIDsKey(groupID)
|
||||
}, func(ctx context.Context, groupID string) (*unrelationtb.SuperGroupModel, error) {
|
||||
return g.mongoDB.TakeSuperGroup(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
// userJoinSuperGroup.
|
||||
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
|
||||
new := g.NewCache()
|
||||
var keys []string
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getJoinedSuperGroupsIDKey(userID))
|
||||
}
|
||||
new.AddKeys(keys...)
|
||||
return new
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache {
|
||||
new := g.NewCache()
|
||||
var keys []string
|
||||
newGroupCache := g.NewCache()
|
||||
keys := make([]string, 0, len(groupIDs))
|
||||
for _, groupID := range groupIDs {
|
||||
keys = append(keys, g.getSuperGroupMemberIDsKey(groupID))
|
||||
}
|
||||
new.AddKeys(keys...)
|
||||
return new
|
||||
newGroupCache.AddKeys(keys...)
|
||||
|
||||
return newGroupCache
|
||||
}
|
||||
|
||||
// groupMembersHash.
|
||||
@@ -351,10 +322,7 @@ func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID strin
|
||||
//)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) {
|
||||
res := make(map[string]*relationtb.GroupSimpleUserID)
|
||||
for _, groupID := range groupIDs {
|
||||
hash, err := g.GetGroupMembersHash(ctx, groupID)
|
||||
@@ -368,26 +336,22 @@ func (g *GroupCacheRedis) GetGroupMemberHashMap(
|
||||
}
|
||||
res[groupID] = &relationtb.GroupSimpleUserID{Hash: hash, MemberNum: uint32(num)}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
|
||||
cache := g.NewCache()
|
||||
cache.AddKeys(g.getGroupMembersHashKey(groupID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
// groupMemberIDs.
|
||||
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getGroupMemberIDsKey(groupID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindMemberUserID(ctx, groupID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, g.rcClient, g.getGroupMemberIDsKey(groupID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindMemberUserID(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupsMemberIDs(ctx context.Context, groupIDs []string) (map[string][]string, error) {
|
||||
@@ -399,79 +363,56 @@ func (g *GroupCacheRedis) GetGroupsMemberIDs(ctx context.Context, groupIDs []str
|
||||
}
|
||||
m[groupID] = userIDs
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupMemberIDs(groupID string) GroupCache {
|
||||
cache := g.NewCache()
|
||||
cache.AddKeys(g.getGroupMemberIDsKey(groupID))
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getJoinedGroupsKey(userID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindUserJoinedGroupID(ctx, userID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, g.rcClient, g.getJoinedGroupsKey(userID), g.expireTime, func(ctx context.Context) ([]string, error) {
|
||||
return g.groupMemberDB.FindUserJoinedGroupID(ctx, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelJoinedGroupID(userIDs ...string) GroupCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getJoinedGroupsKey(userID))
|
||||
}
|
||||
cache := g.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberInfo(
|
||||
ctx context.Context,
|
||||
groupID, userID string,
|
||||
) (groupMember *relationtb.GroupMemberModel, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getGroupMemberInfoKey(groupID, userID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Take(ctx, groupID, userID)
|
||||
},
|
||||
)
|
||||
func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationtb.GroupMemberModel, err error) {
|
||||
return getCache(ctx, g.rcClient, g.getGroupMemberInfoKey(groupID, userID), g.expireTime, func(ctx context.Context) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Take(ctx, groupID, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersInfo(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userIDs []string,
|
||||
) ([]*relationtb.GroupMemberModel, error) {
|
||||
var keys []string
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
keys,
|
||||
g.expireTime,
|
||||
g.GetGroupMemberIndex,
|
||||
func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil)
|
||||
},
|
||||
)
|
||||
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) {
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, userIDs, nil)
|
||||
//})
|
||||
return batchGetCache2(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string {
|
||||
return g.getGroupMemberInfoKey(groupID, userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Take(ctx, groupID, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMembersPage(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
userIDs []string,
|
||||
showNumber, pageNumber int32,
|
||||
) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *GroupCacheRedis) GetGroupMembersPage(ctx context.Context, groupID string, userIDs []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@@ -482,72 +423,58 @@ func (g *GroupCacheRedis) GetGroupMembersPage(
|
||||
userIDs = groupMemberIDs
|
||||
}
|
||||
groupMembers, err = g.GetGroupMembersInfo(ctx, groupID, utils.Paginate(userIDs, int(showNumber), int(showNumber)))
|
||||
|
||||
return uint32(len(userIDs)), groupMembers, err
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetAllGroupMembersInfo(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) (groupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) {
|
||||
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetAllGroupMemberInfo(
|
||||
ctx context.Context,
|
||||
groupID string,
|
||||
) ([]*relationtb.GroupMemberModel, error) {
|
||||
func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) {
|
||||
groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var keys []string
|
||||
for _, groupMemberID := range groupMemberIDs {
|
||||
keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
keys,
|
||||
g.expireTime,
|
||||
g.GetGroupMemberIndex,
|
||||
func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil)
|
||||
},
|
||||
)
|
||||
//var keys []string
|
||||
//for _, groupMemberID := range groupMemberIDs {
|
||||
// keys = append(keys, g.getGroupMemberInfoKey(groupID, groupMemberID))
|
||||
//}
|
||||
//return batchGetCache(ctx, g.rcClient, keys, g.expireTime, g.GetGroupMemberIndex, func(ctx context.Context) ([]*relationtb.GroupMemberModel, error) {
|
||||
// return g.groupMemberDB.Find(ctx, []string{groupID}, groupMemberIDs, nil)
|
||||
//})
|
||||
return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs)
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupMembersInfo(groupID string, userIDs ...string) GroupCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, g.getGroupMemberInfoKey(groupID, userID))
|
||||
}
|
||||
cache := g.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
g.rcClient,
|
||||
g.getGroupMemberNumKey(groupID),
|
||||
g.expireTime,
|
||||
func(ctx context.Context) (int64, error) {
|
||||
return g.groupMemberDB.TakeGroupMemberNum(ctx, groupID)
|
||||
},
|
||||
)
|
||||
return getCache(ctx, g.rcClient, g.getGroupMemberNumKey(groupID), g.expireTime, func(ctx context.Context) (int64, error) {
|
||||
return g.groupMemberDB.TakeGroupMemberNum(ctx, groupID)
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(groupID))
|
||||
for _, groupID := range groupID {
|
||||
keys = append(keys, g.getGroupMemberNumKey(groupID))
|
||||
}
|
||||
cache := g.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
Vendored
+126
-105
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
@@ -59,27 +58,40 @@ type metaCacheRedis struct {
|
||||
func (m *metaCacheRedis) ExecDel(ctx context.Context) error {
|
||||
if len(m.keys) > 0 {
|
||||
log.ZDebug(ctx, "delete cache", "keys", m.keys)
|
||||
retryTimes := 0
|
||||
for {
|
||||
if err := m.rcClient.TagAsDeletedBatch2(ctx, m.keys); err != nil {
|
||||
if retryTimes >= m.maxRetryTimes {
|
||||
err = errs.ErrInternalServer.Wrap(
|
||||
fmt.Sprintf(
|
||||
"delete cache error: %v, keys: %v, retry times %d, please check redis server",
|
||||
err,
|
||||
m.keys,
|
||||
retryTimes,
|
||||
),
|
||||
)
|
||||
log.ZWarn(ctx, "delete cache failed, please handle keys", err, "keys", m.keys)
|
||||
return err
|
||||
for _, key := range m.keys {
|
||||
for i := 0; i < m.maxRetryTimes; i++ {
|
||||
if err := m.rcClient.TagAsDeleted(key); err != nil {
|
||||
log.ZError(ctx, "delete cache failed", err, "key", key)
|
||||
time.Sleep(m.retryInterval)
|
||||
continue
|
||||
}
|
||||
retryTimes++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
||||
//retryTimes := 0
|
||||
//for {
|
||||
// m.rcClient.TagAsDeleted()
|
||||
// if err := m.rcClient.TagAsDeletedBatch2(ctx, []string{key}); err != nil {
|
||||
// if retryTimes >= m.maxRetryTimes {
|
||||
// err = errs.ErrInternalServer.Wrap(
|
||||
// fmt.Sprintf(
|
||||
// "delete cache error: %v, keys: %v, retry times %d, please check redis server",
|
||||
// err,
|
||||
// key,
|
||||
// retryTimes,
|
||||
// ),
|
||||
// )
|
||||
// log.ZWarn(ctx, "delete cache failed, please handle keys", err, "keys", key)
|
||||
// return err
|
||||
// }
|
||||
// retryTimes++
|
||||
// } else {
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -103,16 +115,11 @@ func GetDefaultOpt() rockscache.Options {
|
||||
opts := rockscache.NewDefaultOptions()
|
||||
opts.StrongConsistency = true
|
||||
opts.RandomExpireAdjustment = 0.2
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
func getCache[T any](
|
||||
ctx context.Context,
|
||||
rcClient *rockscache.Client,
|
||||
key string,
|
||||
expire time.Duration,
|
||||
fn func(ctx context.Context) (T, error),
|
||||
) (T, error) {
|
||||
func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key string, expire time.Duration, fn func(ctx context.Context) (T, error)) (T, error) {
|
||||
var t T
|
||||
var write bool
|
||||
v, err := rcClient.Fetch2(ctx, key, expire, func() (s string, err error) {
|
||||
@@ -125,6 +132,7 @@ func getCache[T any](
|
||||
return "", utils.Wrap(err, "")
|
||||
}
|
||||
write = true
|
||||
|
||||
return string(bs), nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -139,95 +147,108 @@ func getCache[T any](
|
||||
err = json.Unmarshal([]byte(v), &t)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "cache json.Unmarshal failed", err, "key", key, "value", v, "expire", expire)
|
||||
|
||||
return t, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func batchGetCache[T any](
|
||||
ctx context.Context,
|
||||
rcClient *rockscache.Client,
|
||||
keys []string,
|
||||
expire time.Duration,
|
||||
keyIndexFn func(t T, keys []string) (int, error),
|
||||
fn func(ctx context.Context) ([]T, error),
|
||||
) ([]T, error) {
|
||||
batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) {
|
||||
values := make(map[int]string)
|
||||
tArrays, err := fn(ctx)
|
||||
//func batchGetCache[T any](ctx context.Context, rcClient *rockscache.Client, keys []string, expire time.Duration, keyIndexFn func(t T, keys []string) (int, error), fn func(ctx context.Context) ([]T, error)) ([]T, error) {
|
||||
// batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) {
|
||||
// values := make(map[int]string)
|
||||
// tArrays, err := fn(ctx)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// for _, v := range tArrays {
|
||||
// index, err := keyIndexFn(v, keys)
|
||||
// if err != nil {
|
||||
// continue
|
||||
// }
|
||||
// bs, err := json.Marshal(v)
|
||||
// if err != nil {
|
||||
// return nil, utils.Wrap(err, "marshal failed")
|
||||
// }
|
||||
// values[index] = string(bs)
|
||||
// }
|
||||
// return values, nil
|
||||
// })
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// var tArrays []T
|
||||
// for _, v := range batchMap {
|
||||
// if v != "" {
|
||||
// var t T
|
||||
// err = json.Unmarshal([]byte(v), &t)
|
||||
// if err != nil {
|
||||
// return nil, utils.Wrap(err, "unmarshal failed")
|
||||
// }
|
||||
// tArrays = append(tArrays, t)
|
||||
// }
|
||||
// }
|
||||
// return tArrays, nil
|
||||
//}
|
||||
|
||||
func batchGetCache2[T any, K comparable](ctx context.Context, rcClient *rockscache.Client, expire time.Duration, keys []K, keyFn func(key K) string, fns func(ctx context.Context, key K) (T, error)) ([]T, error) {
|
||||
if len(keys) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
res := make([]T, 0, len(keys))
|
||||
for _, key := range keys {
|
||||
val, err := getCache(ctx, rcClient, keyFn(key), expire, func(ctx context.Context) (T, error) {
|
||||
return fns(ctx, key)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range tArrays {
|
||||
index, err := keyIndexFn(v, keys)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
bs, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "marshal failed")
|
||||
}
|
||||
values[index] = string(bs)
|
||||
}
|
||||
return values, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
res = append(res, val)
|
||||
}
|
||||
var tArrays []T
|
||||
for _, v := range batchMap {
|
||||
if v != "" {
|
||||
var t T
|
||||
err = json.Unmarshal([]byte(v), &t)
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "unmarshal failed")
|
||||
}
|
||||
tArrays = append(tArrays, t)
|
||||
}
|
||||
}
|
||||
return tArrays, nil
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func batchGetCacheMap[T any](
|
||||
ctx context.Context,
|
||||
rcClient *rockscache.Client,
|
||||
keys, originKeys []string,
|
||||
expire time.Duration,
|
||||
keyIndexFn func(s string, keys []string) (int, error),
|
||||
fn func(ctx context.Context) (map[string]T, error),
|
||||
) (map[string]T, error) {
|
||||
batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) {
|
||||
tArrays, err := fn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := make(map[int]string)
|
||||
for k, v := range tArrays {
|
||||
index, err := keyIndexFn(k, originKeys)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
bs, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "marshal failed")
|
||||
}
|
||||
values[index] = string(bs)
|
||||
}
|
||||
return values, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tMap := make(map[string]T)
|
||||
for i, v := range batchMap {
|
||||
if v != "" {
|
||||
var t T
|
||||
err = json.Unmarshal([]byte(v), &t)
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "unmarshal failed")
|
||||
}
|
||||
tMap[originKeys[i]] = t
|
||||
}
|
||||
}
|
||||
return tMap, nil
|
||||
}
|
||||
//func batchGetCacheMap[T any](
|
||||
// ctx context.Context,
|
||||
// rcClient *rockscache.Client,
|
||||
// keys, originKeys []string,
|
||||
// expire time.Duration,
|
||||
// keyIndexFn func(s string, keys []string) (int, error),
|
||||
// fn func(ctx context.Context) (map[string]T, error),
|
||||
//) (map[string]T, error) {
|
||||
// batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) {
|
||||
// tArrays, err := fn(ctx)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// values := make(map[int]string)
|
||||
// for k, v := range tArrays {
|
||||
// index, err := keyIndexFn(k, originKeys)
|
||||
// if err != nil {
|
||||
// continue
|
||||
// }
|
||||
// bs, err := json.Marshal(v)
|
||||
// if err != nil {
|
||||
// return nil, utils.Wrap(err, "marshal failed")
|
||||
// }
|
||||
// values[index] = string(bs)
|
||||
// }
|
||||
// return values, nil
|
||||
// })
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// tMap := make(map[string]T)
|
||||
// for i, v := range batchMap {
|
||||
// if v != "" {
|
||||
// var t T
|
||||
// err = json.Unmarshal([]byte(v), &t)
|
||||
// if err != nil {
|
||||
// return nil, utils.Wrap(err, "unmarshal failed")
|
||||
// }
|
||||
// tMap[originKeys[i]] = t
|
||||
// }
|
||||
// }
|
||||
// return tMap, nil
|
||||
//}
|
||||
|
||||
Vendored
+226
-157
@@ -16,13 +16,14 @@ package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/dtm-labs/rockscache"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||
|
||||
"github.com/dtm-labs/rockscache"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
@@ -33,7 +34,6 @@ import (
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
@@ -105,11 +105,7 @@ type MsgModel interface {
|
||||
GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error)
|
||||
SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error
|
||||
DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error
|
||||
GetMessagesBySeq(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
seqs []int64,
|
||||
) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error)
|
||||
GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error)
|
||||
SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error)
|
||||
UserDeleteMsgs(ctx context.Context, conversationID string, seqs []int64, userID string) error
|
||||
DelUserDeleteMsgsList(ctx context.Context, conversationID string, seqs []int64)
|
||||
@@ -122,12 +118,7 @@ type MsgModel interface {
|
||||
JudgeMessageReactionExist(ctx context.Context, clientMsgID string, sessionType int32) (bool, error)
|
||||
GetOneMessageAllReactionList(ctx context.Context, clientMsgID string, sessionType int32) (map[string]string, error)
|
||||
DeleteOneMessageKey(ctx context.Context, clientMsgID string, sessionType int32, subKey string) error
|
||||
SetMessageReactionExpire(
|
||||
ctx context.Context,
|
||||
clientMsgID string,
|
||||
sessionType int32,
|
||||
expiration time.Duration,
|
||||
) (bool, error)
|
||||
SetMessageReactionExpire(ctx context.Context, clientMsgID string, sessionType int32, expiration time.Duration) (bool, error)
|
||||
GetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey string) (string, error)
|
||||
SetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey, value string) error
|
||||
LockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error
|
||||
@@ -158,50 +149,51 @@ func (c *msgCache) getHasReadSeqKey(conversationID string, userID string) string
|
||||
return hasReadSeq + userID + ":" + conversationID
|
||||
}
|
||||
|
||||
func (c *msgCache) setSeq(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
seq int64,
|
||||
getkey func(conversationID string) string,
|
||||
) error {
|
||||
func (c *msgCache) setSeq(ctx context.Context, conversationID string, seq int64, getkey func(conversationID string) string) error {
|
||||
return utils.Wrap1(c.rdb.Set(ctx, getkey(conversationID), seq, 0).Err())
|
||||
}
|
||||
|
||||
func (c *msgCache) getSeq(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
getkey func(conversationID string) string,
|
||||
) (int64, error) {
|
||||
func (c *msgCache) getSeq(ctx context.Context, conversationID string, getkey func(conversationID string) string) (int64, error) {
|
||||
return utils.Wrap2(c.rdb.Get(ctx, getkey(conversationID)).Int64())
|
||||
}
|
||||
|
||||
func (c *msgCache) getSeqs(
|
||||
ctx context.Context,
|
||||
items []string,
|
||||
getkey func(s string) string,
|
||||
) (m map[string]int64, err error) {
|
||||
pipe := c.rdb.Pipeline()
|
||||
for _, v := range items {
|
||||
if err := pipe.Get(ctx, getkey(v)).Err(); err != nil && err != redis.Nil {
|
||||
func (c *msgCache) getSeqs(ctx context.Context, items []string, getkey func(s string) string) (m map[string]int64, err error) {
|
||||
m = make(map[string]int64, len(items))
|
||||
for i, v := range items {
|
||||
res, err := c.rdb.Get(ctx, getkey(v)).Result()
|
||||
if err != nil && err != redis.Nil {
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
result, err := pipe.Exec(ctx)
|
||||
if err != nil && err != redis.Nil {
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
m = make(map[string]int64, len(items))
|
||||
for i, v := range result {
|
||||
seq := v.(*redis.StringCmd)
|
||||
if seq.Err() != nil && seq.Err() != redis.Nil {
|
||||
return nil, errs.Wrap(v.Err())
|
||||
}
|
||||
val := utils.StringToInt64(seq.Val())
|
||||
val := utils.StringToInt64(res)
|
||||
if val != 0 {
|
||||
m[items[i]] = val
|
||||
}
|
||||
}
|
||||
|
||||
return m, nil
|
||||
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for _, v := range items {
|
||||
// if err := pipe.Get(ctx, getkey(v)).Err(); err != nil && err != redis.Nil {
|
||||
// return nil, errs.Wrap(err)
|
||||
// }
|
||||
//}
|
||||
//result, err := pipe.Exec(ctx)
|
||||
//if err != nil && err != redis.Nil {
|
||||
// return nil, errs.Wrap(err)
|
||||
//}
|
||||
//m = make(map[string]int64, len(items))
|
||||
//for i, v := range result {
|
||||
// seq := v.(*redis.StringCmd)
|
||||
// if seq.Err() != nil && seq.Err() != redis.Nil {
|
||||
// return nil, errs.Wrap(v.Err())
|
||||
// }
|
||||
// val := utils.StringToInt64(seq.Val())
|
||||
// if val != 0 {
|
||||
// m[items[i]] = val
|
||||
// }
|
||||
//}
|
||||
//return m, nil
|
||||
}
|
||||
|
||||
func (c *msgCache) SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error {
|
||||
@@ -221,15 +213,21 @@ func (c *msgCache) SetMinSeq(ctx context.Context, conversationID string, minSeq
|
||||
}
|
||||
|
||||
func (c *msgCache) setSeqs(ctx context.Context, seqs map[string]int64, getkey func(key string) string) error {
|
||||
pipe := c.rdb.Pipeline()
|
||||
for k, seq := range seqs {
|
||||
err := pipe.Set(ctx, getkey(k), seq, 0).Err()
|
||||
if err != nil {
|
||||
for conversationID, seq := range seqs {
|
||||
if err := c.rdb.Set(ctx, getkey(conversationID), seq, 0).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
_, err := pipe.Exec(ctx)
|
||||
return err
|
||||
return nil
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for k, seq := range seqs {
|
||||
// err := pipe.Set(ctx, getkey(k), seq, 0).Err()
|
||||
// if err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
//}
|
||||
//_, err := pipe.Exec(ctx)
|
||||
//return err
|
||||
}
|
||||
|
||||
func (c *msgCache) SetMinSeqs(ctx context.Context, seqs map[string]int64) error {
|
||||
@@ -252,30 +250,17 @@ func (c *msgCache) GetConversationUserMinSeq(ctx context.Context, conversationID
|
||||
return utils.Wrap2(c.rdb.Get(ctx, c.getConversationUserMinSeqKey(conversationID, userID)).Int64())
|
||||
}
|
||||
|
||||
func (c *msgCache) GetConversationUserMinSeqs(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
userIDs []string,
|
||||
) (m map[string]int64, err error) {
|
||||
func (c *msgCache) GetConversationUserMinSeqs(ctx context.Context, conversationID string, userIDs []string) (m map[string]int64, err error) {
|
||||
return c.getSeqs(ctx, userIDs, func(userID string) string {
|
||||
return c.getConversationUserMinSeqKey(conversationID, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *msgCache) SetConversationUserMinSeq(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
userID string,
|
||||
minSeq int64,
|
||||
) error {
|
||||
func (c *msgCache) SetConversationUserMinSeq(ctx context.Context, conversationID string, userID string, minSeq int64) error {
|
||||
return utils.Wrap1(c.rdb.Set(ctx, c.getConversationUserMinSeqKey(conversationID, userID), minSeq, 0).Err())
|
||||
}
|
||||
|
||||
func (c *msgCache) SetConversationUserMinSeqs(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
seqs map[string]int64,
|
||||
) (err error) {
|
||||
func (c *msgCache) SetConversationUserMinSeqs(ctx context.Context, conversationID string, seqs map[string]int64) (err error) {
|
||||
return c.setSeqs(ctx, seqs, func(userID string) string {
|
||||
return c.getConversationUserMinSeqKey(conversationID, userID)
|
||||
})
|
||||
@@ -303,11 +288,7 @@ func (c *msgCache) UserSetHasReadSeqs(ctx context.Context, userID string, hasRea
|
||||
})
|
||||
}
|
||||
|
||||
func (c *msgCache) GetHasReadSeqs(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
conversationIDs []string,
|
||||
) (map[string]int64, error) {
|
||||
func (c *msgCache) GetHasReadSeqs(ctx context.Context, userID string, conversationIDs []string) (map[string]int64, error) {
|
||||
return c.getSeqs(ctx, conversationIDs, func(conversationID string) string {
|
||||
return c.getHasReadSeqKey(conversationID, userID)
|
||||
})
|
||||
@@ -319,6 +300,7 @@ func (c *msgCache) GetHasReadSeq(ctx context.Context, userID string, conversatio
|
||||
|
||||
func (c *msgCache) AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error {
|
||||
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platformID)
|
||||
|
||||
return errs.Wrap(c.rdb.HSet(ctx, key, token, flag).Err())
|
||||
}
|
||||
|
||||
@@ -332,6 +314,7 @@ func (c *msgCache) GetTokensWithoutError(ctx context.Context, userID string, pla
|
||||
for k, v := range m {
|
||||
mm[k] = utils.StringToInt(v)
|
||||
}
|
||||
|
||||
return mm, nil
|
||||
}
|
||||
|
||||
@@ -341,11 +324,13 @@ func (c *msgCache) SetTokenMapByUidPid(ctx context.Context, userID string, platf
|
||||
for k, v := range m {
|
||||
mm[k] = v
|
||||
}
|
||||
|
||||
return errs.Wrap(c.rdb.HSet(ctx, key, mm).Err())
|
||||
}
|
||||
|
||||
func (c *msgCache) DeleteTokenByUidPid(ctx context.Context, userID string, platform int, fields []string) error {
|
||||
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platform)
|
||||
|
||||
return errs.Wrap(c.rdb.HDel(ctx, key, fields...).Err())
|
||||
}
|
||||
|
||||
@@ -357,58 +342,86 @@ func (c *msgCache) allMessageCacheKey(conversationID string) string {
|
||||
return messageCache + conversationID + "_*"
|
||||
}
|
||||
|
||||
func (c *msgCache) GetMessagesBySeq(
|
||||
ctx context.Context,
|
||||
conversationID string,
|
||||
seqs []int64,
|
||||
) (seqMsgs []*sdkws.MsgData, failedSeqs []int64, err error) {
|
||||
pipe := c.rdb.Pipeline()
|
||||
for _, v := range seqs {
|
||||
// MESSAGE_CACHE:169.254.225.224_reliability1653387820_0_1
|
||||
key := c.getMessageCacheKey(conversationID, v)
|
||||
if err := pipe.Get(ctx, key).Err(); err != nil && err != redis.Nil {
|
||||
return nil, nil, err
|
||||
func (c *msgCache) GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsgs []*sdkws.MsgData, failedSeqs []int64, err error) {
|
||||
for _, seq := range seqs {
|
||||
res, err := c.rdb.Get(ctx, c.getMessageCacheKey(conversationID, seq)).Result()
|
||||
if err != nil {
|
||||
log.ZError(ctx, "GetMessagesBySeq failed", err, "conversationID", conversationID, "seq", seq)
|
||||
failedSeqs = append(failedSeqs, seq)
|
||||
continue
|
||||
}
|
||||
}
|
||||
result, err := pipe.Exec(ctx)
|
||||
for i, v := range result {
|
||||
cmd := v.(*redis.StringCmd)
|
||||
if cmd.Err() != nil {
|
||||
failedSeqs = append(failedSeqs, seqs[i])
|
||||
} else {
|
||||
msg := sdkws.MsgData{}
|
||||
err = msgprocessor.String2Pb(cmd.Val(), &msg)
|
||||
if err == nil {
|
||||
if msg.Status != constant.MsgDeleted {
|
||||
seqMsgs = append(seqMsgs, &msg)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
log.ZWarn(ctx, "UnmarshalString failed", err, "conversationID", conversationID, "seq", seqs[i], "msg", cmd.Val())
|
||||
}
|
||||
failedSeqs = append(failedSeqs, seqs[i])
|
||||
msg := sdkws.MsgData{}
|
||||
if err = msgprocessor.String2Pb(res, &msg); err != nil {
|
||||
log.ZError(ctx, "GetMessagesBySeq Unmarshal failed", err, "res", res, "conversationID", conversationID, "seq", seq)
|
||||
failedSeqs = append(failedSeqs, seq)
|
||||
continue
|
||||
}
|
||||
if msg.Status == constant.MsgDeleted {
|
||||
failedSeqs = append(failedSeqs, seq)
|
||||
continue
|
||||
}
|
||||
seqMsgs = append(seqMsgs, &msg)
|
||||
}
|
||||
return seqMsgs, failedSeqs, err
|
||||
|
||||
return
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for _, v := range seqs {
|
||||
// // MESSAGE_CACHE:169.254.225.224_reliability1653387820_0_1
|
||||
// key := c.getMessageCacheKey(conversationID, v)
|
||||
// if err := pipe.Get(ctx, key).Err(); err != nil && err != redis.Nil {
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//}
|
||||
//result, err := pipe.Exec(ctx)
|
||||
//for i, v := range result {
|
||||
// cmd := v.(*redis.StringCmd)
|
||||
// if cmd.Err() != nil {
|
||||
// failedSeqs = append(failedSeqs, seqs[i])
|
||||
// } else {
|
||||
// msg := sdkws.MsgData{}
|
||||
// err = msgprocessor.String2Pb(cmd.Val(), &msg)
|
||||
// if err == nil {
|
||||
// if msg.Status != constant.MsgDeleted {
|
||||
// seqMsgs = append(seqMsgs, &msg)
|
||||
// continue
|
||||
// }
|
||||
// } else {
|
||||
// log.ZWarn(ctx, "UnmarshalString failed", err, "conversationID", conversationID, "seq", seqs[i], "msg", cmd.Val())
|
||||
// }
|
||||
// failedSeqs = append(failedSeqs, seqs[i])
|
||||
// }
|
||||
//}
|
||||
//return seqMsgs, failedSeqs, err
|
||||
}
|
||||
|
||||
func (c *msgCache) SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) {
|
||||
pipe := c.rdb.Pipeline()
|
||||
var failedMsgs []*sdkws.MsgData
|
||||
for _, msg := range msgs {
|
||||
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
||||
s, err := msgprocessor.Pb2String(msg)
|
||||
if err != nil {
|
||||
return 0, errs.Wrap(err)
|
||||
}
|
||||
err = pipe.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err()
|
||||
if err != nil {
|
||||
failedMsgs = append(failedMsgs, msg)
|
||||
log.ZWarn(ctx, "set msg 2 cache failed", err, "msg", failedMsgs)
|
||||
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
||||
if err := c.rdb.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
return 0, errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
_, err := pipe.Exec(ctx)
|
||||
return len(failedMsgs), err
|
||||
return len(msgs), nil
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//var failedMsgs []*sdkws.MsgData
|
||||
//for _, msg := range msgs {
|
||||
// key := c.getMessageCacheKey(conversationID, msg.Seq)
|
||||
// s, err := msgprocessor.Pb2String(msg)
|
||||
// if err != nil {
|
||||
// return 0, errs.Wrap(err)
|
||||
// }
|
||||
// err = pipe.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err()
|
||||
// if err != nil {
|
||||
// failedMsgs = append(failedMsgs, msg)
|
||||
// log.ZWarn(ctx, "set msg 2 cache failed", err, "msg", failedMsgs)
|
||||
// }
|
||||
//}
|
||||
//_, err := pipe.Exec(ctx)
|
||||
//return len(failedMsgs), err
|
||||
}
|
||||
|
||||
func (c *msgCache) getMessageDelUserListKey(conversationID string, seq int64) string {
|
||||
@@ -420,27 +433,47 @@ func (c *msgCache) getUserDelList(conversationID, userID string) string {
|
||||
}
|
||||
|
||||
func (c *msgCache) UserDeleteMsgs(ctx context.Context, conversationID string, seqs []int64, userID string) error {
|
||||
pipe := c.rdb.Pipeline()
|
||||
for _, seq := range seqs {
|
||||
delUserListKey := c.getMessageDelUserListKey(conversationID, seq)
|
||||
userDelListKey := c.getUserDelList(conversationID, userID)
|
||||
err := pipe.SAdd(ctx, delUserListKey, userID).Err()
|
||||
err := c.rdb.SAdd(ctx, delUserListKey, userID).Err()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
err = pipe.SAdd(ctx, userDelListKey, seq).Err()
|
||||
err = c.rdb.SAdd(ctx, userDelListKey, seq).Err()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
if err := pipe.Expire(ctx, delUserListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
if err := c.rdb.Expire(ctx, delUserListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
if err := pipe.Expire(ctx, userDelListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
if err := c.rdb.Expire(ctx, userDelListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
_, err := pipe.Exec(ctx)
|
||||
return errs.Wrap(err)
|
||||
|
||||
return nil
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for _, seq := range seqs {
|
||||
// delUserListKey := c.getMessageDelUserListKey(conversationID, seq)
|
||||
// userDelListKey := c.getUserDelList(conversationID, userID)
|
||||
// err := pipe.SAdd(ctx, delUserListKey, userID).Err()
|
||||
// if err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
// err = pipe.SAdd(ctx, userDelListKey, seq).Err()
|
||||
// if err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
// if err := pipe.Expire(ctx, delUserListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
// if err := pipe.Expire(ctx, userDelListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
//}
|
||||
//_, err := pipe.Exec(ctx)
|
||||
//return errs.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *msgCache) GetUserDelList(ctx context.Context, userID, conversationID string) (seqs []int64, err error) {
|
||||
@@ -452,6 +485,7 @@ func (c *msgCache) GetUserDelList(ctx context.Context, userID, conversationID st
|
||||
for i, v := range result {
|
||||
seqs[i] = utils.StringToInt64(v)
|
||||
}
|
||||
|
||||
return seqs, nil
|
||||
}
|
||||
|
||||
@@ -460,67 +494,102 @@ func (c *msgCache) DelUserDeleteMsgsList(ctx context.Context, conversationID str
|
||||
delUsers, err := c.rdb.SMembers(ctx, c.getMessageDelUserListKey(conversationID, seq)).Result()
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq)
|
||||
|
||||
continue
|
||||
}
|
||||
if len(delUsers) > 0 {
|
||||
pipe := c.rdb.Pipeline()
|
||||
var failedFlag bool
|
||||
for _, userID := range delUsers {
|
||||
err = pipe.SRem(ctx, c.getUserDelList(conversationID, userID), seq).Err()
|
||||
err = c.rdb.SRem(ctx, c.getUserDelList(conversationID, userID), seq).Err()
|
||||
if err != nil {
|
||||
failedFlag = true
|
||||
log.ZWarn(
|
||||
ctx,
|
||||
"DelUserDeleteMsgsList failed",
|
||||
err,
|
||||
"conversationID",
|
||||
conversationID,
|
||||
"seq",
|
||||
seq,
|
||||
"userID",
|
||||
userID,
|
||||
)
|
||||
log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq, "userID", userID)
|
||||
}
|
||||
}
|
||||
if !failedFlag {
|
||||
if err := pipe.Del(ctx, c.getMessageDelUserListKey(conversationID, seq)).Err(); err != nil {
|
||||
if err := c.rdb.Del(ctx, c.getMessageDelUserListKey(conversationID, seq)).Err(); err != nil {
|
||||
log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq)
|
||||
}
|
||||
}
|
||||
if _, err := pipe.Exec(ctx); err != nil {
|
||||
log.ZError(ctx, "pipe exec failed", err, "conversationID", conversationID, "seq", seq)
|
||||
}
|
||||
}
|
||||
}
|
||||
//for _, seq := range seqs {
|
||||
// delUsers, err := c.rdb.SMembers(ctx, c.getMessageDelUserListKey(conversationID, seq)).Result()
|
||||
// if err != nil {
|
||||
// log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq)
|
||||
// continue
|
||||
// }
|
||||
// if len(delUsers) > 0 {
|
||||
// pipe := c.rdb.Pipeline()
|
||||
// var failedFlag bool
|
||||
// for _, userID := range delUsers {
|
||||
// err = pipe.SRem(ctx, c.getUserDelList(conversationID, userID), seq).Err()
|
||||
// if err != nil {
|
||||
// failedFlag = true
|
||||
// log.ZWarn(
|
||||
// ctx,
|
||||
// "DelUserDeleteMsgsList failed",
|
||||
// err,
|
||||
// "conversationID",
|
||||
// conversationID,
|
||||
// "seq",
|
||||
// seq,
|
||||
// "userID",
|
||||
// userID,
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// if !failedFlag {
|
||||
// if err := pipe.Del(ctx, c.getMessageDelUserListKey(conversationID, seq)).Err(); err != nil {
|
||||
// log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq)
|
||||
// }
|
||||
// }
|
||||
// if _, err := pipe.Exec(ctx); err != nil {
|
||||
// log.ZError(ctx, "pipe exec failed", err, "conversationID", conversationID, "seq", seq)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
func (c *msgCache) DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error {
|
||||
pipe := c.rdb.Pipeline()
|
||||
for _, seq := range seqs {
|
||||
if err := pipe.Del(ctx, c.getMessageCacheKey(conversationID, seq)).Err(); err != nil {
|
||||
if err := c.rdb.Del(ctx, c.getMessageCacheKey(conversationID, seq)).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
_, err := pipe.Exec(ctx)
|
||||
return errs.Wrap(err)
|
||||
return nil
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for _, seq := range seqs {
|
||||
// if err := pipe.Del(ctx, c.getMessageCacheKey(conversationID, seq)).Err(); err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
//}
|
||||
//_, err := pipe.Exec(ctx)
|
||||
//return errs.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *msgCache) CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error {
|
||||
vals, err := c.rdb.Keys(ctx, c.allMessageCacheKey(conversationID)).Result()
|
||||
if err == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
pipe := c.rdb.Pipeline()
|
||||
for _, v := range vals {
|
||||
if err := pipe.Del(ctx, v).Err(); err != nil {
|
||||
if err := c.rdb.Del(ctx, v).Err(); err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
_, err = pipe.Exec(ctx)
|
||||
return errs.Wrap(err)
|
||||
return nil
|
||||
//pipe := c.rdb.Pipeline()
|
||||
//for _, v := range vals {
|
||||
// if err := pipe.Del(ctx, v).Err(); err != nil {
|
||||
// return errs.Wrap(err)
|
||||
// }
|
||||
//}
|
||||
//_, err = pipe.Exec(ctx)
|
||||
//return errs.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []int64) error {
|
||||
@@ -528,13 +597,15 @@ func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []in
|
||||
key := c.getMessageCacheKey(userID, seq)
|
||||
result, err := c.rdb.Get(ctx, key).Result()
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
continue
|
||||
}
|
||||
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
var msg sdkws.MsgData
|
||||
if err := jsonpb.UnmarshalString(result, &msg); err != nil {
|
||||
err = jsonpb.UnmarshalString(result, &msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg.Status = constant.MsgDeleted
|
||||
@@ -546,6 +617,7 @@ func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []in
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -571,20 +643,12 @@ func (c *msgCache) SetSendMsgStatus(ctx context.Context, id string, status int32
|
||||
|
||||
func (c *msgCache) GetSendMsgStatus(ctx context.Context, id string) (int32, error) {
|
||||
result, err := c.rdb.Get(ctx, sendMsgFailedFlag+id).Int()
|
||||
|
||||
return int32(result), errs.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *msgCache) SetFcmToken(
|
||||
ctx context.Context,
|
||||
account string,
|
||||
platformID int,
|
||||
fcmToken string,
|
||||
expireTime int64,
|
||||
) (err error) {
|
||||
return errs.Wrap(
|
||||
c.rdb.Set(ctx, fcmToken+account+":"+strconv.Itoa(platformID), fcmToken, time.Duration(expireTime)*time.Second).
|
||||
Err(),
|
||||
)
|
||||
func (c *msgCache) SetFcmToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) (err error) {
|
||||
return errs.Wrap(c.rdb.Set(ctx, fcmToken+account+":"+strconv.Itoa(platformID), fcmToken, time.Duration(expireTime)*time.Second).Err())
|
||||
}
|
||||
|
||||
func (c *msgCache) GetFcmToken(ctx context.Context, account string, platformID int) (string, error) {
|
||||
@@ -597,6 +661,7 @@ func (c *msgCache) DelFcmToken(ctx context.Context, account string, platformID i
|
||||
|
||||
func (c *msgCache) IncrUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) {
|
||||
seq, err := c.rdb.Incr(ctx, userBadgeUnreadCountSum+userID).Result()
|
||||
|
||||
return int(seq), errs.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -610,11 +675,13 @@ func (c *msgCache) GetUserBadgeUnreadCountSum(ctx context.Context, userID string
|
||||
|
||||
func (c *msgCache) LockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error {
|
||||
key := exTypeKeyLocker + clientMsgID + "_" + TypeKey
|
||||
|
||||
return errs.Wrap(c.rdb.SetNX(ctx, key, 1, time.Minute).Err())
|
||||
}
|
||||
|
||||
func (c *msgCache) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error {
|
||||
key := exTypeKeyLocker + clientMsgID + "_" + TypeKey
|
||||
|
||||
return errs.Wrap(c.rdb.Del(ctx, key).Err())
|
||||
}
|
||||
|
||||
@@ -629,6 +696,7 @@ func (c *msgCache) getMessageReactionExPrefix(clientMsgID string, sessionType in
|
||||
case constant.NotificationChatType:
|
||||
return "EX_NOTIFICATION" + clientMsgID
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -637,6 +705,7 @@ func (c *msgCache) JudgeMessageReactionExist(ctx context.Context, clientMsgID st
|
||||
if err != nil {
|
||||
return false, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
|
||||
Vendored
+103
-81
@@ -17,6 +17,7 @@ package cache
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"hash/crc32"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -70,6 +71,7 @@ func NewUserCacheRedis(
|
||||
options rockscache.Options,
|
||||
) UserCache {
|
||||
rcClient := rockscache.NewClient(rdb, options)
|
||||
|
||||
return &UserCacheRedis{
|
||||
rdb: rdb,
|
||||
metaCache: NewMetaCacheRedis(rcClient),
|
||||
@@ -97,10 +99,6 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
|
||||
return userGlobalRecvMsgOptKey + userID
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) getUserStatusHashKey(userID string, Id int32) string {
|
||||
return userID + "_" + string(Id) + platformID
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) {
|
||||
return getCache(
|
||||
ctx,
|
||||
@@ -114,36 +112,42 @@ func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userIn
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) {
|
||||
var keys []string
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, u.getUserInfoKey(userID))
|
||||
}
|
||||
return batchGetCache(
|
||||
ctx,
|
||||
u.rcClient,
|
||||
keys,
|
||||
u.expireTime,
|
||||
func(user *relationtb.UserModel, keys []string) (int, error) {
|
||||
for i, key := range keys {
|
||||
if key == u.getUserInfoKey(user.UserID) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return 0, errIndex
|
||||
},
|
||||
func(ctx context.Context) ([]*relationtb.UserModel, error) {
|
||||
return u.userDB.Find(ctx, userIDs)
|
||||
},
|
||||
)
|
||||
//var keys []string
|
||||
//for _, userID := range userIDs {
|
||||
// keys = append(keys, u.getUserInfoKey(userID))
|
||||
//}
|
||||
//return batchGetCache(
|
||||
// ctx,
|
||||
// u.rcClient,
|
||||
// keys,
|
||||
// u.expireTime,
|
||||
// func(user *relationtb.UserModel, keys []string) (int, error) {
|
||||
// for i, key := range keys {
|
||||
// if key == u.getUserInfoKey(user.UserID) {
|
||||
// return i, nil
|
||||
// }
|
||||
// }
|
||||
// return 0, errIndex
|
||||
// },
|
||||
// func(ctx context.Context) ([]*relationtb.UserModel, error) {
|
||||
// return u.userDB.Find(ctx, userIDs)
|
||||
// },
|
||||
//)
|
||||
return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string {
|
||||
return u.getUserInfoKey(userID)
|
||||
}, func(ctx context.Context, userID string) (*relationtb.UserModel, error) {
|
||||
return u.userDB.Take(ctx, userID)
|
||||
})
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) DelUsersInfo(userIDs ...string) UserCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, u.getUserInfoKey(userID))
|
||||
}
|
||||
cache := u.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
@@ -160,22 +164,19 @@ func (u *UserCacheRedis) GetUserGlobalRecvMsgOpt(ctx context.Context, userID str
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache {
|
||||
var keys []string
|
||||
keys := make([]string, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
keys = append(keys, u.getUserGlobalRecvMsgOptKey(userID))
|
||||
}
|
||||
cache := u.NewCache()
|
||||
cache.AddKeys(keys...)
|
||||
return cache
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) getOnlineStatusKey(userID string) string {
|
||||
return olineStatusKey + userID
|
||||
return cache
|
||||
}
|
||||
|
||||
// GetUserStatus get user status.
|
||||
func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) {
|
||||
var res []*user.OnlineStatus
|
||||
userStatus := make([]*user.OnlineStatus, 0, len(userIDs))
|
||||
for _, userID := range userIDs {
|
||||
UserIDNum := crc32.ChecksumIEEE([]byte(userID))
|
||||
modKey := strconv.Itoa(int(UserIDNum % statusMod))
|
||||
@@ -183,13 +184,14 @@ func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([
|
||||
key := olineStatusKey + modKey
|
||||
result, err := u.rdb.HGet(ctx, key, userID).Result()
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
// key or field does not exist
|
||||
res = append(res, &user.OnlineStatus{
|
||||
userStatus = append(userStatus, &user.OnlineStatus{
|
||||
UserID: userID,
|
||||
Status: constant.Offline,
|
||||
PlatformIDs: nil,
|
||||
})
|
||||
|
||||
continue
|
||||
} else {
|
||||
return nil, errs.Wrap(err)
|
||||
@@ -201,9 +203,10 @@ func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([
|
||||
}
|
||||
onlineStatus.UserID = userID
|
||||
onlineStatus.Status = constant.Online
|
||||
res = append(res, &onlineStatus)
|
||||
userStatus = append(userStatus, &onlineStatus)
|
||||
}
|
||||
return res, nil
|
||||
|
||||
return userStatus, nil
|
||||
}
|
||||
|
||||
// SetUserStatus Set the user status and save it in redis.
|
||||
@@ -224,15 +227,16 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
Status: constant.Online,
|
||||
PlatformIDs: []int32{platformID},
|
||||
}
|
||||
jsonData, err := json.Marshal(onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
jsonData, err2 := json.Marshal(&onlineStatus)
|
||||
if err2 != nil {
|
||||
return errs.Wrap(err2)
|
||||
}
|
||||
_, err = u.rdb.HSet(ctx, key, userID, string(jsonData)).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
_, err2 = u.rdb.HSet(ctx, key, userID, string(jsonData)).Result()
|
||||
if err2 != nil {
|
||||
return errs.Wrap(err2)
|
||||
}
|
||||
u.rdb.Expire(ctx, key, userOlineStatusExpireTime)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -240,7 +244,7 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
isNil := false
|
||||
result, err := u.rdb.HGet(ctx, key, userID).Result()
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
isNil = true
|
||||
} else {
|
||||
return errs.Wrap(err)
|
||||
@@ -248,51 +252,45 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
}
|
||||
|
||||
if status == constant.Offline {
|
||||
if isNil {
|
||||
log.ZWarn(ctx, "this user not online,maybe trigger order not right",
|
||||
err, "userStatus", status)
|
||||
return nil
|
||||
err = u.refreshStatusOffline(ctx, userID, status, platformID, isNil, err, result, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var onlineStatus user.OnlineStatus
|
||||
err = json.Unmarshal([]byte(result), &onlineStatus)
|
||||
} else {
|
||||
err = u.refreshStatusOnline(ctx, userID, platformID, isNil, err, result, key)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
var newPlatformIDs []int32
|
||||
for _, val := range onlineStatus.PlatformIDs {
|
||||
if val != platformID {
|
||||
newPlatformIDs = append(newPlatformIDs, val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) refreshStatusOffline(ctx context.Context, userID string, status, platformID int32, isNil bool, err error, result, key string) error {
|
||||
if isNil {
|
||||
log.ZWarn(ctx, "this user not online,maybe trigger order not right",
|
||||
err, "userStatus", status)
|
||||
|
||||
return nil
|
||||
}
|
||||
var onlineStatus user.OnlineStatus
|
||||
err = json.Unmarshal([]byte(result), &onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
var newPlatformIDs []int32
|
||||
for _, val := range onlineStatus.PlatformIDs {
|
||||
if val != platformID {
|
||||
newPlatformIDs = append(newPlatformIDs, val)
|
||||
}
|
||||
if newPlatformIDs == nil {
|
||||
_, err = u.rdb.HDel(ctx, key, userID).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
} else {
|
||||
onlineStatus.PlatformIDs = newPlatformIDs
|
||||
newjsonData, err := json.Marshal(&onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
_, err = u.rdb.HSet(ctx, key, userID, string(newjsonData)).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
if newPlatformIDs == nil {
|
||||
_, err = u.rdb.HDel(ctx, key, userID).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
} else {
|
||||
var onlineStatus user.OnlineStatus
|
||||
if !isNil {
|
||||
err = json.Unmarshal([]byte(result), &onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
onlineStatus.PlatformIDs = RemoveRepeatedElementsInList(append(onlineStatus.PlatformIDs, platformID))
|
||||
} else {
|
||||
onlineStatus.PlatformIDs = append(onlineStatus.PlatformIDs, platformID)
|
||||
}
|
||||
onlineStatus.Status = constant.Online
|
||||
onlineStatus.UserID = userID
|
||||
onlineStatus.PlatformIDs = newPlatformIDs
|
||||
newjsonData, err := json.Marshal(&onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
@@ -301,7 +299,31 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *UserCacheRedis) refreshStatusOnline(ctx context.Context, userID string, platformID int32, isNil bool, err error, result, key string) error {
|
||||
var onlineStatus user.OnlineStatus
|
||||
if !isNil {
|
||||
err2 := json.Unmarshal([]byte(result), &onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err2)
|
||||
}
|
||||
onlineStatus.PlatformIDs = RemoveRepeatedElementsInList(append(onlineStatus.PlatformIDs, platformID))
|
||||
} else {
|
||||
onlineStatus.PlatformIDs = append(onlineStatus.PlatformIDs, platformID)
|
||||
}
|
||||
onlineStatus.Status = constant.Online
|
||||
onlineStatus.UserID = userID
|
||||
newjsonData, err := json.Marshal(&onlineStatus)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
_, err = u.rdb.HSet(ctx, key, userID, string(newjsonData)).Result()
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -69,9 +69,9 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
||||
}
|
||||
}
|
||||
if len(deleteTokenKey) != 0 {
|
||||
err := a.cache.DeleteTokenByUidPid(ctx, userID, platformID, deleteTokenKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
err2 := a.cache.DeleteTokenByUidPid(ctx, userID, platformID, deleteTokenKey)
|
||||
if err2 != nil {
|
||||
return "", err2
|
||||
}
|
||||
}
|
||||
claims := tokenverify.BuildClaims(userID, platformID, a.accessExpire)
|
||||
@@ -80,5 +80,6 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return tokenString, a.cache.AddTokenFlag(ctx, userID, platformID, tokenString, constant.NormalToken)
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ func (b *blackDatabase) Create(ctx context.Context, blacks []*relation.BlackMode
|
||||
if err := b.black.Create(ctx, blacks); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.deleteBlackIDsCache(ctx, blacks)
|
||||
}
|
||||
|
||||
@@ -63,6 +64,7 @@ func (b *blackDatabase) Delete(ctx context.Context, blacks []*relation.BlackMode
|
||||
if err := b.black.Delete(ctx, blacks); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return b.deleteBlackIDsCache(ctx, blacks)
|
||||
}
|
||||
|
||||
@@ -71,6 +73,7 @@ func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*relat
|
||||
for _, black := range blacks {
|
||||
cache = cache.DelBlackIDs(ctx, black.OwnerUserID)
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -97,6 +100,7 @@ func (b *blackDatabase) CheckIn(
|
||||
return
|
||||
}
|
||||
log.ZDebug(ctx, "blackIDs", "user1BlackIDs", userID1BlackIDs, "user2BlackIDs", userID2BlackIDs)
|
||||
|
||||
return utils.IsContain(userID2, userID1BlackIDs), utils.IsContain(userID1, userID2BlackIDs), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ type ConversationDatabase interface {
|
||||
GetConversationIDs(ctx context.Context, userID string) ([]string, error)
|
||||
GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error)
|
||||
GetAllConversationIDs(ctx context.Context) ([]string, error)
|
||||
GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
//GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error)
|
||||
GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error)
|
||||
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
||||
@@ -99,8 +99,8 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context,
|
||||
now := time.Now()
|
||||
for _, v := range NotUserIDs {
|
||||
temp := new(relationtb.ConversationModel)
|
||||
if err := utils.CopyStructFields(temp, conversation); err != nil {
|
||||
return err
|
||||
if err2 := utils.CopyStructFields(temp, conversation); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
temp.OwnerUserID = v
|
||||
temp.CreateTime = now
|
||||
@@ -113,10 +113,12 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context,
|
||||
}
|
||||
cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -130,6 +132,7 @@ func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context,
|
||||
if _, ok := args["recv_msg_opt"]; ok {
|
||||
cache = cache.DelConversationNotReceiveMessageUserIDs(conversationID)
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -137,13 +140,14 @@ func (c *conversationDatabase) CreateConversation(ctx context.Context, conversat
|
||||
if err := c.conversationDB.Create(ctx, conversations); err != nil {
|
||||
return err
|
||||
}
|
||||
var userIDs []string
|
||||
userIDs := make([]string, 0, len(conversations))
|
||||
cache := c.cache.NewCache()
|
||||
for _, conversation := range conversations {
|
||||
cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID)
|
||||
cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID)
|
||||
userIDs = append(userIDs, conversation.OwnerUserID)
|
||||
}
|
||||
|
||||
return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -178,10 +182,12 @@ func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Con
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -234,12 +240,15 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID).DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...)
|
||||
cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID)
|
||||
cache = cache.DelConversationNotReceiveMessageUserIDs(utils.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -276,10 +285,12 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context,
|
||||
for _, v := range existConversationUserIDs {
|
||||
cache = cache.DelConversations(v, conversationID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -295,9 +306,9 @@ func (c *conversationDatabase) GetAllConversationIDs(ctx context.Context) ([]str
|
||||
return c.conversationDB.GetAllConversationIDs(ctx)
|
||||
}
|
||||
|
||||
func (c *conversationDatabase) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) {
|
||||
return c.cache.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
}
|
||||
//func (c *conversationDatabase) GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) {
|
||||
// return c.cache.GetUserAllHasReadSeqs(ctx, ownerUserID)
|
||||
//}
|
||||
|
||||
func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) {
|
||||
return c.conversationDB.GetConversationsByConversationID(ctx, conversationIDs)
|
||||
|
||||
@@ -16,6 +16,7 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -109,6 +110,7 @@ func (f *friendDatabase) CheckIn(
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return utils.IsContain(userID2, userID1FriendIDs), utils.IsContain(userID1, userID2FriendIDs), nil
|
||||
}
|
||||
|
||||
@@ -121,8 +123,8 @@ func (f *friendDatabase) AddFriendRequest(
|
||||
) (err error) {
|
||||
return f.tx.Transaction(func(tx any) error {
|
||||
_, err := f.friendRequest.NewTx(tx).Take(ctx, fromUserID, toUserID)
|
||||
// 有db错误
|
||||
if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound {
|
||||
// if there is a db error
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
// 无错误 则更新
|
||||
@@ -136,12 +138,14 @@ func (f *friendDatabase) AddFriendRequest(
|
||||
if err := f.friendRequest.NewTx(tx).UpdateByMap(ctx, fromUserID, toUserID, m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
// gorm.ErrRecordNotFound 错误,则新增
|
||||
if err := f.friendRequest.NewTx(tx).Create(ctx, []*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -154,11 +158,11 @@ func (f *friendDatabase) BecomeFriends(
|
||||
addSource int32,
|
||||
) (err error) {
|
||||
cache := f.cache.NewCache()
|
||||
if err := f.tx.Transaction(func(tx any) error {
|
||||
// 先find 找出重复的 去掉重复的
|
||||
fs1, err := f.friend.NewTx(tx).FindFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
fn := func(tx any) error {
|
||||
// first,find and drop delete ones
|
||||
fs1, err2 := f.friend.NewTx(tx).FindFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
opUserID := mcontext.GetOperationID(ctx)
|
||||
for _, v := range friendUserIDs {
|
||||
@@ -168,13 +172,13 @@ func (f *friendDatabase) BecomeFriends(
|
||||
return e.FriendUserID
|
||||
})
|
||||
|
||||
err = f.friend.NewTx(tx).Create(ctx, fs11)
|
||||
if err != nil {
|
||||
return err
|
||||
err2 = f.friend.NewTx(tx).Create(ctx, fs11)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
fs2, err := f.friend.NewTx(tx).FindReversalFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
fs2, err2 := f.friend.NewTx(tx).FindReversalFriends(ctx, ownerUserID, friendUserIDs)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
var newFriendIDs []string
|
||||
for _, v := range friendUserIDs {
|
||||
@@ -184,16 +188,20 @@ func (f *friendDatabase) BecomeFriends(
|
||||
fs22 := utils.DistinctAny(fs2, func(e *relation.FriendModel) string {
|
||||
return e.OwnerUserID
|
||||
})
|
||||
err = f.friend.NewTx(tx).Create(ctx, fs22)
|
||||
if err != nil {
|
||||
return err
|
||||
err2 = f.friend.NewTx(tx).Create(ctx, fs22)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
newFriendIDs = append(newFriendIDs, ownerUserID)
|
||||
cache = cache.DelFriendIDs(newFriendIDs...)
|
||||
return nil
|
||||
}); err != nil {
|
||||
|
||||
return nil
|
||||
}
|
||||
err = f.tx.Transaction(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -216,6 +224,7 @@ func (f *friendDatabase) RefuseFriendRequest(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -251,7 +260,7 @@ func (f *friendDatabase) AgreeFriendRequest(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound {
|
||||
} else if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -290,6 +299,7 @@ func (f *friendDatabase) AgreeFriendRequest(
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return f.cache.DelFriendIDs(friendRequest.ToUserID, friendRequest.FromUserID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
@@ -299,6 +309,7 @@ func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendU
|
||||
if err := f.friend.Delete(ctx, ownerUserID, friendUserIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f.cache.DelFriendIDs(append(friendUserIDs, ownerUserID)...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -307,6 +318,7 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs
|
||||
if err := f.friend.UpdateRemark(ctx, ownerUserID, friendUserID, remark); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -359,6 +371,7 @@ func (f *friendDatabase) FindFriendsWithError(
|
||||
if len(friends) != len(friendUserIDs) {
|
||||
err = errs.ErrRecordNotFound.Wrap()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ func NewGroupDatabase(
|
||||
cache: cache,
|
||||
mongoDB: superGroup,
|
||||
}
|
||||
|
||||
return database
|
||||
}
|
||||
|
||||
@@ -109,6 +110,7 @@ func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.D
|
||||
rcOptions := rockscache.NewDefaultOptions()
|
||||
rcOptions.StrongConsistency = true
|
||||
rcOptions.RandomExpireAdjustment = 0.2
|
||||
|
||||
return NewGroupDatabase(
|
||||
relation.NewGroupDB(db),
|
||||
relation.NewGroupMemberDB(db),
|
||||
@@ -151,6 +153,7 @@ func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return uint32(num), nil
|
||||
}
|
||||
|
||||
@@ -184,10 +187,12 @@ func (g *groupDatabase) CreateGroup(
|
||||
cache = cache.DelJoinedGroupID(groupMember.UserID).DelGroupMembersInfo(groupMember.GroupID, groupMember.UserID)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(createGroupIDs...)
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -211,6 +216,7 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma
|
||||
if err := g.groupDB.UpdateMap(ctx, groupID, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelGroupsInfo(groupID).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -231,10 +237,12 @@ func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, delete
|
||||
cache = cache.DelJoinedGroupID(userIDs...).DelGroupMemberIDs(groupID).DelGroupsMemberNum(groupID).DelGroupMembersHash(groupID)
|
||||
}
|
||||
cache = cache.DelGroupsInfo(groupID)
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -276,6 +284,7 @@ func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string,
|
||||
}
|
||||
res = append(res, v)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
if len(roleLevels) == 0 {
|
||||
@@ -286,8 +295,10 @@ func (g *groupDatabase) FindGroupMember(ctx context.Context, groupIDs []string,
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
|
||||
return totalGroupMembers, nil
|
||||
}
|
||||
|
||||
return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels)
|
||||
}
|
||||
|
||||
@@ -307,6 +318,7 @@ func (g *groupDatabase) PageGetJoinGroup(
|
||||
}
|
||||
totalGroupMembers = append(totalGroupMembers, groupMembers...)
|
||||
}
|
||||
|
||||
return uint32(len(groupIDs)), totalGroupMembers, nil
|
||||
}
|
||||
|
||||
@@ -327,6 +339,7 @@ func (g *groupDatabase) PageGetGroupMember(
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
return uint32(len(groupMemberIDs)), members, nil
|
||||
}
|
||||
|
||||
@@ -378,6 +391,7 @@ func (g *groupDatabase) HandlerGroupRequest(
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -386,6 +400,7 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u
|
||||
if err := g.groupMemberDB.Delete(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelGroupMembersHash(groupID).
|
||||
DelGroupMemberIDs(groupID).
|
||||
DelGroupsMemberNum(groupID).
|
||||
@@ -410,6 +425,7 @@ func (g *groupDatabase) MapGroupMemberNum(ctx context.Context, groupIDs []string
|
||||
}
|
||||
m[groupID] = uint32(num)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -429,6 +445,7 @@ func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string,
|
||||
if rowsAffected != 1 {
|
||||
return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "")
|
||||
}
|
||||
|
||||
return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID).DelGroupMembersHash(groupID).ExecDel(ctx)
|
||||
})
|
||||
}
|
||||
@@ -442,6 +459,7 @@ func (g *groupDatabase) UpdateGroupMember(
|
||||
if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelGroupMembersInfo(groupID, userID).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -454,10 +472,12 @@ func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relation
|
||||
}
|
||||
cache = cache.DelGroupMembersInfo(item.GroupID, item.UserID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -469,6 +489,7 @@ func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*rela
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return db.Create(ctx, requests)
|
||||
})
|
||||
}
|
||||
@@ -504,6 +525,7 @@ func (g *groupDatabase) CreateSuperGroup(ctx context.Context, groupID string, in
|
||||
if err := g.mongoDB.CreateSuperGroup(ctx, groupID, initMemberIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(initMemberIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -521,10 +543,12 @@ func (g *groupDatabase) DeleteSuperGroup(ctx context.Context, groupID string) er
|
||||
if len(models) > 0 {
|
||||
cache = cache.DelJoinedSuperGroupIDs(models[0].MemberIDs...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -532,6 +556,7 @@ func (g *groupDatabase) DeleteSuperGroupMember(ctx context.Context, groupID stri
|
||||
if err := g.mongoDB.RemoverUserFromSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -539,6 +564,7 @@ func (g *groupDatabase) CreateSuperGroupMember(ctx context.Context, groupID stri
|
||||
if err := g.mongoDB.AddUserToSuperGroup(ctx, groupID, userIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return g.cache.DelSuperGroupMemberIDs(groupID).DelJoinedSuperGroupIDs(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
|
||||
+291
-179
@@ -135,6 +135,7 @@ func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database)
|
||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
||||
msgDocModel := unrelation.NewMsgMongoDriver(database)
|
||||
CommonMsgDatabase := NewCommonMsgDatabase(msgDocModel, cacheModel)
|
||||
|
||||
return CommonMsgDatabase
|
||||
}
|
||||
|
||||
@@ -150,14 +151,17 @@ type commonMsgDatabase struct {
|
||||
|
||||
func (db *commonMsgDatabase) MsgToMQ(ctx context.Context, key string, msg2mq *sdkws.MsgData) error {
|
||||
_, _, err := db.producer.SendMessage(ctx, key, msg2mq)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) MsgToModifyMQ(ctx context.Context, key, conversationID string, messages []*sdkws.MsgData) error {
|
||||
if len(messages) > 0 {
|
||||
_, _, err := db.producerToModify.SendMessage(ctx, key, &pbmsg.MsgDataToModifyByMQ{ConversationID: conversationID, Messages: messages})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -165,26 +169,26 @@ func (db *commonMsgDatabase) MsgToPushMQ(ctx context.Context, key, conversationI
|
||||
partition, offset, err := db.producerToPush.SendMessage(ctx, key, &pbmsg.PushMsgDataToMQ{MsgData: msg2mq, ConversationID: conversationID})
|
||||
if err != nil {
|
||||
log.ZError(ctx, "MsgToPushMQ", err, "key", key, "msg2mq", msg2mq)
|
||||
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return partition, offset, nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) MsgToMongoMQ(ctx context.Context, key, conversationID string, messages []*sdkws.MsgData, lastSeq int64) error {
|
||||
if len(messages) > 0 {
|
||||
_, _, err := db.producerToMongo.SendMessage(ctx, key, &pbmsg.MsgDataToMongoByMQ{LastSeq: lastSeq, ConversationID: conversationID, MsgData: messages})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationID string, fields []any, key int8, firstSeq int64) error {
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
}
|
||||
num := db.msg.GetSingleGocMsgNum()
|
||||
func checkTypeForBatchInsertBlock(fields []any, key int8, firstSeq int64) error {
|
||||
// num = 100
|
||||
for i, field := range fields { // 检查类型
|
||||
for i, field := range fields { // check type
|
||||
var ok bool
|
||||
switch key {
|
||||
case updateKeyMsg:
|
||||
@@ -202,80 +206,106 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI
|
||||
return errs.ErrInternalServer.Wrap("field type is invalid")
|
||||
}
|
||||
}
|
||||
// 返回值为true表示数据库存在该文档,false表示数据库不存在该文档
|
||||
updateMsgModel := func(seq int64, i int) (bool, error) {
|
||||
var (
|
||||
res *mongo.UpdateResult
|
||||
err error
|
||||
)
|
||||
docID := db.msg.GetDocID(conversationID, seq)
|
||||
index := db.msg.GetMsgIndex(seq)
|
||||
field := fields[i]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) updateMsgModelForBatchInsertBlock(ctx context.Context, conversationID string, fields []any, key int8, seq int64, i int) (bool, error) {
|
||||
var (
|
||||
res *mongo.UpdateResult
|
||||
err error
|
||||
)
|
||||
docID := db.msg.GetDocID(conversationID, seq)
|
||||
index := db.msg.GetMsgIndex(seq)
|
||||
field := fields[i]
|
||||
switch key {
|
||||
case updateKeyMsg:
|
||||
res, err = db.msgDocDatabase.UpdateMsg(ctx, docID, index, "msg", field)
|
||||
case updateKeyRevoke:
|
||||
res, err = db.msgDocDatabase.UpdateMsg(ctx, docID, index, "revoke", field)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return res.MatchedCount > 0, nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) newDocForBatchInsertBlock(conversationID string, fields []any, key int8, seq, firstSeq, num int64, i int) (unrelationtb.MsgDocModel, int) {
|
||||
doc := unrelationtb.MsgDocModel{
|
||||
DocID: db.msg.GetDocID(conversationID, seq),
|
||||
Msg: make([]*unrelationtb.MsgInfoModel, num),
|
||||
}
|
||||
var insert int // number of inserted
|
||||
for j := i; j < len(fields); j++ {
|
||||
seq = firstSeq + int64(j)
|
||||
if db.msg.GetDocID(conversationID, seq) != doc.DocID {
|
||||
break
|
||||
}
|
||||
insert++
|
||||
switch key {
|
||||
case updateKeyMsg:
|
||||
res, err = db.msgDocDatabase.UpdateMsg(ctx, docID, index, "msg", field)
|
||||
doc.Msg[db.msg.GetMsgIndex(seq)] = &unrelationtb.MsgInfoModel{
|
||||
Msg: fields[j].(*unrelationtb.MsgDataModel),
|
||||
}
|
||||
case updateKeyRevoke:
|
||||
res, err = db.msgDocDatabase.UpdateMsg(ctx, docID, index, "revoke", field)
|
||||
doc.Msg[db.msg.GetMsgIndex(seq)] = &unrelationtb.MsgInfoModel{
|
||||
Revoke: fields[j].(*unrelationtb.RevokeModel),
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for i, model := range doc.Msg {
|
||||
if model == nil {
|
||||
model = &unrelationtb.MsgInfoModel{}
|
||||
doc.Msg[i] = model
|
||||
}
|
||||
return res.MatchedCount > 0, nil
|
||||
if model.DelList == nil {
|
||||
doc.Msg[i].DelList = []string{}
|
||||
}
|
||||
}
|
||||
|
||||
return doc, insert
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationID string, fields []any, key int8, firstSeq int64) error {
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
}
|
||||
num := db.msg.GetSingleGocMsgNum()
|
||||
// num = 100
|
||||
err := checkTypeForBatchInsertBlock(fields, key, firstSeq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tryUpdate := true
|
||||
for i := 0; i < len(fields); i++ {
|
||||
seq := firstSeq + int64(i) // 当前seq
|
||||
seq := firstSeq + int64(i) // current seq
|
||||
// try update
|
||||
if tryUpdate {
|
||||
matched, err := updateMsgModel(seq, i)
|
||||
matched, err := db.updateMsgModelForBatchInsertBlock(ctx, conversationID, fields, key, seq, i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if matched {
|
||||
continue // 匹配到了,继续下一个(不一定修改)
|
||||
}
|
||||
}
|
||||
doc := unrelationtb.MsgDocModel{
|
||||
DocID: db.msg.GetDocID(conversationID, seq),
|
||||
Msg: make([]*unrelationtb.MsgInfoModel, num),
|
||||
}
|
||||
var insert int // 插入的数量
|
||||
for j := i; j < len(fields); j++ {
|
||||
seq = firstSeq + int64(j)
|
||||
if db.msg.GetDocID(conversationID, seq) != doc.DocID {
|
||||
break
|
||||
}
|
||||
insert++
|
||||
switch key {
|
||||
case updateKeyMsg:
|
||||
doc.Msg[db.msg.GetMsgIndex(seq)] = &unrelationtb.MsgInfoModel{
|
||||
Msg: fields[j].(*unrelationtb.MsgDataModel),
|
||||
}
|
||||
case updateKeyRevoke:
|
||||
doc.Msg[db.msg.GetMsgIndex(seq)] = &unrelationtb.MsgInfoModel{
|
||||
Revoke: fields[j].(*unrelationtb.RevokeModel),
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, model := range doc.Msg {
|
||||
if model == nil {
|
||||
model = &unrelationtb.MsgInfoModel{}
|
||||
doc.Msg[i] = model
|
||||
}
|
||||
if model.DelList == nil {
|
||||
doc.Msg[i].DelList = []string{}
|
||||
continue // if matched,skip
|
||||
}
|
||||
}
|
||||
doc, insert := db.newDocForBatchInsertBlock(conversationID, fields, key, seq, firstSeq, num, i)
|
||||
// insert doc into db
|
||||
if err := db.msgDocDatabase.Create(ctx, &doc); err != nil {
|
||||
if mongo.IsDuplicateKeyError(err) {
|
||||
i-- // 存在并发,重试当前数据
|
||||
tryUpdate = true // 以修改模式
|
||||
i-- // exists concurrent,
|
||||
tryUpdate = true // try update
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
tryUpdate = false // 当前以插入成功,下一块优先插入模式
|
||||
i += insert - 1 // 跳过已插入的数据
|
||||
tryUpdate = false // if insert success,change to insert mode
|
||||
i += insert - 1 // skip inserted data
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -322,6 +352,7 @@ func (db *commonMsgDatabase) BatchInsertChat2DB(ctx context.Context, conversatio
|
||||
Ex: msg.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
return db.BatchInsertBlock(ctx, conversationID, msgs, updateKeyMsg, msgList[0].Seq)
|
||||
}
|
||||
|
||||
@@ -338,9 +369,11 @@ func (db *commonMsgDatabase) MarkSingleChatMsgsAsRead(ctx context.Context, userI
|
||||
log.ZDebug(ctx, "MarkSingleChatMsgsAsRead", "userID", userID, "docID", docID, "indexes", indexes)
|
||||
if err := db.msgDocDatabase.MarkSingleChatMsgsAsRead(ctx, userID, docID, indexes); err != nil {
|
||||
log.ZError(ctx, "MarkSingleChatMsgsAsRead", err, "userID", userID, "docID", docID, "indexes", indexes)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -354,8 +387,9 @@ func (db *commonMsgDatabase) DelUserDeleteMsgsList(ctx context.Context, conversa
|
||||
|
||||
func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (seq int64, isNew bool, err error) {
|
||||
currentMaxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
prome.Inc(prome.SeqGetFailedCounter)
|
||||
|
||||
return 0, false, err
|
||||
}
|
||||
prome.Inc(prome.SeqGetSuccessCounter)
|
||||
@@ -366,7 +400,7 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
|
||||
if lenList < 1 {
|
||||
return 0, false, errors.New("too short as 0")
|
||||
}
|
||||
if errs.Unwrap(err) == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
isNew = true
|
||||
}
|
||||
lastMaxSeq := currentMaxSeq
|
||||
@@ -396,6 +430,7 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
|
||||
} else {
|
||||
prome.Inc(prome.SeqSetSuccessCounter)
|
||||
}
|
||||
|
||||
return lastMaxSeq, isNew, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
@@ -410,6 +445,7 @@ func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversat
|
||||
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
|
||||
}
|
||||
}
|
||||
|
||||
return totalMsgs, nil
|
||||
}
|
||||
|
||||
@@ -420,6 +456,7 @@ func (db *commonMsgDatabase) findMsgInfoBySeq(ctx context.Context, userID, docID
|
||||
msg.Msg.IsRead = true
|
||||
}
|
||||
}
|
||||
|
||||
return msgs, err
|
||||
}
|
||||
|
||||
@@ -438,16 +475,76 @@ func (db *commonMsgDatabase) getMsgBySeqsRange(ctx context.Context, userID strin
|
||||
seqMsgs = append(seqMsgs, convert.MsgDB2Pb(msg.Msg))
|
||||
}
|
||||
}
|
||||
|
||||
return seqMsgs, nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) getCacheMsgForGetMsgBySeqsRange(ctx context.Context, userID string, conversationID string, begin int64, seqs []int64) ([]*sdkws.MsgData, []int64, error) {
|
||||
newBegin := seqs[0]
|
||||
newEnd := seqs[len(seqs)-1]
|
||||
log.ZDebug(ctx, "GetMsgBySeqsRange", "first seqs", seqs, "newBegin", newBegin, "newEnd", newEnd)
|
||||
cachedMsgs, failedSeqs, err := db.cache.GetMessagesBySeq(ctx, conversationID, seqs)
|
||||
if err != nil {
|
||||
if !errors.Is(err, redis.Nil) {
|
||||
prome.Add(prome.MsgPullFromRedisFailedCounter, len(failedSeqs))
|
||||
log.ZError(ctx, "get message from redis exception", err, "conversationID", conversationID, "seqs", seqs)
|
||||
}
|
||||
}
|
||||
var successMsgs []*sdkws.MsgData
|
||||
if len(cachedMsgs) == 0 {
|
||||
return successMsgs, failedSeqs, err
|
||||
}
|
||||
// if len(cachedMsgs) > 0
|
||||
delSeqs, err2 := db.cache.GetUserDelList(ctx, userID, conversationID)
|
||||
if err2 != nil && !errors.Is(err2, redis.Nil) {
|
||||
return nil, nil, err2
|
||||
}
|
||||
var cacheDelNum int
|
||||
for _, msg := range cachedMsgs {
|
||||
if !utils.Contain(msg.Seq, delSeqs...) {
|
||||
successMsgs = append(successMsgs, msg)
|
||||
} else {
|
||||
cacheDelNum += 1
|
||||
}
|
||||
}
|
||||
log.ZDebug(ctx, "get delSeqs from redis", "delSeqs", delSeqs, "userID", userID, "conversationID", conversationID, "cacheDelNum", cacheDelNum)
|
||||
var reGetSeqsCache []int64
|
||||
for i := 1; i <= cacheDelNum; {
|
||||
newSeq := newBegin - int64(i)
|
||||
if newSeq >= begin {
|
||||
if !utils.Contain(newSeq, delSeqs...) {
|
||||
log.ZDebug(ctx, "seq del in cache, a new seq in range append", "new seq", newSeq)
|
||||
reGetSeqsCache = append(reGetSeqsCache, newSeq)
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(reGetSeqsCache) > 0 {
|
||||
log.ZDebug(ctx, "reGetSeqsCache", "reGetSeqsCache", reGetSeqsCache)
|
||||
cachedMsgs, failedSeqs2, err2 := db.cache.GetMessagesBySeq(ctx, conversationID, reGetSeqsCache)
|
||||
if err2 != nil {
|
||||
if !errors.Is(err2, redis.Nil) {
|
||||
prome.Add(prome.MsgPullFromRedisFailedCounter, len(failedSeqs2))
|
||||
log.ZError(ctx, "get message from redis exception", err2, "conversationID", conversationID, "seqs", reGetSeqsCache)
|
||||
}
|
||||
}
|
||||
failedSeqs = append(failedSeqs, failedSeqs2...)
|
||||
successMsgs = append(successMsgs, cachedMsgs...)
|
||||
}
|
||||
|
||||
return successMsgs, failedSeqs, err
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID string, conversationID string, begin, end, num, userMaxSeq int64) (int64, int64, []*sdkws.MsgData, error) {
|
||||
// 从缓存中获取最小和最大序列号,并根据给定的范围值进行调整
|
||||
userMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
minSeq, err := db.cache.GetMinSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
if userMinSeq > minSeq {
|
||||
@@ -455,18 +552,25 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
||||
}
|
||||
if minSeq > end {
|
||||
log.ZInfo(ctx, "minSeq > end", "minSeq", minSeq, "end", end)
|
||||
|
||||
return 0, 0, nil, nil
|
||||
}
|
||||
maxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
|
||||
// log out debug info
|
||||
log.ZDebug(ctx, "GetMsgBySeqsRange", "userMinSeq", userMinSeq, "conMinSeq", minSeq, "conMaxSeq", maxSeq, "userMaxSeq", userMaxSeq)
|
||||
|
||||
// adjust maxSeq according to userMaxSeq
|
||||
if userMaxSeq != 0 {
|
||||
if userMaxSeq < maxSeq {
|
||||
maxSeq = userMaxSeq
|
||||
}
|
||||
}
|
||||
|
||||
// adjust begin and end according to minSeq and maxSeq
|
||||
if begin < minSeq {
|
||||
begin = minSeq
|
||||
}
|
||||
@@ -476,6 +580,8 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
||||
if end < begin {
|
||||
return 0, 0, nil, errs.ErrArgs.Wrap("seq end < begin")
|
||||
}
|
||||
|
||||
// get seqs to search
|
||||
var seqs []int64
|
||||
for i := end; i > end-num; i-- {
|
||||
if i >= begin {
|
||||
@@ -487,67 +593,24 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
||||
if len(seqs) == 0 {
|
||||
return 0, 0, nil, nil
|
||||
}
|
||||
newBegin := seqs[0]
|
||||
newEnd := seqs[len(seqs)-1]
|
||||
log.ZDebug(ctx, "GetMsgBySeqsRange", "first seqs", seqs, "newBegin", newBegin, "newEnd", newEnd)
|
||||
cachedMsgs, failedSeqs, err := db.cache.GetMessagesBySeq(ctx, conversationID, seqs)
|
||||
|
||||
// get info from cache,and filter deleted msg
|
||||
successMsgs, failedSeqs, err := db.getCacheMsgForGetMsgBySeqsRange(ctx, userID, conversationID, begin, seqs)
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
prome.Add(prome.MsgPullFromRedisFailedCounter, len(failedSeqs))
|
||||
log.ZError(ctx, "get message from redis exception", err, "conversationID", conversationID, "seqs", seqs)
|
||||
}
|
||||
}
|
||||
var successMsgs []*sdkws.MsgData
|
||||
if len(cachedMsgs) > 0 {
|
||||
delSeqs, err := db.cache.GetUserDelList(ctx, userID, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
var cacheDelNum int
|
||||
for _, msg := range cachedMsgs {
|
||||
if !utils.Contain(msg.Seq, delSeqs...) {
|
||||
successMsgs = append(successMsgs, msg)
|
||||
} else {
|
||||
cacheDelNum += 1
|
||||
}
|
||||
}
|
||||
log.ZDebug(ctx, "get delSeqs from redis", "delSeqs", delSeqs, "userID", userID, "conversationID", conversationID, "cacheDelNum", cacheDelNum)
|
||||
var reGetSeqsCache []int64
|
||||
for i := 1; i <= cacheDelNum; {
|
||||
newSeq := newBegin - int64(i)
|
||||
if newSeq >= begin {
|
||||
if !utils.Contain(newSeq, delSeqs...) {
|
||||
log.ZDebug(ctx, "seq del in cache, a new seq in range append", "new seq", newSeq)
|
||||
reGetSeqsCache = append(reGetSeqsCache, newSeq)
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(reGetSeqsCache) > 0 {
|
||||
log.ZDebug(ctx, "reGetSeqsCache", "reGetSeqsCache", reGetSeqsCache)
|
||||
cachedMsgs, failedSeqs2, err := db.cache.GetMessagesBySeq(ctx, conversationID, reGetSeqsCache)
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
prome.Add(prome.MsgPullFromRedisFailedCounter, len(failedSeqs2))
|
||||
log.ZError(ctx, "get message from redis exception", err, "conversationID", conversationID, "seqs", reGetSeqsCache)
|
||||
}
|
||||
}
|
||||
failedSeqs = append(failedSeqs, failedSeqs2...)
|
||||
successMsgs = append(successMsgs, cachedMsgs...)
|
||||
}
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
// log out debug info
|
||||
log.ZDebug(ctx, "get msgs from cache", "successMsgs", successMsgs)
|
||||
if len(failedSeqs) != 0 {
|
||||
log.ZDebug(ctx, "msgs not exist in redis", "seqs", failedSeqs)
|
||||
}
|
||||
// get from cache or db
|
||||
// if not found in cache,find in mongo
|
||||
prome.Add(prome.MsgPullFromRedisSuccessCounter, len(successMsgs))
|
||||
if len(failedSeqs) > 0 {
|
||||
mongoMsgs, err := db.getMsgBySeqsRange(ctx, userID, conversationID, failedSeqs, begin, end)
|
||||
if err != nil {
|
||||
prome.Add(prome.MsgPullFromMongoFailedCounter, len(failedSeqs))
|
||||
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
prome.Add(prome.MsgPullFromMongoSuccessCounter, len(mongoMsgs))
|
||||
@@ -559,15 +622,15 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin
|
||||
|
||||
func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) (int64, int64, []*sdkws.MsgData, error) {
|
||||
userMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
minSeq, err := db.cache.GetMinSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
maxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
if userMinSeq < minSeq {
|
||||
@@ -581,7 +644,7 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co
|
||||
}
|
||||
successMsgs, failedSeqs, err := db.cache.GetMessagesBySeq(ctx, conversationID, newSeqs)
|
||||
if err != nil {
|
||||
if err != redis.Nil {
|
||||
if !errors.Is(err, redis.Nil) {
|
||||
prome.Add(prome.MsgPullFromRedisFailedCounter, len(failedSeqs))
|
||||
log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID)
|
||||
}
|
||||
@@ -607,11 +670,13 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co
|
||||
mongoMsgs, err := db.getMsgBySeqs(ctx, userID, conversationID, failedSeqs)
|
||||
if err != nil {
|
||||
prome.Add(prome.MsgPullFromMongoFailedCounter, len(failedSeqs))
|
||||
|
||||
return 0, 0, nil, err
|
||||
}
|
||||
prome.Add(prome.MsgPullFromMongoSuccessCounter, len(mongoMsgs))
|
||||
successMsgs = append(successMsgs, mongoMsgs...)
|
||||
}
|
||||
|
||||
return minSeq, maxSeq, successMsgs, nil
|
||||
}
|
||||
|
||||
@@ -632,61 +697,81 @@ func (db *commonMsgDatabase) DeleteConversationMsgsAndSetMinSeq(ctx context.Cont
|
||||
log.ZWarn(ctx, "CleanUpOneUserAllMsg", err, "conversationID", conversationID)
|
||||
}
|
||||
}
|
||||
|
||||
return db.cache.SetMinSeq(ctx, conversationID, minSeq)
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID string, conversationID string, destructTime int64, lastMsgDestructTime time.Time) (seqs []int64, err error) {
|
||||
func processMsgDocModel(
|
||||
ctx context.Context,
|
||||
msgDocModel *unrelationtb.MsgDocModel,
|
||||
userID, conversationID string,
|
||||
index int64,
|
||||
destructTime int64,
|
||||
lastMsgDestructTime time.Time,
|
||||
) (seqs []int64, over bool) {
|
||||
if len(msgDocModel.Msg) > 0 {
|
||||
i := 0
|
||||
for _, msg := range msgDocModel.Msg {
|
||||
i++
|
||||
if msg != nil && msg.Msg != nil && msg.Msg.SendTime+destructTime*1000 <= time.Now().UnixMilli() {
|
||||
if msg.Msg.SendTime+destructTime*1000 > lastMsgDestructTime.UnixMilli() && !utils.Contain(userID, msg.DelList...) {
|
||||
seqs = append(seqs, msg.Msg.Seq)
|
||||
}
|
||||
} else {
|
||||
log.ZDebug(ctx, "all msg need destruct is found", "conversationID", conversationID, "userID", userID, "index", index, "stop index", i)
|
||||
over = true
|
||||
|
||||
return seqs, over
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return seqs, over
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID, conversationID string, destructTime int64, lastMsgDestructTime time.Time) (seqs []int64, err error) {
|
||||
var index int64
|
||||
|
||||
// refresh msg list
|
||||
for {
|
||||
// from oldest 2 newest
|
||||
msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1)
|
||||
if err != nil || msgDocModel.DocID == "" {
|
||||
if err != nil {
|
||||
if err == unrelation.ErrMsgListNotExist {
|
||||
// from oldest to newest
|
||||
msgDocModel, err2 := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1)
|
||||
if err2 != nil || msgDocModel.DocID == "" {
|
||||
if err2 != nil {
|
||||
if errors.Is(err2, unrelation.ErrMsgListNotExist) {
|
||||
log.ZDebug(ctx, "not doc find", "conversationID", conversationID, "userID", userID, "index", index)
|
||||
} else {
|
||||
log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index)
|
||||
log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err2, "conversationID", conversationID, "index", index)
|
||||
}
|
||||
}
|
||||
// 获取报错,或者获取不到了,物理删除并且返回seq delMongoMsgsPhysical(delStruct.delDocIDList), 结束递归
|
||||
// If there is an error or no message document is found, delete the message physically and return the sequence number, then end the recursion.
|
||||
break
|
||||
}
|
||||
index++
|
||||
//&& msgDocModel.Msg[0].Msg.SendTime > lastMsgDestructTime.UnixMilli()
|
||||
if len(msgDocModel.Msg) > 0 {
|
||||
i := 0
|
||||
var over bool
|
||||
for _, msg := range msgDocModel.Msg {
|
||||
i++
|
||||
if msg != nil && msg.Msg != nil && msg.Msg.SendTime+destructTime*1000 <= time.Now().UnixMilli() {
|
||||
if msg.Msg.SendTime+destructTime*1000 > lastMsgDestructTime.UnixMilli() && !utils.Contain(userID, msg.DelList...) {
|
||||
seqs = append(seqs, msg.Msg.Seq)
|
||||
}
|
||||
} else {
|
||||
log.ZDebug(ctx, "all msg need destruct is found", "conversationID", conversationID, "userID", userID, "index", index, "stop index", i)
|
||||
over = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if over {
|
||||
break
|
||||
}
|
||||
curSeqs, over := processMsgDocModel(ctx, msgDocModel, userID, conversationID, index, destructTime, lastMsgDestructTime)
|
||||
seqs = append(seqs, curSeqs...)
|
||||
if over {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Log the result of the function call.
|
||||
log.ZDebug(ctx, "UserMsgsDestruct", "conversationID", conversationID, "userID", userID, "seqs", seqs)
|
||||
if len(seqs) == 0 {
|
||||
return seqs, nil
|
||||
}
|
||||
// if len(seqs) > 0
|
||||
userMinSeq := seqs[len(seqs)-1] + 1
|
||||
currentUserMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return nil, err
|
||||
}
|
||||
if currentUserMinSeq < userMinSeq {
|
||||
if err := db.cache.SetConversationUserMinSeq(ctx, conversationID, userID, userMinSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "UserMsgsDestruct", "conversationID", conversationID, "userID", userID, "seqs", seqs)
|
||||
if len(seqs) > 0 {
|
||||
userMinSeq := seqs[len(seqs)-1] + 1
|
||||
currentUserMinSeq, err := db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
return nil, err
|
||||
}
|
||||
if currentUserMinSeq < userMinSeq {
|
||||
if err := db.cache.SetConversationUserMinSeq(ctx, conversationID, userID, userMinSeq); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return seqs, nil
|
||||
}
|
||||
|
||||
@@ -709,47 +794,67 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio
|
||||
msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1)
|
||||
if err != nil || msgDocModel.DocID == "" {
|
||||
if err != nil {
|
||||
if err == unrelation.ErrMsgListNotExist {
|
||||
if errors.Is(err, unrelation.ErrMsgListNotExist) {
|
||||
log.ZDebug(ctx, "deleteMsgRecursion ErrMsgListNotExist", "conversationID", conversationID, "index:", index)
|
||||
} else {
|
||||
log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index)
|
||||
}
|
||||
}
|
||||
// 获取报错,或者获取不到了,物理删除并且返回seq delMongoMsgsPhysical(delStruct.delDocIDList), 结束递归
|
||||
// get error or miss content, delete physically and return minSeq,delMongoMsgsPhysical(delStruct.delDocIDList), end recursion
|
||||
err = db.msgDocDatabase.DeleteDocs(ctx, delStruct.delDocIDs)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return delStruct.getSetMinSeq() + 1, nil
|
||||
}
|
||||
|
||||
log.ZDebug(ctx, "doc info", "conversationID", conversationID, "index", index, "docID", msgDocModel.DocID, "len", len(msgDocModel.Msg))
|
||||
if int64(len(msgDocModel.Msg)) > db.msg.GetSingleGocMsgNum() {
|
||||
log.ZWarn(ctx, "msgs too large", nil, "lenth", len(msgDocModel.Msg), "docID:", msgDocModel.DocID)
|
||||
}
|
||||
if msgDocModel.IsFull() && msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.SendTime+(remainTime*1000) < utils.GetCurrentTimestampByMill() {
|
||||
log.ZDebug(ctx, "doc is full and all msg is expired", "docID", msgDocModel.DocID)
|
||||
delStruct.delDocIDs = append(delStruct.delDocIDs, msgDocModel.DocID)
|
||||
delStruct.minSeq = msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.Seq
|
||||
fullAndExpired := msgDocModel.IsFull() && msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.SendTime+(remainTime*1000) < utils.GetCurrentTimestampByMill()
|
||||
if fullAndExpired {
|
||||
handleFullAndExpiredForDeleteMsgRecursion(ctx, msgDocModel, delStruct)
|
||||
} else {
|
||||
var delMsgIndexs []int
|
||||
for i, MsgInfoModel := range msgDocModel.Msg {
|
||||
if MsgInfoModel != nil && MsgInfoModel.Msg != nil {
|
||||
if utils.GetCurrentTimestampByMill() > MsgInfoModel.Msg.SendTime+(remainTime*1000) {
|
||||
delMsgIndexs = append(delMsgIndexs, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(delMsgIndexs) > 0 {
|
||||
if err := db.msgDocDatabase.DeleteMsgsInOneDocByIndex(ctx, msgDocModel.DocID, delMsgIndexs); err != nil {
|
||||
log.ZError(ctx, "deleteMsgRecursion DeleteMsgsInOneDocByIndex failed", err, "conversationID", conversationID, "index", index)
|
||||
}
|
||||
delStruct.minSeq = int64(msgDocModel.Msg[delMsgIndexs[len(delMsgIndexs)-1]].Msg.Seq)
|
||||
}
|
||||
handleNotFullAndExpiredForDeleteMsgRecursion(ctx, msgDocModel, remainTime, index, conversationID, delStruct, db)
|
||||
}
|
||||
seq, err := db.deleteMsgRecursion(ctx, conversationID, index+1, delStruct, remainTime)
|
||||
|
||||
return seq, err
|
||||
}
|
||||
|
||||
func handleFullAndExpiredForDeleteMsgRecursion(ctx context.Context, msgDocModel *unrelationtb.MsgDocModel, delStruct *delMsgRecursionStruct) {
|
||||
log.ZDebug(ctx, "doc is full and all msg is expired", "docID", msgDocModel.DocID)
|
||||
delStruct.delDocIDs = append(delStruct.delDocIDs, msgDocModel.DocID)
|
||||
delStruct.minSeq = msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.Seq
|
||||
}
|
||||
|
||||
func handleNotFullAndExpiredForDeleteMsgRecursion(
|
||||
ctx context.Context,
|
||||
msgDocModel *unrelationtb.MsgDocModel,
|
||||
remainTime, index int64,
|
||||
conversationID string,
|
||||
delStruct *delMsgRecursionStruct,
|
||||
db *commonMsgDatabase,
|
||||
) {
|
||||
var delMsgIndexs []int
|
||||
for i, MsgInfoModel := range msgDocModel.Msg {
|
||||
if MsgInfoModel != nil && MsgInfoModel.Msg != nil {
|
||||
if utils.GetCurrentTimestampByMill() > MsgInfoModel.Msg.SendTime+(remainTime*1000) {
|
||||
delMsgIndexs = append(delMsgIndexs, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(delMsgIndexs) > 0 {
|
||||
err2 := db.msgDocDatabase.DeleteMsgsInOneDocByIndex(ctx, msgDocModel.DocID, delMsgIndexs)
|
||||
if err2 != nil {
|
||||
log.ZError(ctx, "deleteMsgRecursion DeleteMsgsInOneDocByIndex failed", err2, "conversationID", conversationID, "index", index)
|
||||
}
|
||||
delStruct.minSeq = msgDocModel.Msg[delMsgIndexs[len(delMsgIndexs)-1]].Msg.Seq
|
||||
}
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) DeleteMsgsPhysicalBySeqs(ctx context.Context, conversationID string, allSeqs []int64) error {
|
||||
if err := db.cache.DeleteMessages(ctx, conversationID, allSeqs); err != nil {
|
||||
return err
|
||||
@@ -763,13 +868,15 @@ func (db *commonMsgDatabase) DeleteMsgsPhysicalBySeqs(ctx context.Context, conve
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) DeleteUserMsgsBySeqs(ctx context.Context, userID string, conversationID string, seqs []int64) error {
|
||||
cachedMsgs, _, err := db.cache.GetMessagesBySeq(ctx, conversationID, seqs)
|
||||
if err != nil && errs.Unwrap(err) != redis.Nil {
|
||||
if err != nil && errors.Is(err, redis.Nil) {
|
||||
log.ZWarn(ctx, "DeleteUserMsgsBySeqs", err, "conversationID", conversationID, "seqs", seqs)
|
||||
|
||||
return err
|
||||
}
|
||||
if len(cachedMsgs) > 0 {
|
||||
@@ -789,6 +896,7 @@ func (db *commonMsgDatabase) DeleteUserMsgsBySeqs(ctx context.Context, userID st
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -800,11 +908,12 @@ func (db *commonMsgDatabase) CleanUpUserConversationsMsgs(ctx context.Context, u
|
||||
for _, conversationID := range conversationIDs {
|
||||
maxSeq, err := db.cache.GetMaxSeq(ctx, conversationID)
|
||||
if err != nil {
|
||||
if err == redis.Nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
log.ZInfo(ctx, "max seq is nil", "conversationID", conversationID)
|
||||
} else {
|
||||
log.ZError(ctx, "get max seq failed", err, "conversationID", conversationID)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
if err := db.cache.SetMinSeq(ctx, conversationID, maxSeq+1); err != nil {
|
||||
@@ -898,6 +1007,7 @@ func (db *commonMsgDatabase) GetConversationMinMaxSeqInMongoAndCache(ctx context
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -916,6 +1026,7 @@ func (db *commonMsgDatabase) GetMinMaxSeqMongo(ctx context.Context, conversation
|
||||
return
|
||||
}
|
||||
maxSeqMongo = newestMsgMongo.Msg.Seq
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -943,7 +1054,7 @@ func (db *commonMsgDatabase) RangeGroupSendCount(
|
||||
}
|
||||
|
||||
func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) {
|
||||
var totalMsgs []*sdkws.MsgData
|
||||
totalMsgs := make([]*sdkws.MsgData, 0)
|
||||
total, msgs, err := db.msgDocDatabase.SearchMessage(ctx, req)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
@@ -954,6 +1065,7 @@ func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbmsg.Searc
|
||||
}
|
||||
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
|
||||
}
|
||||
|
||||
return total, totalMsgs, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -162,6 +162,7 @@ func GetDB() *commonMsgDatabase {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &commonMsgDatabase{
|
||||
msgDocDatabase: unrelation.NewMsgMongoDriver(mongo.GetDatabase()),
|
||||
}
|
||||
|
||||
@@ -89,5 +89,6 @@ func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Dur
|
||||
if err != nil {
|
||||
return time.Time{}, "", err
|
||||
}
|
||||
|
||||
return expireTime, rawURL, nil
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel
|
||||
if len(miss) > 0 {
|
||||
_ = u.userDB.Create(ctx, miss)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -102,30 +103,35 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use
|
||||
if len(users) != len(userIDs) {
|
||||
err = errs.ErrRecordNotFound.Wrap("userID not found")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Find Get the information of the specified user. If the userID is not found, no error will be returned.
|
||||
func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
|
||||
users, err = u.cache.GetUsersInfo(ctx, userIDs)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db.
|
||||
func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) {
|
||||
if err := u.tx.Transaction(func(tx any) error {
|
||||
err = u.tx.Transaction(func(tx any) error {
|
||||
err = u.userDB.Create(ctx, users)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var userIDs []string
|
||||
userIDs := make([]string, 0, len(users))
|
||||
for _, user := range users {
|
||||
userIDs = append(userIDs, user.UserID)
|
||||
}
|
||||
|
||||
return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -134,6 +140,7 @@ func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (er
|
||||
if err := u.userDB.Update(ctx, user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -142,6 +149,7 @@ func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[
|
||||
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
|
||||
}
|
||||
|
||||
@@ -162,6 +170,7 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo
|
||||
if len(users) > 0 {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@@ -183,12 +192,14 @@ func (u *userDatabase) CountRangeEverydayTotal(ctx context.Context, start time.T
|
||||
// SubscribeUsersStatus Subscribe or unsubscribe a user's presence status.
|
||||
func (u *userDatabase) SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
||||
err := u.mongoDB.AddSubscriptionList(ctx, userID, userIDs)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// UnsubscribeUsersStatus unsubscribe a user's presence status.
|
||||
func (u *userDatabase) UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
|
||||
err := u.mongoDB.UnsubscriptionList(ctx, userID, userIDs)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -198,6 +209,7 @@ func (u *userDatabase) GetAllSubscribeList(ctx context.Context, userID string) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -207,12 +219,14 @@ func (u *userDatabase) GetSubscribedList(ctx context.Context, userID string) ([]
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// GetUserStatus get user status.
|
||||
func (u *userDatabase) GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) {
|
||||
onlineStatusList, err := u.cache.GetUserStatus(ctx, userIDs)
|
||||
|
||||
return onlineStatusList, err
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ func (g *ConversationLocalCache) GetRecvMsgNotNotifyUserIDs(ctx context.Context,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.UserIDs, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string)
|
||||
localHashInfo, ok := g.cache[groupID]
|
||||
if ok && localHashInfo.memberListHash == resp.GroupAbstractInfos[0].GroupMemberListHash {
|
||||
g.lock.Unlock()
|
||||
|
||||
return localHashInfo.userIDs, nil
|
||||
}
|
||||
g.lock.Unlock()
|
||||
@@ -74,5 +75,6 @@ func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string)
|
||||
memberListHash: resp.GroupAbstractInfos[0].GroupMemberListHash,
|
||||
userIDs: groupMembersResp.UserIDs,
|
||||
}
|
||||
|
||||
return g.cache[groupID].userIDs, nil
|
||||
}
|
||||
|
||||
@@ -63,10 +63,11 @@ func (b *BlackGorm) Find(
|
||||
ctx context.Context,
|
||||
blacks []*relation.BlackModel,
|
||||
) (blackList []*relation.BlackModel, err error) {
|
||||
var where [][]interface{}
|
||||
where := make([][]interface{}, 0, len(blacks))
|
||||
for _, black := range blacks {
|
||||
where = append(where, []interface{}{black.OwnerUserID, black.BlockUserID})
|
||||
}
|
||||
|
||||
return blackList, utils.Wrap(
|
||||
b.db(ctx).Where("(owner_user_id, block_user_id) in ?", where).Find(&blackList).Error,
|
||||
"",
|
||||
@@ -75,6 +76,7 @@ func (b *BlackGorm) Find(
|
||||
|
||||
func (b *BlackGorm) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) {
|
||||
black = &relation.BlackModel{}
|
||||
|
||||
return black, utils.Wrap(
|
||||
b.db(ctx).Where("owner_user_id = ? and block_user_id = ?", ownerUserID, blockUserID).Take(black).Error,
|
||||
"",
|
||||
@@ -96,6 +98,7 @@ func (b *BlackGorm) FindOwnerBlacks(
|
||||
showNumber,
|
||||
)
|
||||
total = int64(totalUint32)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package relation
|
||||
|
||||
import (
|
||||
|
||||
//nolint:staticcheck //tofix: SA1019: "github.com/golang/protobuf/jsonpb" is deprecated: Use the "google.golang.org/protobuf/encoding/protojson" package instead.
|
||||
"github.com/golang/protobuf/jsonpb"
|
||||
"github.com/jinzhu/copier"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -38,7 +40,10 @@ func NewChatLogGorm(db *gorm.DB) relation.ChatLogModelInterface {
|
||||
|
||||
func (c *ChatLogGorm) Create(msg *pbmsg.MsgDataToMQ) error {
|
||||
chatLog := new(relation.ChatLogModel)
|
||||
copier.Copy(chatLog, msg.MsgData)
|
||||
err := copier.Copy(chatLog, msg.MsgData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch msg.MsgData.SessionType {
|
||||
case constant.GroupChatType, constant.SuperGroupChatType:
|
||||
chatLog.RecvID = msg.MsgData.GroupID
|
||||
@@ -59,5 +64,6 @@ func (c *ChatLogGorm) Create(msg *pbmsg.MsgDataToMQ) error {
|
||||
}
|
||||
chatLog.CreateTime = utils.UnixMillSecondToTime(msg.MsgData.CreateTime)
|
||||
chatLog.SendTime = utils.UnixMillSecondToTime(msg.MsgData.SendTime)
|
||||
|
||||
return c.DB.Create(chatLog).Error
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ func (c *ConversationGorm) UpdateByMap(
|
||||
args map[string]interface{},
|
||||
) (rows int64, err error) {
|
||||
result := c.db(ctx).Where("owner_user_id IN (?) and conversation_id=?", userIDList, conversationID).Updates(args)
|
||||
|
||||
return result.RowsAffected, utils.Wrap(result.Error, "")
|
||||
}
|
||||
|
||||
@@ -79,6 +80,7 @@ func (c *ConversationGorm) Find(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return conversations, err
|
||||
}
|
||||
|
||||
@@ -87,6 +89,7 @@ func (c *ConversationGorm) Take(
|
||||
userID, conversationID string,
|
||||
) (conversation *relation.ConversationModel, err error) {
|
||||
cc := &relation.ConversationModel{}
|
||||
|
||||
return cc, utils.Wrap(
|
||||
c.db(ctx).Where("conversation_id = ? And owner_user_id = ?", conversationID, userID).Take(cc).Error,
|
||||
"",
|
||||
@@ -169,6 +172,7 @@ func (c *ConversationGorm) GetUserRecvMsgOpt(
|
||||
ownerUserID, conversationID string,
|
||||
) (opt int, err error) {
|
||||
var conversation relation.ConversationModel
|
||||
|
||||
return int(
|
||||
conversation.RecvMsgOpt,
|
||||
), utils.Wrap(
|
||||
@@ -219,6 +223,7 @@ func (c *ConversationGorm) GetConversationIDsNeedDestruct(
|
||||
|
||||
func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID string, conversationID string) (int32, error) {
|
||||
var recvMsgOpt int32
|
||||
|
||||
return recvMsgOpt, errs.Wrap(
|
||||
c.db(ctx).
|
||||
Model(&relation.ConversationModel{}).
|
||||
@@ -230,6 +235,7 @@ func (c *ConversationGorm) GetConversationRecvMsgOpt(ctx context.Context, userID
|
||||
|
||||
func (c *ConversationGorm) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) {
|
||||
var userIDs []string
|
||||
|
||||
return userIDs, errs.Wrap(
|
||||
c.db(ctx).
|
||||
Model(&relation.ConversationModel{}).
|
||||
|
||||
@@ -50,6 +50,7 @@ func (f *FriendGorm) Delete(ctx context.Context, ownerUserID string, friendUserI
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -84,6 +85,7 @@ func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID
|
||||
}
|
||||
m := make(map[string]interface{}, 1)
|
||||
m["remark"] = ""
|
||||
|
||||
return utils.Wrap(f.db(ctx).Where("owner_user_id = ?", ownerUserID).Updates(m).Error, "")
|
||||
}
|
||||
|
||||
@@ -93,6 +95,7 @@ func (f *FriendGorm) Take(
|
||||
ownerUserID, friendUserID string,
|
||||
) (friend *relation.FriendModel, err error) {
|
||||
friend = &relation.FriendModel{}
|
||||
|
||||
return friend, utils.Wrap(
|
||||
f.db(ctx).Where("owner_user_id = ? and friend_user_id", ownerUserID, friendUserID).Take(friend).Error,
|
||||
"",
|
||||
@@ -156,6 +159,7 @@ func (f *FriendGorm) FindOwnerFriends(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -178,6 +182,7 @@ func (f *FriendGorm) FindInWhoseFriends(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.
|
||||
fr2 := *friendRequest
|
||||
fr2.FromUserID = ""
|
||||
fr2.ToUserID = ""
|
||||
|
||||
return utils.Wrap(
|
||||
f.db(ctx).
|
||||
Where("from_user_id = ? AND to_user_id =?", friendRequest.FromUserID, friendRequest.ToUserID).
|
||||
@@ -93,6 +94,7 @@ func (f *FriendRequestGorm) Find(
|
||||
f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Find(friendRequest).Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return friendRequest, err
|
||||
}
|
||||
|
||||
@@ -105,6 +107,7 @@ func (f *FriendRequestGorm) Take(
|
||||
f.db(ctx).Where("from_user_id = ? and to_user_id = ?", fromUserID, toUserID).Take(friendRequest).Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return friendRequest, err
|
||||
}
|
||||
|
||||
@@ -127,6 +130,7 @@ func (f *FriendRequestGorm) FindToUserID(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -149,6 +153,7 @@ func (f *FriendRequestGorm) FindFromUserID(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -160,5 +165,6 @@ func (f *FriendRequestGorm) FindBothFriendRequests(ctx context.Context, fromUser
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ func (g *GroupMemberGorm) UpdateRoleLevel(
|
||||
db := g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Updates(map[string]any{
|
||||
"role_level": roleLevel,
|
||||
})
|
||||
|
||||
return db.RowsAffected, utils.Wrap(db.Error, "")
|
||||
}
|
||||
|
||||
@@ -87,6 +88,7 @@ func (g *GroupMemberGorm) Find(
|
||||
if len(roleLevels) > 0 {
|
||||
db = db.Where("role_level in (?)", roleLevels)
|
||||
}
|
||||
|
||||
return groupMembers, utils.Wrap(db.Find(&groupMembers).Error, "")
|
||||
}
|
||||
|
||||
@@ -96,6 +98,7 @@ func (g *GroupMemberGorm) Take(
|
||||
userID string,
|
||||
) (groupMember *relation.GroupMemberModel, err error) {
|
||||
groupMember = &relation.GroupMemberModel{}
|
||||
|
||||
return groupMember, utils.Wrap(
|
||||
g.db(ctx).Where("group_id = ? and user_id = ?", groupID, userID).Take(groupMember).Error,
|
||||
"",
|
||||
@@ -107,6 +110,7 @@ func (g *GroupMemberGorm) TakeOwner(
|
||||
groupID string,
|
||||
) (groupMember *relation.GroupMemberModel, err error) {
|
||||
groupMember = &relation.GroupMemberModel{}
|
||||
|
||||
return groupMember, utils.Wrap(
|
||||
g.db(ctx).Where("group_id = ? and role_level = ?", groupID, constant.GroupOwner).Take(groupMember).Error,
|
||||
"",
|
||||
@@ -125,6 +129,7 @@ func (g *GroupMemberGorm) SearchMember(
|
||||
ormutil.GormIn(&db, "group_id", groupIDs)
|
||||
ormutil.GormIn(&db, "user_id", userIDs)
|
||||
ormutil.GormIn(&db, "role_level", roleLevels)
|
||||
|
||||
return ormutil.GormSearch[relation.GroupMemberModel](db, []string{"nickname"}, keyword, pageNumber, showNumber)
|
||||
}
|
||||
|
||||
@@ -152,6 +157,7 @@ func (g *GroupMemberGorm) FindJoinUserID(
|
||||
groupUsers[item.GroupID] = append(v, item.UserID)
|
||||
}
|
||||
}
|
||||
|
||||
return groupUsers, nil
|
||||
}
|
||||
|
||||
@@ -182,6 +188,7 @@ func (g *GroupMemberGorm) FindUsersJoinedGroupID(ctx context.Context, userIDs []
|
||||
result[groupMember.UserID] = append(v, groupMember.GroupID)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,14 @@ func (g *GroupGorm) Find(ctx context.Context, groupIDs []string) (groups []*rela
|
||||
|
||||
func (g *GroupGorm) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) {
|
||||
group = &relation.GroupModel{}
|
||||
|
||||
return group, utils.Wrap(g.DB.Where("group_id = ?", groupID).Take(group).Error, "")
|
||||
}
|
||||
|
||||
func (g *GroupGorm) Search(ctx context.Context, keyword string, pageNumber, showNumber int32) (total uint32, groups []*relation.GroupModel, err error) {
|
||||
db := g.DB
|
||||
db = db.WithContext(ctx).Where("status!=?", constant.GroupStatusDismissed)
|
||||
|
||||
return ormutil.GormSearch[relation.GroupModel](db, []string{"name"}, keyword, pageNumber, showNumber)
|
||||
}
|
||||
|
||||
@@ -82,6 +84,7 @@ func (g *GroupGorm) CountTotal(ctx context.Context, before *time.Time) (count in
|
||||
if err := db.Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
@@ -98,6 +101,7 @@ func (g *GroupGorm) CountRangeEverydayTotal(ctx context.Context, start time.Time
|
||||
for _, r := range res {
|
||||
v[r.Date.Format("2006-01-02")] = r.Count
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ func (g *GroupRequestGorm) Take(
|
||||
userID string,
|
||||
) (groupRequest *relation.GroupRequestModel, err error) {
|
||||
groupRequest = &relation.GroupRequestModel{}
|
||||
|
||||
return groupRequest, utils.Wrap(
|
||||
g.DB.WithContext(ctx).Where("group_id = ? and user_id = ? ", groupID, userID).Take(groupRequest).Error,
|
||||
utils.GetSelfFuncName(),
|
||||
@@ -114,5 +115,6 @@ func (g *GroupRequestGorm) PageGroup(
|
||||
|
||||
func (g *GroupRequestGorm) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) (total int64, groupRequests []*relation.GroupRequestModel, err error) {
|
||||
err = g.DB.WithContext(ctx).Where("group_id = ? and user_id in ?", groupID, userIDs).Find(&groupRequests).Error
|
||||
|
||||
return int64(len(groupRequests)), groupRequests, utils.Wrap(err, utils.GetSelfFuncName())
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ func (l *LogGorm) Search(ctx context.Context, keyword string, start time.Time, e
|
||||
db = l.db.WithContext(ctx).Where("create_time <= ?", end)
|
||||
}
|
||||
db = db.Order("create_time desc")
|
||||
|
||||
return ormutil.GormSearch[relationtb.Log](db, []string{"user_id"}, keyword, pageNumber, showNumber)
|
||||
}
|
||||
|
||||
@@ -32,6 +33,7 @@ func (l *LogGorm) Delete(ctx context.Context, logIDs []string, userID string) er
|
||||
if userID == "" {
|
||||
return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Delete(&relationtb.Log{}).Error)
|
||||
}
|
||||
|
||||
return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Delete(&relationtb.Log{}).Error)
|
||||
}
|
||||
|
||||
@@ -40,10 +42,15 @@ func (l *LogGorm) Get(ctx context.Context, logIDs []string, userID string) ([]*r
|
||||
if userID == "" {
|
||||
return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Find(&logs).Error)
|
||||
}
|
||||
|
||||
return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Find(&logs).Error)
|
||||
}
|
||||
|
||||
func NewLogGorm(db *gorm.DB) relationtb.LogInterface {
|
||||
db.AutoMigrate(&relationtb.Log{})
|
||||
err := db.AutoMigrate(&relationtb.Log{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &LogGorm{db: db}
|
||||
}
|
||||
|
||||
@@ -34,5 +34,6 @@ func NewMetaDB(db *gorm.DB, table any) *MetaDB {
|
||||
|
||||
func (g *MetaDB) db(ctx context.Context) *gorm.DB {
|
||||
db := g.DB.WithContext(ctx).Model(g.table)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package relation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -82,6 +83,7 @@ func newMysqlGormDB() (*gorm.DB, error) {
|
||||
sqlDB.SetConnMaxLifetime(time.Second * time.Duration(config.Config.Mysql.MaxLifeTime))
|
||||
sqlDB.SetMaxOpenConns(config.Config.Mysql.MaxOpenConn)
|
||||
sqlDB.SetMaxIdleConns(config.Config.Mysql.MaxIdleConn)
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
@@ -94,11 +96,13 @@ func connectToDatabase(dsn string, maxRetry int) (*gorm.DB, error) {
|
||||
if err == nil {
|
||||
return db, nil
|
||||
}
|
||||
if mysqlErr, ok := err.(*mysqldriver.MySQLError); ok && mysqlErr.Number == 1045 {
|
||||
var mysqlErr *mysqldriver.MySQLError
|
||||
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1045 {
|
||||
return nil, err
|
||||
}
|
||||
time.Sleep(time.Duration(1) * time.Second)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -106,6 +110,7 @@ func connectToDatabase(dsn string, maxRetry int) (*gorm.DB, error) {
|
||||
func NewGormDB() (*gorm.DB, error) {
|
||||
specialerror.AddReplace(gorm.ErrRecordNotFound, errs.ErrRecordNotFound)
|
||||
specialerror.AddErrHandler(replaceDuplicateKey)
|
||||
|
||||
return newMysqlGormDB()
|
||||
}
|
||||
|
||||
@@ -113,12 +118,15 @@ func replaceDuplicateKey(err error) errs.CodeError {
|
||||
if IsMysqlDuplicateKey(err) {
|
||||
return errs.ErrDuplicateKey
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsMysqlDuplicateKey(err error) bool {
|
||||
if mysqlErr, ok := err.(*mysqldriver.MySQLError); ok {
|
||||
var mysqlErr *mysqldriver.MySQLError
|
||||
if errors.As(err, &mysqlErr) {
|
||||
return mysqlErr.Number == 1062
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -44,10 +44,12 @@ func (o *ObjectInfoGorm) SetObject(ctx context.Context, obj *relation.ObjectMode
|
||||
if err := o.DB.WithContext(ctx).Where("name = ?", obj.Name).FirstOrCreate(obj).Error; err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ObjectInfoGorm) Take(ctx context.Context, name string) (info *relation.ObjectModel, err error) {
|
||||
info = &relation.ObjectModel{}
|
||||
|
||||
return info, errs.Wrap(o.DB.WithContext(ctx).Where("name = ?", name).Take(info).Error)
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ func (u *UserGorm) Update(ctx context.Context, user *relation.UserModel) (err er
|
||||
// 获取指定用户信息 不存在,也不返回错误.
|
||||
func (u *UserGorm) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
|
||||
err = utils.Wrap(u.db(ctx).Where("user_id in (?)", userIDs).Find(&users).Error, "")
|
||||
|
||||
return users, err
|
||||
}
|
||||
|
||||
@@ -60,6 +61,7 @@ func (u *UserGorm) Find(ctx context.Context, userIDs []string) (users []*relatio
|
||||
func (u *UserGorm) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) {
|
||||
user = &relation.UserModel{}
|
||||
err = utils.Wrap(u.db(ctx).Where("user_id = ?", userID).Take(&user).Error, "")
|
||||
|
||||
return user, err
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ func (u *UserGorm) Page(
|
||||
Error,
|
||||
"",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -88,13 +91,14 @@ func (u *UserGorm) Page(
|
||||
func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
|
||||
if pageNumber == 0 || showNumber == 0 {
|
||||
return userIDs, errs.Wrap(u.db(ctx).Pluck("user_id", &userIDs).Error)
|
||||
} else {
|
||||
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
|
||||
}
|
||||
|
||||
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
|
||||
}
|
||||
|
||||
func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {
|
||||
err = u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Pluck("global_recv_msg_opt", &opt).Error
|
||||
|
||||
return opt, err
|
||||
}
|
||||
|
||||
@@ -106,6 +110,7 @@ func (u *UserGorm) CountTotal(ctx context.Context, before *time.Time) (count int
|
||||
if err := db.Count(&count).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
@@ -132,5 +137,6 @@ func (u *UserGorm) CountRangeEverydayTotal(
|
||||
for _, r := range res {
|
||||
v[r.Date.Format("2006-01-02")] = r.Count
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ func (c *Controller) HashPath(md5 string) string {
|
||||
|
||||
func (c *Controller) NowPath() string {
|
||||
now := time.Now()
|
||||
|
||||
return path.Join(
|
||||
fmt.Sprintf("%04d", now.Year()),
|
||||
fmt.Sprintf("%02d", now.Month()),
|
||||
@@ -58,6 +59,7 @@ func (c *Controller) NowPath() string {
|
||||
|
||||
func (c *Controller) UUID() string {
|
||||
id := uuid.New()
|
||||
|
||||
return hex.EncodeToString(id[:])
|
||||
}
|
||||
|
||||
@@ -92,20 +94,24 @@ func (c *Controller) InitiateUpload(ctx context.Context, hash string, size int64
|
||||
partNumber++
|
||||
}
|
||||
if maxParts > 0 && partNumber > 0 && partNumber < maxParts {
|
||||
return nil, errors.New(fmt.Sprintf("too many parts: %d", partNumber))
|
||||
return nil, fmt.Errorf("too few parts: %d", partNumber)
|
||||
}
|
||||
if info, err := c.impl.StatObject(ctx, c.HashPath(hash)); err == nil {
|
||||
info, err := c.impl.StatObject(ctx, c.HashPath(hash))
|
||||
if err == nil {
|
||||
return nil, &HashAlreadyExistsError{Object: info}
|
||||
} else if !c.impl.IsNotFound(err) {
|
||||
}
|
||||
if !c.impl.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if size <= partSize {
|
||||
// 预签名上传
|
||||
key := path.Join(tempPath, c.NowPath(), fmt.Sprintf("%s_%d_%s.presigned", hash, size, c.UUID()))
|
||||
rawURL, err := c.impl.PresignedPutObject(ctx, key, expire)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
rawURL, err2 := c.impl.PresignedPutObject(ctx, key, expire)
|
||||
if err2 != nil {
|
||||
return nil, err2
|
||||
}
|
||||
|
||||
return &InitiateUploadResult{
|
||||
UploadID: newMultipartUploadID(multipartUploadID{
|
||||
Type: UploadTypePresigned,
|
||||
@@ -124,38 +130,39 @@ func (c *Controller) InitiateUpload(ctx context.Context, hash string, size int64
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
} else {
|
||||
// 分片上传
|
||||
upload, err := c.impl.InitiateMultipartUpload(ctx, c.HashPath(hash))
|
||||
}
|
||||
|
||||
// 分片上传
|
||||
upload, err := c.impl.InitiateMultipartUpload(ctx, c.HashPath(hash))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if maxParts < 0 {
|
||||
maxParts = partNumber
|
||||
}
|
||||
var authSign *s3.AuthSignResult
|
||||
if maxParts > 0 {
|
||||
partNumbers := make([]int, partNumber)
|
||||
for i := 0; i < maxParts; i++ {
|
||||
partNumbers[i] = i + 1
|
||||
}
|
||||
authSign, err = c.impl.AuthSign(ctx, upload.UploadID, upload.Key, time.Hour*24, partNumbers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if maxParts < 0 {
|
||||
maxParts = partNumber
|
||||
}
|
||||
var authSign *s3.AuthSignResult
|
||||
if maxParts > 0 {
|
||||
partNumbers := make([]int, partNumber)
|
||||
for i := 0; i < maxParts; i++ {
|
||||
partNumbers[i] = i + 1
|
||||
}
|
||||
authSign, err = c.impl.AuthSign(ctx, upload.UploadID, upload.Key, time.Hour*24, partNumbers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &InitiateUploadResult{
|
||||
UploadID: newMultipartUploadID(multipartUploadID{
|
||||
Type: UploadTypeMultipart,
|
||||
ID: upload.UploadID,
|
||||
Key: upload.Key,
|
||||
Size: size,
|
||||
Hash: hash,
|
||||
}),
|
||||
PartSize: partSize,
|
||||
Sign: authSign,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &InitiateUploadResult{
|
||||
UploadID: newMultipartUploadID(multipartUploadID{
|
||||
Type: UploadTypeMultipart,
|
||||
ID: upload.UploadID,
|
||||
Key: upload.Key,
|
||||
Size: size,
|
||||
Hash: hash,
|
||||
}),
|
||||
PartSize: partSize,
|
||||
Sign: authSign,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHashs []string) (*UploadResult, error) {
|
||||
@@ -164,8 +171,10 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//nolint:gosec //tofix G401: Use of weak cryptographic primitive
|
||||
if md5Sum := md5.Sum([]byte(strings.Join(partHashs, partSeparator))); hex.EncodeToString(md5Sum[:]) != upload.Hash {
|
||||
fmt.Println("CompleteUpload sum:", hex.EncodeToString(md5Sum[:]), "upload hash:", upload.Hash)
|
||||
|
||||
return nil, errors.New("md5 mismatching")
|
||||
}
|
||||
if info, err := c.impl.StatObject(ctx, c.HashPath(upload.Hash)); err == nil {
|
||||
@@ -193,7 +202,7 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa
|
||||
ETag: part,
|
||||
}
|
||||
}
|
||||
// todo: 验证大小
|
||||
// todo: verify size
|
||||
result, err := c.impl.CompleteMultipartUpload(ctx, upload.ID, upload.Key, parts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -208,11 +217,12 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa
|
||||
if uploadInfo.Size != upload.Size {
|
||||
return nil, errors.New("upload size mismatching")
|
||||
}
|
||||
//nolint:gosec //G401: Use of weak cryptographic primitive
|
||||
md5Sum := md5.Sum([]byte(strings.Join([]string{uploadInfo.ETag}, partSeparator)))
|
||||
if md5val := hex.EncodeToString(md5Sum[:]); md5val != upload.Hash {
|
||||
return nil, errs.ErrArgs.Wrap(fmt.Sprintf("md5 mismatching %s != %s", md5val, upload.Hash))
|
||||
}
|
||||
// 防止在这个时候,并发操作,导致文件被覆盖
|
||||
// Prevent concurrent operations at this time to avoid file overwrite
|
||||
copyInfo, err := c.impl.CopyObject(ctx, uploadInfo.Key, upload.Key+"."+c.UUID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -230,6 +240,7 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa
|
||||
default:
|
||||
return nil, errors.New("invalid upload id type")
|
||||
}
|
||||
|
||||
return &UploadResult{
|
||||
Key: targetKey,
|
||||
Size: upload.Size,
|
||||
@@ -261,5 +272,6 @@ func (c *Controller) AccessURL(ctx context.Context, name string, expire time.Dur
|
||||
opt.Filename = ""
|
||||
opt.ContentType = ""
|
||||
}
|
||||
|
||||
return c.impl.AccessURL(ctx, name, expire, opt)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ func newMultipartUploadID(id multipartUploadID) string {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
@@ -45,5 +46,6 @@ func parseMultipartUploadID(id string) (*multipartUploadID, error) {
|
||||
if err := json.Unmarshal(data, &upload); err != nil {
|
||||
return nil, fmt.Errorf("invalid multipart upload id: %w", err)
|
||||
}
|
||||
|
||||
return &upload, nil
|
||||
}
|
||||
|
||||
+72
-52
@@ -44,11 +44,6 @@ const (
|
||||
imageWebp = "webp"
|
||||
)
|
||||
|
||||
const (
|
||||
videoSnapshotImagePng = "png"
|
||||
videoSnapshotImageJpg = "jpg"
|
||||
)
|
||||
|
||||
func NewCos() (s3.Interface, error) {
|
||||
conf := config.Config.Object.Cos
|
||||
u, err := url.Parse(conf.BucketURL)
|
||||
@@ -62,6 +57,7 @@ func NewCos() (s3.Interface, error) {
|
||||
SessionToken: conf.SessionToken,
|
||||
},
|
||||
})
|
||||
|
||||
return &Cos{
|
||||
copyURL: u.Host + "/",
|
||||
client: client,
|
||||
@@ -92,6 +88,7 @@ func (c *Cos) InitiateMultipartUpload(ctx context.Context, name string) (*s3.Ini
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.InitiateMultipartUploadResult{
|
||||
UploadID: result.UploadID,
|
||||
Bucket: result.Bucket,
|
||||
@@ -113,6 +110,7 @@ func (c *Cos) CompleteMultipartUpload(ctx context.Context, uploadID string, name
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CompleteMultipartUploadResult{
|
||||
Location: result.Location,
|
||||
Bucket: result.Bucket,
|
||||
@@ -135,6 +133,7 @@ func (c *Cos) PartSize(ctx context.Context, size int64) (int64, error) {
|
||||
if size%maxNumSize != 0 {
|
||||
partSize++
|
||||
}
|
||||
|
||||
return partSize, nil
|
||||
}
|
||||
|
||||
@@ -157,6 +156,7 @@ func (c *Cos) AuthSign(ctx context.Context, uploadID string, name string, expire
|
||||
Query: url.Values{"partNumber": {strconv.Itoa(partNumber)}},
|
||||
}
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -165,11 +165,13 @@ func (c *Cos) PresignedPutObject(ctx context.Context, name string, expire time.D
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
func (c *Cos) DeleteObject(ctx context.Context, name string) error {
|
||||
_, err := c.client.Object.Delete(ctx, name)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -185,25 +187,26 @@ func (c *Cos) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, erro
|
||||
if res.ETag = strings.ToLower(strings.ReplaceAll(info.Header.Get("ETag"), `"`, "")); res.ETag == "" {
|
||||
return nil, errors.New("StatObject etag not found")
|
||||
}
|
||||
if contentLengthStr := info.Header.Get("Content-Length"); contentLengthStr == "" {
|
||||
contentLengthStr := info.Header.Get("Content-Length")
|
||||
if contentLengthStr == "" {
|
||||
return nil, errors.New("StatObject content-length not found")
|
||||
} else {
|
||||
res.Size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject content-length parse error: %w", err)
|
||||
}
|
||||
if res.Size < 0 {
|
||||
return nil, errors.New("StatObject content-length must be greater than 0")
|
||||
}
|
||||
}
|
||||
if lastModified := info.Header.Get("Last-Modified"); lastModified == "" {
|
||||
res.Size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject content-length parse error: %w", err)
|
||||
}
|
||||
if res.Size < 0 {
|
||||
return nil, errors.New("StatObject content-length must be greater than 0")
|
||||
}
|
||||
lastModified := info.Header.Get("Last-Modified")
|
||||
if lastModified == "" {
|
||||
return nil, errors.New("StatObject last-modified not found")
|
||||
} else {
|
||||
res.LastModified, err = time.Parse(http.TimeFormat, lastModified)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject last-modified parse error: %w", err)
|
||||
}
|
||||
}
|
||||
res.LastModified, err = time.Parse(http.TimeFormat, lastModified)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject last-modified parse error: %w", err)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -213,6 +216,7 @@ func (c *Cos) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CopyObjectInfo{
|
||||
Key: dst,
|
||||
ETag: strings.ReplaceAll(result.ETag, `"`, ``),
|
||||
@@ -220,16 +224,17 @@ func (c *Cos) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
||||
}
|
||||
|
||||
func (c *Cos) IsNotFound(err error) bool {
|
||||
switch e := err.(type) {
|
||||
case *cos.ErrorResponse:
|
||||
return e.Response.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
default:
|
||||
return false
|
||||
var cosErr *cos.ErrorResponse
|
||||
if errors.As(err, &cosErr) {
|
||||
return cosErr.Response.StatusCode == http.StatusNotFound || cosErr.Code == "NoSuchKey"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Cos) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error {
|
||||
_, err := c.client.Object.AbortMultipartUpload(ctx, name, uploadID)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -257,46 +262,59 @@ func (c *Cos) ListUploadedParts(ctx context.Context, uploadID string, name strin
|
||||
Size: part.Size,
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||
var imageMogr string
|
||||
var option cos.PresignedURLOptions
|
||||
if opt != nil {
|
||||
query := make(url.Values)
|
||||
if opt.Image != nil {
|
||||
// https://cloud.tencent.com/document/product/436/44880
|
||||
style := make([]string, 0, 2)
|
||||
wh := make([]string, 2)
|
||||
if opt.Image.Width > 0 {
|
||||
wh[0] = strconv.Itoa(opt.Image.Width)
|
||||
}
|
||||
if opt.Image.Height > 0 {
|
||||
wh[1] = strconv.Itoa(opt.Image.Height)
|
||||
}
|
||||
if opt.Image.Width > 0 || opt.Image.Height > 0 {
|
||||
style = append(style, strings.Join(wh, "x"))
|
||||
}
|
||||
switch opt.Image.Format {
|
||||
case
|
||||
imagePng,
|
||||
imageJpg,
|
||||
imageJpeg,
|
||||
imageGif,
|
||||
imageWebp:
|
||||
style = append(style, "format/"+opt.Image.Format)
|
||||
}
|
||||
if len(style) > 0 {
|
||||
imageMogr = "imageMogr2/thumbnail/" + strings.Join(style, "/") + "/ignore-error/1"
|
||||
}
|
||||
getImageMogr := func(opt *s3.AccessURLOption) (imageMogr string) {
|
||||
if opt.Image == nil {
|
||||
return imageMogr
|
||||
}
|
||||
// https://cloud.tencent.com/document/product/436/44880
|
||||
style := make([]string, 0, 2)
|
||||
wh := make([]string, 2)
|
||||
if opt.Image.Width > 0 {
|
||||
wh[0] = strconv.Itoa(opt.Image.Width)
|
||||
}
|
||||
if opt.Image.Height > 0 {
|
||||
wh[1] = strconv.Itoa(opt.Image.Height)
|
||||
}
|
||||
if opt.Image.Width > 0 || opt.Image.Height > 0 {
|
||||
style = append(style, strings.Join(wh, "x"))
|
||||
}
|
||||
switch opt.Image.Format {
|
||||
case
|
||||
imagePng,
|
||||
imageJpg,
|
||||
imageJpeg,
|
||||
imageGif,
|
||||
imageWebp:
|
||||
style = append(style, "format/"+opt.Image.Format)
|
||||
}
|
||||
if len(style) > 0 {
|
||||
imageMogr = "imageMogr2/thumbnail/" + strings.Join(style, "/") + "/ignore-error/1"
|
||||
}
|
||||
|
||||
return imageMogr
|
||||
}
|
||||
getQuery := func(opt *s3.AccessURLOption) (query url.Values) {
|
||||
query = make(url.Values)
|
||||
if opt.ContentType != "" {
|
||||
query.Set("response-content-type", opt.ContentType)
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
query.Set("response-content-disposition", `attachment; filename=`+strconv.Quote(opt.Filename))
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
if opt != nil {
|
||||
imageMogr = getImageMogr(opt)
|
||||
query := getQuery(opt)
|
||||
if len(query) > 0 {
|
||||
option.Query = &query
|
||||
}
|
||||
@@ -317,6 +335,7 @@ func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration,
|
||||
rawURL.RawQuery = rawURL.RawQuery + "&" + imageMogr
|
||||
}
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
@@ -324,5 +343,6 @@ func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Dura
|
||||
if !config.Config.Object.Cos.PublicRead {
|
||||
return c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, opt)
|
||||
}
|
||||
|
||||
return c.client.Object.GetObjectURL(name), nil
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ func ImageStat(reader io.Reader) (image.Image, string, error) {
|
||||
|
||||
func ImageWidthHeight(img image.Image) (int, int) {
|
||||
bounds := img.Bounds().Max
|
||||
|
||||
return bounds.X, bounds.Y
|
||||
}
|
||||
|
||||
@@ -47,27 +48,27 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
imgWidth := bounds.Max.X
|
||||
imgHeight := bounds.Max.Y
|
||||
|
||||
// 计算缩放比例
|
||||
// Calculate scaling ratio
|
||||
scaleWidth := float64(maxWidth) / float64(imgWidth)
|
||||
scaleHeight := float64(maxHeight) / float64(imgHeight)
|
||||
|
||||
// 如果都为0,则不缩放,返回原始图片
|
||||
// If both maxWidth and maxHeight are 0, return the original image
|
||||
if maxWidth == 0 && maxHeight == 0 {
|
||||
return img
|
||||
}
|
||||
|
||||
// 如果宽度和高度都大于0,则选择较小的缩放比例,以保持宽高比
|
||||
// If both maxWidth and maxHeight are greater than 0, choose the smaller scaling ratio to maintain aspect ratio
|
||||
if maxWidth > 0 && maxHeight > 0 {
|
||||
scale := scaleWidth
|
||||
if scaleHeight < scaleWidth {
|
||||
scale = scaleHeight
|
||||
}
|
||||
|
||||
// 计算缩略图尺寸
|
||||
// Calculate thumbnail size
|
||||
thumbnailWidth := int(float64(imgWidth) * scale)
|
||||
thumbnailHeight := int(float64(imgHeight) * scale)
|
||||
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -80,12 +81,12 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
return thumbnail
|
||||
}
|
||||
|
||||
// 如果只指定了宽度或高度,则根据最大不超过的规则生成缩略图
|
||||
// If only maxWidth or maxHeight is specified, generate thumbnail according to the "max not exceed" rule
|
||||
if maxWidth > 0 {
|
||||
thumbnailWidth := maxWidth
|
||||
thumbnailHeight := int(float64(imgHeight) * scaleWidth)
|
||||
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -102,7 +103,7 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
thumbnailWidth := int(float64(imgWidth) * scaleHeight)
|
||||
thumbnailHeight := maxHeight
|
||||
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -115,6 +116,6 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
return thumbnail
|
||||
}
|
||||
|
||||
// 默认情况下,返回原始图片
|
||||
// By default, return the original image
|
||||
return img
|
||||
}
|
||||
|
||||
+126
-49
@@ -111,6 +111,7 @@ func NewMinio() (s3.Interface, error) {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
fmt.Println("init minio error:", err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -141,8 +142,9 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
return fmt.Errorf("check bucket exists error: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
if err := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||
return fmt.Errorf("make bucket error: %w", err)
|
||||
err2 := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{})
|
||||
if err2 != nil {
|
||||
return fmt.Errorf("make bucket error: %w", err2)
|
||||
}
|
||||
}
|
||||
if conf.PublicRead {
|
||||
@@ -150,8 +152,9 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
`{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject","s3:PutObject"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::%s/*"],"Sid": ""}]}`,
|
||||
conf.Bucket,
|
||||
)
|
||||
if err := m.core.Client.SetBucketPolicy(ctx, conf.Bucket, policy); err != nil {
|
||||
return err
|
||||
err2 := m.core.Client.SetBucketPolicy(ctx, conf.Bucket, policy)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
}
|
||||
m.location, err = m.core.Client.GetBucketLocation(ctx, conf.Bucket)
|
||||
@@ -182,6 +185,7 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
vblc.Elem().Elem().Interface().(interface{ Set(string, string) }).Set(conf.Bucket, m.location)
|
||||
}()
|
||||
m.init = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -205,6 +209,7 @@ func (m *Minio) InitiateMultipartUpload(ctx context.Context, name string) (*s3.I
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.InitiateMultipartUploadResult{
|
||||
Bucket: m.bucket,
|
||||
Key: name,
|
||||
@@ -227,6 +232,7 @@ func (m *Minio) CompleteMultipartUpload(ctx context.Context, uploadID string, na
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CompleteMultipartUploadResult{
|
||||
Location: upload.Location,
|
||||
Bucket: upload.Bucket,
|
||||
@@ -249,6 +255,7 @@ func (m *Minio) PartSize(ctx context.Context, size int64) (int64, error) {
|
||||
if size%maxNumSize != 0 {
|
||||
partSize++
|
||||
}
|
||||
|
||||
return partSize, nil
|
||||
}
|
||||
|
||||
@@ -282,6 +289,7 @@ func (m *Minio) AuthSign(ctx context.Context, uploadID string, name string, expi
|
||||
if m.prefix != "" {
|
||||
result.URL = m.signEndpoint + m.prefix + "/" + m.bucket + "/" + name
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -296,6 +304,7 @@ func (m *Minio) PresignedPutObject(ctx context.Context, name string, expire time
|
||||
if m.prefix != "" {
|
||||
rawURL.Path = path.Join(m.prefix, rawURL.Path)
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
@@ -303,6 +312,7 @@ func (m *Minio) DeleteObject(ctx context.Context, name string) error {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.core.Client.RemoveObject(ctx, m.bucket, name, minio.RemoveObjectOptions{})
|
||||
}
|
||||
|
||||
@@ -314,6 +324,7 @@ func (m *Minio) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.ObjectInfo{
|
||||
ETag: strings.ToLower(info.ETag),
|
||||
Key: info.Key,
|
||||
@@ -336,6 +347,7 @@ func (m *Minio) CopyObject(ctx context.Context, src string, dst string) (*s3.Cop
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CopyObjectInfo{
|
||||
Key: dst,
|
||||
ETag: strings.ToLower(result.ETag),
|
||||
@@ -346,20 +358,23 @@ func (m *Minio) IsNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch e := err.(type) {
|
||||
case minio.ErrorResponse:
|
||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
case *minio.ErrorResponse:
|
||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
default:
|
||||
return false
|
||||
var minioErr minio.ErrorResponse
|
||||
if errors.As(err, &minio.ErrorResponse{}) {
|
||||
return minioErr.StatusCode == http.StatusNotFound || minioErr.Code == "NoSuchKey"
|
||||
}
|
||||
var minioErr2 *minio.ErrorResponse
|
||||
if errors.As(err, &minioErr2) {
|
||||
return minioErr2.StatusCode == http.StatusNotFound || minioErr2.Code == "NoSuchKey"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Minio) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.core.AbortMultipartUpload(ctx, m.bucket, name, uploadID)
|
||||
}
|
||||
|
||||
@@ -386,6 +401,7 @@ func (m *Minio) ListUploadedParts(ctx context.Context, uploadID string, name str
|
||||
Size: part.Size,
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -410,14 +426,17 @@ func (m *Minio) presignedGetObject(ctx context.Context, name string, expire time
|
||||
if m.prefix != "" {
|
||||
rawURL.Path = path.Join(m.prefix, rawURL.Path)
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
reqParams := make(url.Values)
|
||||
func (m *Minio) getImageInfoForAccessURL(
|
||||
ctx context.Context,
|
||||
name string,
|
||||
expire time.Duration,
|
||||
opt *s3.AccessURLOption,
|
||||
reqParams url.Values,
|
||||
) (fileInfo *s3.ObjectInfo, objectInfoPath, msg string, err error) {
|
||||
if opt != nil {
|
||||
if opt.ContentType != "" {
|
||||
reqParams.Set("response-content-type", opt.ContentType)
|
||||
@@ -427,35 +446,47 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
||||
}
|
||||
}
|
||||
if opt.Image == nil || (opt.Image.Width < 0 && opt.Image.Height < 0 && opt.Image.Format == "") || (opt.Image.Width > maxImageWidth || opt.Image.Height > maxImageHeight) {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
msg, err = m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
|
||||
return nil, "", msg, err
|
||||
}
|
||||
fileInfo, err := m.StatObject(ctx, name)
|
||||
fileInfo, err = m.StatObject(ctx, name)
|
||||
objectInfoPath = path.Join(pathInfo, fileInfo.ETag, "image.json")
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, "", msg, err
|
||||
}
|
||||
if fileInfo.Size > maxImageSize {
|
||||
return "", errors.New("file size too large")
|
||||
return nil, "", "", errors.New("file size too large")
|
||||
}
|
||||
objectInfoPath := path.Join(pathInfo, fileInfo.ETag, "image.json")
|
||||
var (
|
||||
img image.Image
|
||||
info minioImageInfo
|
||||
)
|
||||
data, err := m.getObjectData(ctx, objectInfoPath, 1024)
|
||||
|
||||
return fileInfo, objectInfoPath, "", nil
|
||||
}
|
||||
|
||||
func (m *Minio) loadImgDataForAccessURL(objectInfoPath string, ctx context.Context, name string, info *minioImageInfo) (img image.Image, msg string, err error) {
|
||||
var data []byte
|
||||
data, err = m.getObjectData(ctx, objectInfoPath, 1024)
|
||||
|
||||
//nolint:nestif //easy enough to understand
|
||||
if err == nil {
|
||||
if err := json.Unmarshal(data, &info); err != nil {
|
||||
return "", fmt.Errorf("unmarshal minio image info.json error: %w", err)
|
||||
err = json.Unmarshal(data, &info)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unmarshal minio image info.json error: %w", err)
|
||||
}
|
||||
if info.NotImage {
|
||||
return "", errors.New("not image")
|
||||
return nil, "", errors.New("not image")
|
||||
}
|
||||
} else if m.IsNotFound(err) {
|
||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
var reader *minio.Object
|
||||
reader, err = m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
return img, msg, err
|
||||
}
|
||||
defer reader.Close()
|
||||
imageInfo, format, err := ImageStat(reader)
|
||||
var (
|
||||
imageInfo image.Image
|
||||
format string
|
||||
)
|
||||
imageInfo, format, err = ImageStat(reader)
|
||||
if err == nil {
|
||||
info.NotImage = false
|
||||
info.Format = format
|
||||
@@ -464,16 +495,22 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
||||
} else {
|
||||
info.NotImage = true
|
||||
}
|
||||
data, err := json.Marshal(&info)
|
||||
|
||||
data, err = json.Marshal(&info)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return img, msg, err
|
||||
}
|
||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, objectInfoPath, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{}); err != nil {
|
||||
return "", err
|
||||
|
||||
_, err = m.core.Client.PutObject(ctx, m.bucket, objectInfoPath, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{})
|
||||
if err != nil {
|
||||
return img, msg, err
|
||||
}
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return img, msg, err
|
||||
}
|
||||
|
||||
func (m *Minio) formatImgInfoForAccessURL(opt *s3.AccessURLOption, info *minioImageInfo, reqParams url.Values) {
|
||||
if opt.Image.Width > info.Width || opt.Image.Width <= 0 {
|
||||
opt.Image.Width = info.Width
|
||||
}
|
||||
@@ -496,24 +533,24 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
||||
}
|
||||
}
|
||||
reqParams.Set("response-content-type", "image/"+opt.Image.Format)
|
||||
if opt.Image.Width == info.Width && opt.Image.Height == info.Height && opt.Image.Format == info.Format {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
cacheKey := filepath.Join(pathInfo, fileInfo.ETag, fmt.Sprintf("image_w%d_h%d.%s", opt.Image.Width, opt.Image.Height, opt.Image.Format))
|
||||
if _, err := m.core.Client.StatObject(ctx, m.bucket, cacheKey, minio.StatObjectOptions{}); err == nil {
|
||||
}
|
||||
|
||||
func (m *Minio) cacheImgInfoForAccessURL(ctx context.Context, name, cacheKey string, img image.Image, expire time.Duration, opt *s3.AccessURLOption, reqParams url.Values) (string, error) {
|
||||
_, err := m.core.Client.StatObject(ctx, m.bucket, cacheKey, minio.StatObjectOptions{})
|
||||
if err == nil {
|
||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
||||
} else if !m.IsNotFound(err) {
|
||||
return "", err
|
||||
}
|
||||
if img == nil {
|
||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
reader, err2 := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err2 != nil {
|
||||
return "", err2
|
||||
}
|
||||
defer reader.Close()
|
||||
img, _, err = ImageStat(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
img, _, err2 = ImageStat(reader)
|
||||
if err2 != nil {
|
||||
return "", err2
|
||||
}
|
||||
}
|
||||
thumbnail := resizeImage(img, opt.Image.Width, opt.Image.Height)
|
||||
@@ -526,9 +563,48 @@ func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration
|
||||
case formatGif:
|
||||
err = gif.Encode(buf, thumbnail, nil)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, cacheKey, buf, int64(buf.Len()), minio.PutObjectOptions{}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||
errInit := m.initMinio(ctx)
|
||||
if errInit != nil {
|
||||
return "", errInit
|
||||
}
|
||||
reqParams := make(url.Values)
|
||||
fileInfo, objectInfoPath, msg, err := m.getImageInfoForAccessURL(ctx, name, expire, opt, reqParams)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// load-cache img data
|
||||
var (
|
||||
img image.Image
|
||||
info minioImageInfo
|
||||
)
|
||||
img, msg, err = m.loadImgDataForAccessURL(objectInfoPath, ctx, name, &info)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// format img info
|
||||
m.formatImgInfoForAccessURL(opt, &info, reqParams)
|
||||
// no need resize
|
||||
if opt.Image.Width == info.Width && opt.Image.Height == info.Height && opt.Image.Format == info.Format {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
// cache img
|
||||
cacheKey := filepath.Join(pathInfo, fileInfo.ETag, fmt.Sprintf("image_w%d_h%d.%s", opt.Image.Width, opt.Image.Height, opt.Image.Format))
|
||||
msg, err = m.cacheImgInfoForAccessURL(ctx, name, cacheKey, img, expire, opt, reqParams)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// return cache img
|
||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
||||
}
|
||||
|
||||
@@ -541,5 +617,6 @@ func (m *Minio) getObjectData(ctx context.Context, name string, limit int64) ([]
|
||||
if limit < 0 {
|
||||
return io.ReadAll(object)
|
||||
}
|
||||
|
||||
return io.ReadAll(io.LimitReader(object, 1024))
|
||||
}
|
||||
|
||||
Regular → Executable
+65
-54
@@ -45,11 +45,6 @@ const (
|
||||
imageWebp = "webp"
|
||||
)
|
||||
|
||||
const (
|
||||
videoSnapshotImagePng = "png"
|
||||
videoSnapshotImageJpg = "jpg"
|
||||
)
|
||||
|
||||
func NewOSS() (s3.Interface, error) {
|
||||
conf := config.Config.Object.Oss
|
||||
if conf.BucketURL == "" {
|
||||
@@ -66,6 +61,7 @@ func NewOSS() (s3.Interface, error) {
|
||||
if conf.BucketURL[len(conf.BucketURL)-1] != '/' {
|
||||
conf.BucketURL += "/"
|
||||
}
|
||||
|
||||
return &OSS{
|
||||
bucketURL: conf.BucketURL,
|
||||
bucket: bucket,
|
||||
@@ -98,6 +94,7 @@ func (o *OSS) InitiateMultipartUpload(ctx context.Context, name string) (*s3.Ini
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.InitiateMultipartUploadResult{
|
||||
UploadID: result.UploadID,
|
||||
Bucket: result.Bucket,
|
||||
@@ -121,6 +118,7 @@ func (o *OSS) CompleteMultipartUpload(ctx context.Context, uploadID string, name
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CompleteMultipartUploadResult{
|
||||
Location: result.Location,
|
||||
Bucket: result.Bucket,
|
||||
@@ -143,6 +141,7 @@ func (o *OSS) PartSize(ctx context.Context, size int64) (int64, error) {
|
||||
if size%maxNumSize != 0 {
|
||||
partSize++
|
||||
}
|
||||
|
||||
return partSize, nil
|
||||
}
|
||||
|
||||
@@ -155,7 +154,7 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
||||
}
|
||||
for i, partNumber := range partNumbers {
|
||||
rawURL := fmt.Sprintf(`%s%s?partNumber=%d&uploadId=%s`, o.bucketURL, name, partNumber, uploadID)
|
||||
request, err := http.NewRequest(http.MethodPut, rawURL, nil)
|
||||
request, err := http.NewRequestWithContext(context.Background(), http.MethodPut, rawURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -175,6 +174,7 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
|
||||
Header: request.Header,
|
||||
}
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -191,25 +191,26 @@ func (o *OSS) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, erro
|
||||
if res.ETag = strings.ToLower(strings.ReplaceAll(header.Get("ETag"), `"`, ``)); res.ETag == "" {
|
||||
return nil, errors.New("StatObject etag not found")
|
||||
}
|
||||
if contentLengthStr := header.Get("Content-Length"); contentLengthStr == "" {
|
||||
contentLengthStr := header.Get("Content-Length")
|
||||
if contentLengthStr == "" {
|
||||
return nil, errors.New("StatObject content-length not found")
|
||||
} else {
|
||||
res.Size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject content-length parse error: %w", err)
|
||||
}
|
||||
if res.Size < 0 {
|
||||
return nil, errors.New("StatObject content-length must be greater than 0")
|
||||
}
|
||||
}
|
||||
if lastModified := header.Get("Last-Modified"); lastModified == "" {
|
||||
res.Size, err = strconv.ParseInt(contentLengthStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject content-length parse error: %w", err)
|
||||
}
|
||||
if res.Size < 0 {
|
||||
return nil, errors.New("StatObject content-length must be greater than 0")
|
||||
}
|
||||
lastModified := header.Get("Last-Modified")
|
||||
if lastModified == "" {
|
||||
return nil, errors.New("StatObject last-modified not found")
|
||||
} else {
|
||||
res.LastModified, err = time.Parse(http.TimeFormat, lastModified)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject last-modified parse error: %w", err)
|
||||
}
|
||||
}
|
||||
res.LastModified, err = time.Parse(http.TimeFormat, lastModified)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatObject last-modified parse error: %w", err)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -222,6 +223,7 @@ func (o *OSS) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CopyObjectInfo{
|
||||
Key: dst,
|
||||
ETag: strings.ToLower(strings.ReplaceAll(result.ETag, `"`, ``)),
|
||||
@@ -229,6 +231,7 @@ func (o *OSS) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
||||
}
|
||||
|
||||
func (o *OSS) IsNotFound(err error) bool {
|
||||
//nolint:errorlint //this is exactly what we want,there is no risk for no wrapped errors
|
||||
switch e := err.(type) {
|
||||
case oss.ServiceError:
|
||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
@@ -271,6 +274,7 @@ func (o *OSS) ListUploadedParts(ctx context.Context, uploadID string, name strin
|
||||
Size: int64(part.Size),
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -278,39 +282,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration,
|
||||
publicRead := config.Config.Object.Oss.PublicRead
|
||||
var opts []oss.Option
|
||||
if opt != nil {
|
||||
if opt.Image != nil {
|
||||
// 文档地址: https://help.aliyun.com/zh/oss/user-guide/resize-images-4?spm=a2c4g.11186623.0.0.4b3b1e4fWW6yji
|
||||
var format string
|
||||
switch opt.Image.Format {
|
||||
case
|
||||
imagePng,
|
||||
imageJpg,
|
||||
imageJpeg,
|
||||
imageGif,
|
||||
imageWebp:
|
||||
format = opt.Image.Format
|
||||
default:
|
||||
opt.Image.Format = imageJpg
|
||||
}
|
||||
// https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,h_100,m_lfit
|
||||
process := "image/resize,m_lfit"
|
||||
if opt.Image.Width > 0 {
|
||||
process += ",w_" + strconv.Itoa(opt.Image.Width)
|
||||
}
|
||||
if opt.Image.Height > 0 {
|
||||
process += ",h_" + strconv.Itoa(opt.Image.Height)
|
||||
}
|
||||
process += ",format," + format
|
||||
opts = append(opts, oss.Process(process))
|
||||
}
|
||||
if !publicRead {
|
||||
if opt.ContentType != "" {
|
||||
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename=`+strconv.Quote(opt.Filename)))
|
||||
}
|
||||
}
|
||||
opts = optsForAccessURL(opt, opts, publicRead)
|
||||
}
|
||||
if expire <= 0 {
|
||||
expire = time.Hour * 24 * 365 * 99 // 99 years
|
||||
@@ -325,5 +297,44 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration,
|
||||
return "", err
|
||||
}
|
||||
params := getURLParams(*o.bucket.Client.Conn, rawParams)
|
||||
|
||||
return getURL(o.um, o.bucket.BucketName, name, params).String(), nil
|
||||
}
|
||||
|
||||
func optsForAccessURL(opt *s3.AccessURLOption, opts []oss.Option, publicRead bool) []oss.Option {
|
||||
if opt.Image != nil {
|
||||
// 文档地址: https://help.aliyun.com/zh/oss/user-guide/resize-images-4?spm=a2c4g.11186623.0.0.4b3b1e4fWW6yji
|
||||
var format string
|
||||
switch opt.Image.Format {
|
||||
case
|
||||
imagePng,
|
||||
imageJpg,
|
||||
imageJpeg,
|
||||
imageGif,
|
||||
imageWebp:
|
||||
format = opt.Image.Format
|
||||
default:
|
||||
opt.Image.Format = imageJpg
|
||||
}
|
||||
// https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/example.jpg?x-oss-process=image/resize,h_100,m_lfit
|
||||
process := "image/resize,m_lfit"
|
||||
if opt.Image.Width > 0 {
|
||||
process += ",w_" + strconv.Itoa(opt.Image.Width)
|
||||
}
|
||||
if opt.Image.Height > 0 {
|
||||
process += ",h_" + strconv.Itoa(opt.Image.Height)
|
||||
}
|
||||
process += ",format," + format
|
||||
opts = append(opts, oss.Process(process))
|
||||
}
|
||||
if !publicRead {
|
||||
if opt.ContentType != "" {
|
||||
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
||||
}
|
||||
if opt.Filename != "" {
|
||||
opts = append(opts, oss.ResponseContentDisposition(`attachment; filename=`+strconv.Quote(opt.Filename)))
|
||||
}
|
||||
}
|
||||
|
||||
return opts
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ type GroupModel struct {
|
||||
Introduction string `gorm:"column:introduction;size:255" json:"introduction"`
|
||||
FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"`
|
||||
CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"`
|
||||
Ex string `gorm:"column:ex" json:"ex;size:1024"`
|
||||
Ex string `gorm:"column:ex;size:1024" json:"ex"`
|
||||
Status int32 `gorm:"column:status"`
|
||||
CreatorUserID string `gorm:"column:creator_user_id;size:64"`
|
||||
GroupType int32 `gorm:"column:group_type"`
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package relation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -32,5 +34,5 @@ type GroupSimpleUserID struct {
|
||||
}
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
return utils.Unwrap(err) == gorm.ErrRecordNotFound
|
||||
return errors.Is(utils.Unwrap(err), gorm.ErrRecordNotFound)
|
||||
}
|
||||
|
||||
@@ -150,6 +150,7 @@ func (m *MsgDocModel) IsFull() bool {
|
||||
|
||||
func (m MsgDocModel) GetDocID(conversationID string, seq int64) string {
|
||||
seqSuffix := (seq - 1) / singleGocMsgNum
|
||||
|
||||
return m.indexGen(conversationID, seqSuffix)
|
||||
}
|
||||
|
||||
@@ -164,6 +165,7 @@ func (m MsgDocModel) GetDocIDSeqsMap(conversationID string, seqs []int64) map[st
|
||||
t[docID] = append(value, seqs[i])
|
||||
}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -181,5 +183,6 @@ func (MsgDocModel) GenExceptionMessageBySeqs(seqs []int64) (exceptionMsg []*sdkw
|
||||
msgModel.Seq = v
|
||||
exceptionMsg = append(exceptionMsg, msgModel)
|
||||
}
|
||||
|
||||
return exceptionMsg
|
||||
}
|
||||
|
||||
Regular → Executable
+33
-21
@@ -16,6 +16,7 @@ package unrelation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -44,27 +45,12 @@ type Mongo struct {
|
||||
// NewMongo Initialize MongoDB connection.
|
||||
func NewMongo() (*Mongo, error) {
|
||||
specialerror.AddReplace(mongo.ErrNoDocuments, errs.ErrRecordNotFound)
|
||||
uri := "mongodb://sample.host:27017/?maxPoolSize=20&w=majority"
|
||||
// uri := "mongodb://sample.host:27017/?maxPoolSize=20&w=majority"
|
||||
var uri string
|
||||
if config.Config.Mongo.Uri != "" {
|
||||
uri = config.Config.Mongo.Uri
|
||||
} else {
|
||||
mongodbHosts := ""
|
||||
for i, v := range config.Config.Mongo.Address {
|
||||
if i == len(config.Config.Mongo.Address)-1 {
|
||||
mongodbHosts += v
|
||||
} else {
|
||||
mongodbHosts += v + ","
|
||||
}
|
||||
}
|
||||
if config.Config.Mongo.Password != "" && config.Config.Mongo.Username != "" {
|
||||
uri = fmt.Sprintf("mongodb://%s:%s@%s/%s?maxPoolSize=%d&authSource=admin",
|
||||
config.Config.Mongo.Username, config.Config.Mongo.Password, mongodbHosts,
|
||||
config.Config.Mongo.Database, config.Config.Mongo.MaxPoolSize)
|
||||
} else {
|
||||
uri = fmt.Sprintf("mongodb://%s/%s/?maxPoolSize=%d&authSource=admin",
|
||||
mongodbHosts, config.Config.Mongo.Database,
|
||||
config.Config.Mongo.MaxPoolSize)
|
||||
}
|
||||
uri = defaultMongoUriForNewMongo()
|
||||
}
|
||||
fmt.Println("mongo:", uri)
|
||||
var mongoClient *mongo.Client
|
||||
@@ -76,17 +62,41 @@ func NewMongo() (*Mongo, error) {
|
||||
if err == nil {
|
||||
return &Mongo{db: mongoClient}, nil
|
||||
}
|
||||
if cmdErr, ok := err.(mongo.CommandError); ok {
|
||||
var cmdErr mongo.CommandError
|
||||
if errors.As(err, &cmdErr) {
|
||||
if cmdErr.Code == 13 || cmdErr.Code == 18 {
|
||||
return nil, err
|
||||
} else {
|
||||
fmt.Printf("Failed to connect to MongoDB: %s\n", err)
|
||||
}
|
||||
fmt.Printf("Failed to connect to MongoDB: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func defaultMongoUriForNewMongo() string {
|
||||
var uri string
|
||||
mongodbHosts := ""
|
||||
for i, v := range config.Config.Mongo.Address {
|
||||
if i == len(config.Config.Mongo.Address)-1 {
|
||||
mongodbHosts += v
|
||||
} else {
|
||||
mongodbHosts += v + ","
|
||||
}
|
||||
}
|
||||
if config.Config.Mongo.Password != "" && config.Config.Mongo.Username != "" {
|
||||
uri = fmt.Sprintf("mongodb://%s:%s@%s/%s?maxPoolSize=%d&authSource=admin",
|
||||
config.Config.Mongo.Username, config.Config.Mongo.Password, mongodbHosts,
|
||||
config.Config.Mongo.Database, config.Config.Mongo.MaxPoolSize)
|
||||
} else {
|
||||
uri = fmt.Sprintf("mongodb://%s/%s/?maxPoolSize=%d&authSource=admin",
|
||||
mongodbHosts, config.Config.Mongo.Database,
|
||||
config.Config.Mongo.MaxPoolSize)
|
||||
}
|
||||
|
||||
return uri
|
||||
}
|
||||
|
||||
func (m *Mongo) GetClient() *mongo.Client {
|
||||
return m.db
|
||||
}
|
||||
@@ -106,6 +116,7 @@ func (m *Mongo) CreateSuperGroupIndex() error {
|
||||
if err := m.createMongoIndex(unrelation.CUserToSuperGroup, true, "user_id"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,5 +150,6 @@ func (m *Mongo) createMongoIndex(collection string, isUnique bool, keys ...strin
|
||||
if err != nil {
|
||||
return utils.Wrap(err, result)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Regular → Executable
+83
-51
@@ -49,6 +49,7 @@ type MsgMongoDriver struct {
|
||||
|
||||
func NewMsgMongoDriver(database *mongo.Database) table.MsgDocModelInterface {
|
||||
collection := database.Collection(table.MsgDocModel{}.TableName())
|
||||
|
||||
return &MsgMongoDriver{MsgCollection: collection}
|
||||
}
|
||||
|
||||
@@ -59,6 +60,7 @@ func (m *MsgMongoDriver) PushMsgsToDoc(ctx context.Context, docID string, msgsTo
|
||||
|
||||
func (m *MsgMongoDriver) Create(ctx context.Context, model *table.MsgDocModel) error {
|
||||
_, err := m.MsgCollection.InsertOne(ctx, model)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ func (m *MsgMongoDriver) UpdateMsg(
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -108,6 +111,7 @@ func (m *MsgMongoDriver) PushUnique(
|
||||
if err != nil {
|
||||
return nil, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -120,6 +124,7 @@ func (m *MsgMongoDriver) UpdateMsgContent(ctx context.Context, docID string, ind
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -143,12 +148,14 @@ func (m *MsgMongoDriver) UpdateMsgStatusByIndexInOneDoc(
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MsgMongoDriver) FindOneByDocID(ctx context.Context, docID string) (*table.MsgDocModel, error) {
|
||||
doc := &table.MsgDocModel{}
|
||||
err := m.MsgCollection.FindOne(ctx, bson.M{"doc_id": docID}).Decode(doc)
|
||||
|
||||
return doc, err
|
||||
}
|
||||
|
||||
@@ -177,6 +184,7 @@ func (m *MsgMongoDriver) GetMsgDocModelByIndex(
|
||||
if len(msgs) > 0 {
|
||||
return &msgs[0], nil
|
||||
}
|
||||
|
||||
return nil, ErrMsgListNotExist
|
||||
}
|
||||
|
||||
@@ -225,6 +233,7 @@ func (m *MsgMongoDriver) DeleteMsgsInOneDocByIndex(ctx context.Context, docID st
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -233,6 +242,7 @@ func (m *MsgMongoDriver) DeleteDocs(ctx context.Context, docIDs []string) error
|
||||
return nil
|
||||
}
|
||||
_, err := m.MsgCollection.DeleteMany(ctx, bson.M{"doc_id": bson.M{"$in": docIDs}})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -246,6 +256,7 @@ func (m *MsgMongoDriver) GetMsgBySeqIndexIn1Doc(
|
||||
for _, seq := range seqs {
|
||||
indexs = append(indexs, m.model.GetMsgIndex(seq))
|
||||
}
|
||||
//nolint:govet //This is already the officially recommended standard practice.
|
||||
pipeline := mongo.Pipeline{
|
||||
{
|
||||
{"$match", bson.D{
|
||||
@@ -336,6 +347,7 @@ func (m *MsgMongoDriver) GetMsgBySeqIndexIn1Doc(
|
||||
}
|
||||
msgs = append(msgs, msg)
|
||||
}
|
||||
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
@@ -344,6 +356,7 @@ func (m *MsgMongoDriver) IsExistDocID(ctx context.Context, docID string) (bool,
|
||||
if err != nil {
|
||||
return false, errs.Wrap(err)
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
@@ -372,6 +385,7 @@ func (m *MsgMongoDriver) MarkSingleChatMsgsAsRead(
|
||||
updates = append(updates, updateModel)
|
||||
}
|
||||
_, err := m.MsgCollection.BulkWrite(ctx, updates)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -611,7 +625,39 @@ func (m *MsgMongoDriver) RangeUserSendCount(
|
||||
},
|
||||
)
|
||||
}
|
||||
pipeline := bson.A{
|
||||
pipeline := buildPiplineForRangeUserSendCount(or, start, end, sort, pageNumber, showNumber)
|
||||
cur, err := m.MsgCollection.Aggregate(ctx, pipeline, options.Aggregate().SetAllowDiskUse(true))
|
||||
if err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
defer cur.Close(ctx)
|
||||
var result []Result
|
||||
if err = cur.All(ctx, &result); err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
users = make([]*table.UserCount, len(result[0].Users))
|
||||
for i, r := range result[0].Users {
|
||||
users[i] = &table.UserCount{
|
||||
UserID: r.UserID,
|
||||
Count: r.Count,
|
||||
}
|
||||
}
|
||||
dateCount = make(map[string]int64)
|
||||
for _, r := range result[0].Dates {
|
||||
dateCount[r.Date] = r.Count
|
||||
}
|
||||
|
||||
return result[0].MsgCount, result[0].UserCount, users, dateCount, nil
|
||||
}
|
||||
|
||||
//nolint:funlen // it need to be such long
|
||||
func buildPiplineForRangeUserSendCount(or bson.A, start time.Time,
|
||||
end time.Time, sort int, pageNumber, showNumber int32,
|
||||
) bson.A {
|
||||
return bson.A{
|
||||
bson.M{
|
||||
"$match": bson.M{
|
||||
"$and": bson.A{
|
||||
@@ -795,30 +841,6 @@ func (m *MsgMongoDriver) RangeUserSendCount(
|
||||
},
|
||||
},
|
||||
}
|
||||
cur, err := m.MsgCollection.Aggregate(ctx, pipeline, options.Aggregate().SetAllowDiskUse(true))
|
||||
if err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
defer cur.Close(ctx)
|
||||
var result []Result
|
||||
if err := cur.All(ctx, &result); err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
users = make([]*table.UserCount, len(result[0].Users))
|
||||
for i, r := range result[0].Users {
|
||||
users[i] = &table.UserCount{
|
||||
UserID: r.UserID,
|
||||
Count: r.Count,
|
||||
}
|
||||
}
|
||||
dateCount = make(map[string]int64)
|
||||
for _, r := range result[0].Dates {
|
||||
dateCount[r.Date] = r.Count
|
||||
}
|
||||
return result[0].MsgCount, result[0].UserCount, users, dateCount, nil
|
||||
}
|
||||
|
||||
func (m *MsgMongoDriver) RangeGroupSendCount(
|
||||
@@ -847,7 +869,39 @@ func (m *MsgMongoDriver) RangeGroupSendCount(
|
||||
Count int64 `bson:"count"`
|
||||
} `bson:"dates"`
|
||||
}
|
||||
pipeline := bson.A{
|
||||
pipeline := buildPiplineForRangeGroupSendCount(start, end, sort, pageNumber, showNumber)
|
||||
cur, err := m.MsgCollection.Aggregate(ctx, pipeline, options.Aggregate().SetAllowDiskUse(true))
|
||||
if err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
defer cur.Close(ctx)
|
||||
var result []Result
|
||||
if err = cur.All(ctx, &result); err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
groups = make([]*table.GroupCount, len(result[0].Groups))
|
||||
for i, r := range result[0].Groups {
|
||||
groups[i] = &table.GroupCount{
|
||||
GroupID: r.GroupID,
|
||||
Count: r.Count,
|
||||
}
|
||||
}
|
||||
dateCount = make(map[string]int64)
|
||||
for _, r := range result[0].Dates {
|
||||
dateCount[r.Date] = r.Count
|
||||
}
|
||||
|
||||
return result[0].MsgCount, result[0].UserCount, groups, dateCount, nil
|
||||
}
|
||||
|
||||
//nolint:funlen //it need to has such length
|
||||
func buildPiplineForRangeGroupSendCount(start time.Time,
|
||||
end time.Time, sort int, pageNumber, showNumber int32,
|
||||
) bson.A {
|
||||
return bson.A{
|
||||
bson.M{
|
||||
"$match": bson.M{
|
||||
"$and": bson.A{
|
||||
@@ -1044,30 +1098,6 @@ func (m *MsgMongoDriver) RangeGroupSendCount(
|
||||
},
|
||||
},
|
||||
}
|
||||
cur, err := m.MsgCollection.Aggregate(ctx, pipeline, options.Aggregate().SetAllowDiskUse(true))
|
||||
if err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
defer cur.Close(ctx)
|
||||
var result []Result
|
||||
if err := cur.All(ctx, &result); err != nil {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
if len(result) == 0 {
|
||||
return 0, 0, nil, nil, errs.Wrap(err)
|
||||
}
|
||||
groups = make([]*table.GroupCount, len(result[0].Groups))
|
||||
for i, r := range result[0].Groups {
|
||||
groups[i] = &table.GroupCount{
|
||||
GroupID: r.GroupID,
|
||||
Count: r.Count,
|
||||
}
|
||||
}
|
||||
dateCount = make(map[string]int64)
|
||||
for _, r := range result[0].Dates {
|
||||
dateCount[r.Date] = r.Count
|
||||
}
|
||||
return result[0].MsgCount, result[0].UserCount, groups, dateCount, nil
|
||||
}
|
||||
|
||||
func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*table.MsgInfoModel, error) {
|
||||
@@ -1075,6 +1105,7 @@ func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
return total, msgs, nil
|
||||
}
|
||||
|
||||
@@ -1119,7 +1150,7 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
//nolint:govet //this is already standard
|
||||
pipe = mongo.Pipeline{
|
||||
{
|
||||
{"$match", bson.D{
|
||||
@@ -1214,5 +1245,6 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
|
||||
} else {
|
||||
msgs = msgs[start:]
|
||||
}
|
||||
|
||||
return n, msgs, nil
|
||||
}
|
||||
|
||||
@@ -31,12 +31,14 @@ func (m *MsgMongoDriver) ConvertMsgsDocLen(ctx context.Context, conversationIDs
|
||||
cursor, err := m.MsgCollection.Find(ctx, bson.M{"doc_id": regex})
|
||||
if err != nil {
|
||||
log.ZError(ctx, "convertAll find msg doc failed", err, "conversationID", conversationID)
|
||||
|
||||
continue
|
||||
}
|
||||
var msgDocs []table.MsgDocModel
|
||||
err = cursor.All(ctx, &msgDocs)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "convertAll cursor all failed", err, "conversationID", conversationID)
|
||||
|
||||
continue
|
||||
}
|
||||
if len(msgDocs) < 1 {
|
||||
@@ -44,39 +46,45 @@ func (m *MsgMongoDriver) ConvertMsgsDocLen(ctx context.Context, conversationIDs
|
||||
}
|
||||
log.ZInfo(ctx, "msg doc convert", "conversationID", conversationID, "len(msgDocs)", len(msgDocs))
|
||||
if len(msgDocs[0].Msg) == int(m.model.GetSingleGocMsgNum5000()) {
|
||||
if _, err := m.MsgCollection.DeleteMany(ctx, bson.M{"doc_id": regex}); err != nil {
|
||||
log.ZError(ctx, "convertAll delete many failed", err, "conversationID", conversationID)
|
||||
continue
|
||||
}
|
||||
var newMsgDocs []interface{}
|
||||
for _, msgDoc := range msgDocs {
|
||||
if int64(len(msgDoc.Msg)) == m.model.GetSingleGocMsgNum() {
|
||||
continue
|
||||
}
|
||||
var index int64
|
||||
for index < int64(len(msgDoc.Msg)) {
|
||||
msg := msgDoc.Msg[index]
|
||||
if msg != nil && msg.Msg != nil {
|
||||
msgDocModel := table.MsgDocModel{DocID: m.model.GetDocID(conversationID, msg.Msg.Seq)}
|
||||
end := index + m.model.GetSingleGocMsgNum()
|
||||
if int(end) >= len(msgDoc.Msg) {
|
||||
msgDocModel.Msg = msgDoc.Msg[index:]
|
||||
} else {
|
||||
msgDocModel.Msg = msgDoc.Msg[index:end]
|
||||
}
|
||||
newMsgDocs = append(newMsgDocs, msgDocModel)
|
||||
index = end
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = m.MsgCollection.InsertMany(ctx, newMsgDocs)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "convertAll insert many failed", err, "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
||||
} else {
|
||||
log.ZInfo(ctx, "msg doc convert", "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
||||
}
|
||||
convertMsgDocs(m, ctx, msgDocs, conversationID, regex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func convertMsgDocs(m *MsgMongoDriver, ctx context.Context, msgDocs []table.MsgDocModel, conversationID string, regex primitive.Regex) {
|
||||
var err error
|
||||
if _, err = m.MsgCollection.DeleteMany(ctx, bson.M{"doc_id": regex}); err != nil {
|
||||
log.ZError(ctx, "convertAll delete many failed", err, "conversationID", conversationID)
|
||||
|
||||
return
|
||||
}
|
||||
var newMsgDocs []interface{}
|
||||
for _, msgDoc := range msgDocs {
|
||||
if int64(len(msgDoc.Msg)) == m.model.GetSingleGocMsgNum() {
|
||||
continue
|
||||
}
|
||||
var index int64
|
||||
for index < int64(len(msgDoc.Msg)) {
|
||||
msg := msgDoc.Msg[index]
|
||||
if msg != nil && msg.Msg != nil {
|
||||
msgDocModel := table.MsgDocModel{DocID: m.model.GetDocID(conversationID, msg.Msg.Seq)}
|
||||
end := index + m.model.GetSingleGocMsgNum()
|
||||
if int(end) >= len(msgDoc.Msg) {
|
||||
msgDocModel.Msg = msgDoc.Msg[index:]
|
||||
} else {
|
||||
msgDocModel.Msg = msgDoc.Msg[index:end]
|
||||
}
|
||||
newMsgDocs = append(newMsgDocs, msgDocModel)
|
||||
index = end
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = m.MsgCollection.InsertMany(ctx, newMsgDocs)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "convertAll insert many failed", err, "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
||||
} else {
|
||||
log.ZInfo(ctx, "msg doc convert", "conversationID", conversationID, "len(newMsgDocs)", len(newMsgDocs))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ func (s *SuperGroupMongoDriver) CreateSuperGroup(ctx context.Context, groupID st
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ func (s *SuperGroupMongoDriver) TakeSuperGroup(
|
||||
if err := s.superGroupCollection.FindOne(ctx, bson.M{"group_id": groupID}).Decode(&group); err != nil {
|
||||
return nil, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
|
||||
@@ -86,6 +88,7 @@ func (s *SuperGroupMongoDriver) FindSuperGroup(
|
||||
if err := cursor.All(ctx, &groups); err != nil {
|
||||
return nil, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
@@ -113,6 +116,7 @@ func (s *SuperGroupMongoDriver) AddUserToSuperGroup(ctx context.Context, groupID
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -129,6 +133,7 @@ func (s *SuperGroupMongoDriver) RemoverUserFromSuperGroup(ctx context.Context, g
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -138,6 +143,7 @@ func (s *SuperGroupMongoDriver) GetSuperGroupByUserID(
|
||||
) (*unrelation.UserToSuperGroupModel, error) {
|
||||
var user unrelation.UserToSuperGroupModel
|
||||
err := s.userToSuperGroupCollection.FindOne(ctx, bson.M{"user_id": userID}).Decode(&user)
|
||||
|
||||
return &user, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
@@ -149,6 +155,7 @@ func (s *SuperGroupMongoDriver) DeleteSuperGroup(ctx context.Context, groupID st
|
||||
if _, err := s.superGroupCollection.DeleteOne(ctx, bson.M{"group_id": groupID}); err != nil {
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
return s.RemoveGroupFromUser(ctx, groupID, group.MemberIDs)
|
||||
}
|
||||
|
||||
@@ -158,5 +165,6 @@ func (s *SuperGroupMongoDriver) RemoveGroupFromUser(ctx context.Context, groupID
|
||||
bson.M{"user_id": bson.M{"$in": userIDs}},
|
||||
bson.M{"$pull": bson.M{"group_id_list": groupID}},
|
||||
)
|
||||
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
Regular → Executable
+14
-7
@@ -16,6 +16,7 @@ package unrelation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
@@ -50,6 +51,7 @@ type UserMongoDriver struct {
|
||||
// AddSubscriptionList Subscriber's handling of thresholds.
|
||||
func (u *UserMongoDriver) AddSubscriptionList(ctx context.Context, userID string, userIDList []string) error {
|
||||
// Check the number of lists in the key.
|
||||
//nolint:govet //this has already been the standard format for mongo.Pipeline
|
||||
pipeline := mongo.Pipeline{
|
||||
{{"$match", bson.D{{"user_id", SubscriptionPrefix + userID}}}},
|
||||
{{"$project", bson.D{{"count", bson.D{{"$size", "$user_id_list"}}}}}},
|
||||
@@ -65,7 +67,7 @@ func (u *UserMongoDriver) AddSubscriptionList(ctx context.Context, userID string
|
||||
}
|
||||
// iterate over aggregated results
|
||||
for cursor.Next(ctx) {
|
||||
err := cursor.Decode(&cnt)
|
||||
err = cursor.Decode(&cnt)
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
@@ -122,6 +124,7 @@ func (u *UserMongoDriver) AddSubscriptionList(ctx context.Context, userID string
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -139,6 +142,7 @@ func (u *UserMongoDriver) UnsubscriptionList(ctx context.Context, userID string,
|
||||
if err != nil {
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -152,6 +156,7 @@ func (u *UserMongoDriver) RemoveSubscribedListFromUser(ctx context.Context, user
|
||||
bson.M{"$pull": bson.M{"user_id_list": userID}},
|
||||
)
|
||||
}
|
||||
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -163,12 +168,13 @@ func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string
|
||||
bson.M{"user_id": SubscriptionPrefix + userID})
|
||||
err = cursor.Decode(&user)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||
return []string{}, nil
|
||||
} else {
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
|
||||
return user.UserIDList, nil
|
||||
}
|
||||
|
||||
@@ -180,11 +186,12 @@ func (u *UserMongoDriver) GetSubscribedList(ctx context.Context, userID string)
|
||||
bson.M{"user_id": SubscribedPrefix + userID})
|
||||
err = cursor.Decode(&user)
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
if errors.Is(err, mongo.ErrNoDocuments) {
|
||||
return []string{}, nil
|
||||
} else {
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
|
||||
return nil, errs.Wrap(err)
|
||||
}
|
||||
|
||||
return user.UserIDList, nil
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||
openkeeper "github.com/OpenIMSDK/tools/discoveryregistry/zookeeper"
|
||||
"github.com/OpenIMSDK/tools/log"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"google.golang.org/grpc"
|
||||
"time"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
func NewDiscoveryRegister(envType string) (discoveryregistry.SvcDiscoveryRegistry, error) {
|
||||
@@ -28,6 +30,7 @@ func NewDiscoveryRegister(envType string) (discoveryregistry.SvcDiscoveryRegistr
|
||||
client = nil
|
||||
err = errors.New("envType not correct")
|
||||
}
|
||||
|
||||
return client, err
|
||||
}
|
||||
|
||||
@@ -42,47 +45,51 @@ func NewK8sDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, error) {
|
||||
|
||||
func (cli *K8sDR) Register(serviceName, host string, port int, opts ...grpc.DialOption) error {
|
||||
cli.rpcRegisterAddr = serviceName
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *K8sDR) UnRegister() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *K8sDR) CreateRpcRootNodes(serviceNames []string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
func (cli *K8sDR) RegisterConf2Registry(key string, conf []byte) error {
|
||||
|
||||
func (cli *K8sDR) RegisterConf2Registry(key string, conf []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cli *K8sDR) GetConfFromRegistry(key string) ([]byte, error) {
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error) {
|
||||
|
||||
func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error) {
|
||||
conn, err := grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
|
||||
|
||||
return []*grpc.ClientConn{conn}, err
|
||||
}
|
||||
func (cli *K8sDR) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||||
|
||||
func (cli *K8sDR) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||||
return grpc.DialContext(ctx, serviceName, append(cli.options, opts...)...)
|
||||
}
|
||||
func (cli *K8sDR) GetSelfConnTarget() string {
|
||||
|
||||
func (cli *K8sDR) GetSelfConnTarget() string {
|
||||
return cli.rpcRegisterAddr
|
||||
}
|
||||
|
||||
func (cli *K8sDR) AddOption(opts ...grpc.DialOption) {
|
||||
cli.options = append(cli.options, opts...)
|
||||
}
|
||||
|
||||
func (cli *K8sDR) CloseConn(conn *grpc.ClientConn) {
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
// do not use this method for call rpc
|
||||
// do not use this method for call rpc.
|
||||
func (cli *K8sDR) GetClientLocalConns() map[string][]*grpc.ClientConn {
|
||||
fmt.Println("should not call this function!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -34,16 +34,21 @@ import (
|
||||
var client http.Client
|
||||
|
||||
func Get(url string) (response []byte, err error) {
|
||||
client := http.Client{Timeout: 5 * time.Second}
|
||||
resp, err := client.Get(url)
|
||||
clientGet := http.Client{Timeout: 5 * time.Second}
|
||||
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err2 := clientGet.Do(req)
|
||||
if err2 != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
body, err3 := io.ReadAll(resp.Body)
|
||||
if err3 != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
@@ -83,6 +88,7 @@ func Post(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -98,6 +104,7 @@ func PostReturn(
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(b, output)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -116,17 +123,22 @@ func callBackPostReturn(
|
||||
if err != nil {
|
||||
if callbackConfig.CallbackFailedContinue != nil && *callbackConfig.CallbackFailedContinue {
|
||||
log.ZWarn(ctx, "callback failed but continue", err, "url", url)
|
||||
|
||||
return errs.ErrCallbackContinue
|
||||
}
|
||||
|
||||
return errs.ErrNetwork.Wrap(err.Error())
|
||||
}
|
||||
if err = json.Unmarshal(b, output); err != nil {
|
||||
if callbackConfig.CallbackFailedContinue != nil && *callbackConfig.CallbackFailedContinue {
|
||||
log.ZWarn(ctx, "callback failed but continue", err, "url", url)
|
||||
|
||||
return errs.ErrCallbackContinue
|
||||
}
|
||||
|
||||
return errs.ErrData.Wrap(err.Error())
|
||||
}
|
||||
|
||||
return output.Parse()
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ func NewMConsumerGroup(consumerConfig *MConsumerGroupConfig, topics, addrs []str
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
return &MConsumerGroup{
|
||||
consumerGroup,
|
||||
groupID,
|
||||
|
||||
@@ -67,6 +67,7 @@ func NewKafkaProducer(addr []string, topic string) *Producer {
|
||||
producer, err = sarama.NewSyncProducer(p.addr, p.config) // Initialize the client
|
||||
if err == nil {
|
||||
p.producer = producer
|
||||
|
||||
return &p
|
||||
}
|
||||
//TODO If the password is wrong, exit directly
|
||||
@@ -83,6 +84,7 @@ func NewKafkaProducer(addr []string, topic string) *Producer {
|
||||
panic(err.Error())
|
||||
}
|
||||
p.producer = producer
|
||||
|
||||
return &p
|
||||
}
|
||||
|
||||
@@ -91,6 +93,7 @@ func GetMQHeaderWithContext(ctx context.Context) ([]sarama.RecordHeader, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []sarama.RecordHeader{
|
||||
{Key: []byte(constant.OperationID), Value: []byte(operationID)},
|
||||
{Key: []byte(constant.OpUserID), Value: []byte(opUserID)},
|
||||
@@ -100,10 +103,11 @@ func GetMQHeaderWithContext(ctx context.Context) ([]sarama.RecordHeader, error)
|
||||
}
|
||||
|
||||
func GetContextWithMQHeader(header []*sarama.RecordHeader) context.Context {
|
||||
var values []string
|
||||
values := make([]string, 0, len(header))
|
||||
for _, recordHeader := range header {
|
||||
values = append(values, string(recordHeader.Value))
|
||||
}
|
||||
|
||||
return mcontext.WithMustInfoCtx(values) // TODO
|
||||
}
|
||||
|
||||
@@ -134,5 +138,6 @@ func (p *Producer) SendMessage(ctx context.Context, key string, msg proto.Messag
|
||||
if err == nil {
|
||||
prome.Inc(prome.SendMsgCounter)
|
||||
}
|
||||
|
||||
return partition, offset, utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
@@ -42,11 +42,13 @@ func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typ
|
||||
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, typeKey)
|
||||
if err != nil {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
continue
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -55,11 +57,13 @@ func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID strin
|
||||
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
|
||||
if err != nil {
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
continue
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ var (
|
||||
ConversationCreateFailedCounter prometheus.Counter
|
||||
)
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewUserLoginCounter() {
|
||||
if UserLoginCounter != nil {
|
||||
return
|
||||
@@ -89,6 +90,7 @@ func NewUserLoginCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewUserRegisterCounter() {
|
||||
if UserRegisterCounter != nil {
|
||||
return
|
||||
@@ -99,6 +101,7 @@ func NewUserRegisterCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSeqGetSuccessCounter() {
|
||||
if SeqGetSuccessCounter != nil {
|
||||
return
|
||||
@@ -109,6 +112,7 @@ func NewSeqGetSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSeqGetFailedCounter() {
|
||||
if SeqGetFailedCounter != nil {
|
||||
return
|
||||
@@ -119,6 +123,7 @@ func NewSeqGetFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSeqSetSuccessCounter() {
|
||||
if SeqSetSuccessCounter != nil {
|
||||
return
|
||||
@@ -129,6 +134,7 @@ func NewSeqSetSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSeqSetFailedCounter() {
|
||||
if SeqSetFailedCounter != nil {
|
||||
return
|
||||
@@ -139,6 +145,7 @@ func NewSeqSetFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewApiRequestCounter() {
|
||||
if ApiRequestCounter != nil {
|
||||
return
|
||||
@@ -149,6 +156,7 @@ func NewApiRequestCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewApiRequestSuccessCounter() {
|
||||
if ApiRequestSuccessCounter != nil {
|
||||
return
|
||||
@@ -159,6 +167,7 @@ func NewApiRequestSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewApiRequestFailedCounter() {
|
||||
if ApiRequestFailedCounter != nil {
|
||||
return
|
||||
@@ -169,6 +178,7 @@ func NewApiRequestFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGrpcRequestCounter() {
|
||||
if GrpcRequestCounter != nil {
|
||||
return
|
||||
@@ -179,6 +189,7 @@ func NewGrpcRequestCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGrpcRequestSuccessCounter() {
|
||||
if GrpcRequestSuccessCounter != nil {
|
||||
return
|
||||
@@ -189,6 +200,7 @@ func NewGrpcRequestSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGrpcRequestFailedCounter() {
|
||||
if GrpcRequestFailedCounter != nil {
|
||||
return
|
||||
@@ -199,6 +211,7 @@ func NewGrpcRequestFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSendMsgCount() {
|
||||
if SendMsgCounter != nil {
|
||||
return
|
||||
@@ -209,6 +222,7 @@ func NewSendMsgCount() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgInsertRedisSuccessCounter() {
|
||||
if MsgInsertRedisSuccessCounter != nil {
|
||||
return
|
||||
@@ -219,6 +233,7 @@ func NewMsgInsertRedisSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix its
|
||||
func NewMsgInsertRedisFailedCounter() {
|
||||
if MsgInsertRedisFailedCounter != nil {
|
||||
return
|
||||
@@ -229,6 +244,7 @@ func NewMsgInsertRedisFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgInsertMongoSuccessCounter() {
|
||||
if MsgInsertMongoSuccessCounter != nil {
|
||||
return
|
||||
@@ -239,6 +255,7 @@ func NewMsgInsertMongoSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgInsertMongoFailedCounter() {
|
||||
if MsgInsertMongoFailedCounter != nil {
|
||||
return
|
||||
@@ -249,6 +266,7 @@ func NewMsgInsertMongoFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgPullFromRedisSuccessCounter() {
|
||||
if MsgPullFromRedisSuccessCounter != nil {
|
||||
return
|
||||
@@ -259,6 +277,7 @@ func NewMsgPullFromRedisSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgPullFromRedisFailedCounter() {
|
||||
if MsgPullFromRedisFailedCounter != nil {
|
||||
return
|
||||
@@ -269,6 +288,7 @@ func NewMsgPullFromRedisFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgPullFromMongoSuccessCounter() {
|
||||
if MsgPullFromMongoSuccessCounter != nil {
|
||||
return
|
||||
@@ -279,6 +299,7 @@ func NewMsgPullFromMongoSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgPullFromMongoFailedCounter() {
|
||||
if MsgPullFromMongoFailedCounter != nil {
|
||||
return
|
||||
@@ -319,6 +340,7 @@ func NewPullMsgBySeqListTotalCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSingleChatMsgRecvSuccessCounter() {
|
||||
if SingleChatMsgRecvSuccessCounter != nil {
|
||||
return
|
||||
@@ -329,6 +351,7 @@ func NewSingleChatMsgRecvSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGroupChatMsgRecvSuccessCounter() {
|
||||
if GroupChatMsgRecvSuccessCounter != nil {
|
||||
return
|
||||
@@ -339,6 +362,7 @@ func NewGroupChatMsgRecvSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewWorkSuperGroupChatMsgRecvSuccessCounter() {
|
||||
if WorkSuperGroupChatMsgRecvSuccessCounter != nil {
|
||||
return
|
||||
@@ -359,6 +383,7 @@ func NewOnlineUserGauges() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSingleChatMsgProcessSuccessCounter() {
|
||||
if SingleChatMsgProcessSuccessCounter != nil {
|
||||
return
|
||||
@@ -369,6 +394,7 @@ func NewSingleChatMsgProcessSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewSingleChatMsgProcessFailedCounter() {
|
||||
if SingleChatMsgProcessFailedCounter != nil {
|
||||
return
|
||||
@@ -379,6 +405,7 @@ func NewSingleChatMsgProcessFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGroupChatMsgProcessSuccessCounter() {
|
||||
if GroupChatMsgProcessSuccessCounter != nil {
|
||||
return
|
||||
@@ -389,6 +416,7 @@ func NewGroupChatMsgProcessSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewGroupChatMsgProcessFailedCounter() {
|
||||
if GroupChatMsgProcessFailedCounter != nil {
|
||||
return
|
||||
@@ -399,6 +427,7 @@ func NewGroupChatMsgProcessFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewWorkSuperGroupChatMsgProcessSuccessCounter() {
|
||||
if WorkSuperGroupChatMsgProcessSuccessCounter != nil {
|
||||
return
|
||||
@@ -409,6 +438,7 @@ func NewWorkSuperGroupChatMsgProcessSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewWorkSuperGroupChatMsgProcessFailedCounter() {
|
||||
if WorkSuperGroupChatMsgProcessFailedCounter != nil {
|
||||
return
|
||||
@@ -419,6 +449,7 @@ func NewWorkSuperGroupChatMsgProcessFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgOnlinePushSuccessCounter() {
|
||||
if MsgOnlinePushSuccessCounter != nil {
|
||||
return
|
||||
@@ -429,6 +460,7 @@ func NewMsgOnlinePushSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgOfflinePushSuccessCounter() {
|
||||
if MsgOfflinePushSuccessCounter != nil {
|
||||
return
|
||||
@@ -439,6 +471,7 @@ func NewMsgOfflinePushSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewMsgOfflinePushFailedCounter() {
|
||||
if MsgOfflinePushFailedCounter != nil {
|
||||
return
|
||||
@@ -449,6 +482,7 @@ func NewMsgOfflinePushFailedCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewConversationCreateSuccessCounter() {
|
||||
if ConversationCreateSuccessCounter != nil {
|
||||
return
|
||||
@@ -459,6 +493,7 @@ func NewConversationCreateSuccessCounter() {
|
||||
})
|
||||
}
|
||||
|
||||
//nolint:promlinter //no idea to fix it
|
||||
func NewConversationCreateFailedCounter() {
|
||||
if ConversationCreateFailedCounter != nil {
|
||||
return
|
||||
|
||||
@@ -30,13 +30,16 @@ func StartPrometheusSrv(prometheusPort int) error {
|
||||
if config.Config.Prometheus.Enable {
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
err := http.ListenAndServe(":"+strconv.Itoa(prometheusPort), nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func PrometheusHandler() gin.HandlerFunc {
|
||||
h := promhttp.Handler()
|
||||
|
||||
return func(c *gin.Context) {
|
||||
h.ServeHTTP(c.Writer, c.Request)
|
||||
}
|
||||
@@ -49,6 +52,7 @@ type responseBodyWriter struct {
|
||||
|
||||
func (r responseBodyWriter) Write(b []byte) (int, error) {
|
||||
r.body.Write(b)
|
||||
|
||||
return r.ResponseWriter.Write(b)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,4 +12,5 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package startrpc // import "github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||
// Package startrpc start rpc server.
|
||||
package startrpc
|
||||
|
||||
@@ -16,11 +16,12 @@ package startrpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/discovery_register"
|
||||
|
||||
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
@@ -32,6 +33,7 @@ import (
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
)
|
||||
|
||||
// Start rpc server.
|
||||
func Start(
|
||||
rpcPort int,
|
||||
rpcRegisterName string,
|
||||
@@ -39,16 +41,8 @@ func Start(
|
||||
rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||
options ...grpc.ServerOption,
|
||||
) error {
|
||||
fmt.Println(
|
||||
"start",
|
||||
rpcRegisterName,
|
||||
"server, port: ",
|
||||
rpcPort,
|
||||
"prometheusPort:",
|
||||
prometheusPort,
|
||||
", OpenIM version: ",
|
||||
config.Version,
|
||||
)
|
||||
fmt.Printf("start %s server, port: %d, prometheusPort: %d, OpenIM version: %s",
|
||||
rpcRegisterName, rpcPort, prometheusPort, config.Version)
|
||||
listener, err := net.Listen(
|
||||
"tcp",
|
||||
net.JoinHostPort(network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort)),
|
||||
@@ -63,11 +57,10 @@ func Start(
|
||||
zookeeper.WithFreq(time.Hour), zookeeper.WithUserNameAndPassword(
|
||||
config.Config.Zookeeper.Username,
|
||||
config.Config.Zookeeper.Password,
|
||||
), zookeeper.WithRoundRobin(), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/
|
||||
if err != nil {
|
||||
), zookeeper.WithRoundRobin(), zookeeper.WithTimeout(10), zookeeper.WithLogger(log.NewZkLogger()))*/if err != nil {
|
||||
return utils.Wrap1(err)
|
||||
}
|
||||
//defer zkClient.CloseZK()
|
||||
// defer zkClient.CloseZK()
|
||||
zkClient.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
registerIP, err := network.GetRpcRegisterIP(config.Config.Rpc.RegisterIP)
|
||||
if err != nil {
|
||||
@@ -108,5 +101,6 @@ func Start(
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return utils.Wrap1(srv.Serve(listener))
|
||||
}
|
||||
|
||||
Regular → Executable
+3
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
)
|
||||
|
||||
//nolint:staticcheck //we have not time looking for a replacement for x509 to fix the security valnerability
|
||||
func decryptPEM(data []byte, passphrase []byte) ([]byte, error) {
|
||||
if len(passphrase) == 0 {
|
||||
return data, nil
|
||||
@@ -33,6 +34,7 @@ func decryptPEM(data []byte, passphrase []byte) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(&pem.Block{
|
||||
Type: b.Type,
|
||||
Bytes: d,
|
||||
@@ -44,6 +46,7 @@ func readEncryptablePEMBlock(path string, pwd []byte) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decryptPEM(data, pwd)
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ func GetNotificationConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
case constant.SingleChatType:
|
||||
l := []string{msg.SendID, msg.RecvID}
|
||||
sort.Strings(l)
|
||||
|
||||
return "n_" + strings.Join(l, "_")
|
||||
case constant.GroupChatType:
|
||||
return "n_" + msg.GroupID
|
||||
@@ -36,6 +37,7 @@ func GetNotificationConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
case constant.NotificationChatType:
|
||||
return "n_" + msg.SendID + "_" + msg.RecvID
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -44,6 +46,7 @@ func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
case constant.SingleChatType:
|
||||
l := []string{msg.SendID, msg.RecvID}
|
||||
sort.Strings(l)
|
||||
|
||||
return "si_" + strings.Join(l, "_")
|
||||
case constant.GroupChatType:
|
||||
return "g_" + msg.GroupID
|
||||
@@ -52,6 +55,7 @@ func GetChatConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
case constant.NotificationChatType:
|
||||
return "sn_" + msg.SendID + "_" + msg.RecvID
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -60,10 +64,12 @@ func GenConversationUniqueKey(msg *sdkws.MsgData) string {
|
||||
case constant.SingleChatType, constant.NotificationChatType:
|
||||
l := []string{msg.SendID, msg.RecvID}
|
||||
sort.Strings(l)
|
||||
|
||||
return strings.Join(l, "_")
|
||||
case constant.SuperGroupChatType:
|
||||
return msg.GroupID
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -76,23 +82,28 @@ func GetConversationIDByMsg(msg *sdkws.MsgData) string {
|
||||
if !options.IsNotNotification() {
|
||||
return "n_" + strings.Join(l, "_")
|
||||
}
|
||||
|
||||
return "si_" + strings.Join(l, "_") // single chat
|
||||
case constant.GroupChatType:
|
||||
if !options.IsNotNotification() {
|
||||
return "n_" + msg.GroupID // group chat
|
||||
}
|
||||
|
||||
return "g_" + msg.GroupID // group chat
|
||||
case constant.SuperGroupChatType:
|
||||
if !options.IsNotNotification() {
|
||||
return "n_" + msg.GroupID // super group chat
|
||||
}
|
||||
|
||||
return "sg_" + msg.GroupID // super group chat
|
||||
case constant.NotificationChatType:
|
||||
if !options.IsNotNotification() {
|
||||
return "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||
}
|
||||
|
||||
return "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -111,6 +122,7 @@ func GetConversationIDBySessionType(sessionType int, ids ...string) string {
|
||||
case constant.NotificationChatType:
|
||||
return "sn_" + ids[0] // server notification chat
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -118,10 +130,11 @@ func GetNotificationConversationIDByConversationID(conversationID string) string
|
||||
l := strings.Split(conversationID, "_")
|
||||
if len(l) > 1 {
|
||||
l[0] = "n"
|
||||
|
||||
return strings.Join(l, "_")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func GetNotificationConversationID(sessionType int, ids ...string) string {
|
||||
@@ -135,6 +148,7 @@ func GetNotificationConversationID(sessionType int, ids ...string) string {
|
||||
case constant.SuperGroupChatType:
|
||||
return "n_" + ids[0] // super group chat
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -155,18 +169,22 @@ func ParseConversationID(msg *sdkws.MsgData) (isNotification bool, conversationI
|
||||
if !options.IsNotNotification() {
|
||||
return true, "n_" + strings.Join(l, "_")
|
||||
}
|
||||
|
||||
return false, "si_" + strings.Join(l, "_") // single chat
|
||||
case constant.SuperGroupChatType:
|
||||
if !options.IsNotNotification() {
|
||||
return true, "n_" + msg.GroupID // super group chat
|
||||
}
|
||||
|
||||
return false, "sg_" + msg.GroupID // super group chat
|
||||
case constant.NotificationChatType:
|
||||
if !options.IsNotNotification() {
|
||||
return true, "n_" + msg.SendID + "_" + msg.RecvID // super group chat
|
||||
}
|
||||
|
||||
return false, "sn_" + msg.SendID + "_" + msg.RecvID // server notification chat
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
@@ -189,6 +207,7 @@ func Pb2String(pb proto.Message) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(s), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,14 @@ func NewOptions(opts ...OptionsOpt) Options {
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
func NewMsgOptions() Options {
|
||||
options := make(map[string]bool, 11)
|
||||
options[constant.IsOfflinePush] = false
|
||||
|
||||
return make(map[string]bool)
|
||||
}
|
||||
|
||||
@@ -51,6 +53,7 @@ func WithOptions(options Options, opts ...OptionsOpt) Options {
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
@@ -131,6 +134,7 @@ func (o Options) Is(notification string) bool {
|
||||
if !ok || v {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry) *Auth {
|
||||
panic(err)
|
||||
}
|
||||
client := auth.NewAuthClient(conn)
|
||||
|
||||
return &Auth{discov: discov, conn: conn, Client: client}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,23 +59,32 @@ func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Cont
|
||||
return conversation.GetConversation().RecvMsgOpt, err
|
||||
}
|
||||
|
||||
func (c *ConversationRpcClient) SingleChatFirstCreateConversation(ctx context.Context, recvID, sendID string) error {
|
||||
_, err := c.Client.CreateSingleChatConversations(ctx, &pbconversation.CreateSingleChatConversationsReq{RecvID: recvID, SendID: sendID})
|
||||
func (c *ConversationRpcClient) SingleChatFirstCreateConversation(ctx context.Context, recvID, sendID,
|
||||
conversationID string, conversationType int32,
|
||||
) error {
|
||||
_, err := c.Client.CreateSingleChatConversations(ctx,
|
||||
&pbconversation.CreateSingleChatConversationsReq{
|
||||
RecvID: recvID, SendID: sendID, ConversationID: conversationID,
|
||||
ConversationType: conversationType,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ConversationRpcClient) GroupChatFirstCreateConversation(ctx context.Context, groupID string, userIDs []string) error {
|
||||
_, err := c.Client.CreateGroupChatConversations(ctx, &pbconversation.CreateGroupChatConversationsReq{UserIDs: userIDs, GroupID: groupID})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ConversationRpcClient) SetConversationMaxSeq(ctx context.Context, ownerUserIDs []string, conversationID string, maxSeq int64) error {
|
||||
_, err := c.Client.SetConversationMaxSeq(ctx, &pbconversation.SetConversationMaxSeqReq{OwnerUserID: ownerUserIDs, ConversationID: conversationID, MaxSeq: maxSeq})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *ConversationRpcClient) SetConversations(ctx context.Context, userIDs []string, conversation *pbconversation.ConversationReq) error {
|
||||
_, err := c.Client.SetConversations(ctx, &pbconversation.SetConversationsReq{UserIDs: userIDs, Conversation: conversation})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -84,6 +93,7 @@ func (c *ConversationRpcClient) GetConversationIDs(ctx context.Context, ownerUse
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.ConversationIDs, nil
|
||||
}
|
||||
|
||||
@@ -92,6 +102,7 @@ func (c *ConversationRpcClient) GetConversation(ctx context.Context, ownerUserID
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Conversation, nil
|
||||
}
|
||||
|
||||
@@ -106,6 +117,7 @@ func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Con
|
||||
if len(resp.Conversations) == 0 {
|
||||
return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("conversationIDs: %v not found", conversationIDs))
|
||||
}
|
||||
|
||||
return resp.Conversations, nil
|
||||
}
|
||||
|
||||
@@ -124,5 +136,6 @@ func (c *ConversationRpcClient) GetConversations(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Conversations, nil
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ func NewFriend(discov discoveryregistry.SvcDiscoveryRegistry) *Friend {
|
||||
panic(err)
|
||||
}
|
||||
client := friend.NewFriendClient(conn)
|
||||
|
||||
return &Friend{discov: discov, conn: conn, Client: client}
|
||||
}
|
||||
|
||||
@@ -59,6 +60,7 @@ func (f *FriendRpcClient) GetFriendsInfo(
|
||||
return nil, err
|
||||
}
|
||||
resp = r.FriendsInfo[0]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -68,6 +70,7 @@ func (f *FriendRpcClient) IsFriend(ctx context.Context, possibleFriendUserID, us
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return resp.InUser1Friends, nil
|
||||
}
|
||||
|
||||
@@ -77,6 +80,7 @@ func (f *FriendRpcClient) GetFriendIDs(ctx context.Context, ownerUserID string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.FriendIDs, nil
|
||||
}
|
||||
|
||||
@@ -85,5 +89,6 @@ func (b *FriendRpcClient) IsBlocked(ctx context.Context, possibleBlackUserID, us
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return r.InUser2Blacks, nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ func NewGroup(discov discoveryregistry.SvcDiscoveryRegistry) *Group {
|
||||
panic(err)
|
||||
}
|
||||
client := group.NewGroupClient(conn)
|
||||
|
||||
return &Group{discov: discov, conn: conn, Client: client}
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ func (g *GroupRpcClient) GetGroupInfos(
|
||||
return nil, errs.ErrGroupIDNotFound.Wrap(strings.Join(ids, ","))
|
||||
}
|
||||
}
|
||||
|
||||
return resp.GroupInfos, nil
|
||||
}
|
||||
|
||||
@@ -77,6 +79,7 @@ func (g *GroupRpcClient) GetGroupInfo(ctx context.Context, groupID string) (*sdk
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return groups[0], nil
|
||||
}
|
||||
|
||||
@@ -89,6 +92,7 @@ func (g *GroupRpcClient) GetGroupInfoMap(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return utils.SliceToMap(groups, func(e *sdkws.GroupInfo) string {
|
||||
return e.GroupID
|
||||
}), nil
|
||||
@@ -114,6 +118,7 @@ func (g *GroupRpcClient) GetGroupMemberInfos(
|
||||
return nil, errs.ErrNotInGroupYet.Wrap(strings.Join(ids, ","))
|
||||
}
|
||||
}
|
||||
|
||||
return resp.Members, nil
|
||||
}
|
||||
|
||||
@@ -126,6 +131,7 @@ func (g *GroupRpcClient) GetGroupMemberInfo(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return members[0], nil
|
||||
}
|
||||
|
||||
@@ -139,6 +145,7 @@ func (g *GroupRpcClient) GetGroupMemberInfoMap(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return utils.SliceToMap(members, func(e *sdkws.GroupMemberFullInfo) string {
|
||||
return e.UserID
|
||||
}), nil
|
||||
@@ -155,6 +162,7 @@ func (g *GroupRpcClient) GetOwnerAndAdminInfos(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Members, nil
|
||||
}
|
||||
|
||||
@@ -163,6 +171,7 @@ func (g *GroupRpcClient) GetOwnerInfo(ctx context.Context, groupID string) (*sdk
|
||||
GroupID: groupID,
|
||||
RoleLevels: []int32{constant.GroupOwner},
|
||||
})
|
||||
|
||||
return resp.Members[0], err
|
||||
}
|
||||
|
||||
@@ -173,6 +182,7 @@ func (g *GroupRpcClient) GetGroupMemberIDs(ctx context.Context, groupID string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.UserIDs, nil
|
||||
}
|
||||
|
||||
@@ -183,6 +193,7 @@ func (g *GroupRpcClient) GetGroupInfoCache(ctx context.Context, groupID string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.GroupInfo, nil
|
||||
}
|
||||
|
||||
@@ -198,6 +209,7 @@ func (g *GroupRpcClient) GetGroupMemberCache(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Member, nil
|
||||
}
|
||||
|
||||
@@ -206,6 +218,7 @@ func (g *GroupRpcClient) DismissGroup(ctx context.Context, groupID string) error
|
||||
GroupID: groupID,
|
||||
DeleteMember: true,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -213,5 +226,6 @@ func (g *GroupRpcClient) NotificationUserInfoUpdate(ctx context.Context, userID
|
||||
_, err := g.Client.NotificationUserInfoUpdate(ctx, &group.NotificationUserInfoUpdateReq{
|
||||
UserID: userID,
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
+14
-4
@@ -136,6 +136,7 @@ func NewMessage(discov discoveryregistry.SvcDiscoveryRegistry) *Message {
|
||||
panic(err)
|
||||
}
|
||||
client := msg.NewMsgClient(conn)
|
||||
|
||||
return &Message{discov: discov, conn: conn, Client: client}
|
||||
}
|
||||
|
||||
@@ -147,16 +148,19 @@ func NewMessageRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) MessageR
|
||||
|
||||
func (m *MessageRpcClient) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
|
||||
resp, err := m.Client.SendMsg(ctx, req)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MessageRpcClient) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sdkws.GetMaxSeqResp, error) {
|
||||
resp, err := m.Client.GetMaxSeq(ctx, req)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *MessageRpcClient) PullMessageBySeqList(ctx context.Context, req *sdkws.PullMessageBySeqsReq) (*sdkws.PullMessageBySeqsResp, error) {
|
||||
resp, err := m.Client.PullMessageBySeqs(ctx, req)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
@@ -165,6 +169,7 @@ func (m *MessageRpcClient) GetConversationMaxSeq(ctx context.Context, conversati
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return resp.MaxSeq, nil
|
||||
}
|
||||
|
||||
@@ -200,6 +205,7 @@ func NewNotificationSender(opts ...NotificationSenderOptions) *NotificationSende
|
||||
for _, opt := range opts {
|
||||
opt(notificationSender)
|
||||
}
|
||||
|
||||
return notificationSender
|
||||
}
|
||||
|
||||
@@ -215,11 +221,13 @@ func WithRpcGetUserName() NotificationOptions {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, sendID, recvID string, contentType, sesstionType int32, m proto.Message, opts ...NotificationOptions) (err error) {
|
||||
func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, sendID, recvID string,
|
||||
contentType, sesstionType int32, m proto.Message, opts ...NotificationOptions) (err error) {
|
||||
n := sdkws.NotificationElem{Detail: utils.StructToJsonString(m)}
|
||||
content, err := json.Marshal(&n)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "MsgClient Notification json.Marshal failed", err, "sendID", sendID, "recvID", recvID, "contentType", contentType, "msg", m)
|
||||
log.ZError(ctx, "MsgClient Notification json.Marshal failed", err, "sendID",
|
||||
sendID, "recvID", recvID, "contentType", contentType, "msg", m)
|
||||
return err
|
||||
}
|
||||
notificationOpt := ¬ificationOpt{}
|
||||
@@ -228,8 +236,9 @@ func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, s
|
||||
}
|
||||
var req msg.SendMsgReq
|
||||
var msg sdkws.MsgData
|
||||
var userInfo *sdkws.UserInfo
|
||||
if notificationOpt.WithRpcGetUsername && s.getUserInfo != nil {
|
||||
userInfo, err := s.getUserInfo(ctx, sendID)
|
||||
userInfo, err = s.getUserInfo(ctx, sendID)
|
||||
if err != nil {
|
||||
log.ZWarn(ctx, "getUserInfo failed", err, "sendID", sendID)
|
||||
} else {
|
||||
@@ -251,7 +260,7 @@ func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, s
|
||||
msg.CreateTime = utils.GetCurrentTimestampByMill()
|
||||
msg.ClientMsgID = utils.GetMsgID(sendID)
|
||||
optionsConfig := s.contentTypeConf[contentType]
|
||||
if sesstionType == constant.SuperGroupChatType && contentType == constant.HasReadReceipt {
|
||||
if sendID == recvID && contentType == constant.HasReadReceipt {
|
||||
optionsConfig.ReliabilityLevel = constant.UnreliableNotification
|
||||
}
|
||||
options := config.GetOptionsByNotification(optionsConfig)
|
||||
@@ -267,6 +276,7 @@ func (s *NotificationSender) NotificationWithSesstionType(ctx context.Context, s
|
||||
} else {
|
||||
log.ZError(ctx, "MsgClient Notification SendMsg failed", err, "req", &req)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -41,6 +41,7 @@ func (c *ConversationNotificationSender) ConversationSetPrivateNotification(ctx
|
||||
IsPrivate: isPrivateChat,
|
||||
ConversationID: conversationID,
|
||||
}
|
||||
|
||||
return c.Notification(ctx, sendID, recvID, constant.ConversationPrivateChatNotification, tips)
|
||||
}
|
||||
|
||||
@@ -50,6 +51,7 @@ func (c *ConversationNotificationSender) ConversationChangeNotification(ctx cont
|
||||
UserID: userID,
|
||||
ConversationIDList: conversationIDs,
|
||||
}
|
||||
|
||||
return c.Notification(ctx, userID, userID, constant.ConversationChangeNotification, tips)
|
||||
}
|
||||
|
||||
@@ -65,5 +67,6 @@ func (c *ConversationNotificationSender) ConversationUnreadChangeNotification(
|
||||
HasReadSeq: hasReadSeq,
|
||||
UnreadCountTime: unreadCountTime,
|
||||
}
|
||||
|
||||
return c.Notification(ctx, userID, userID, constant.ConversationUnreadNotification, tips)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user