feat: support app update service (#2811)

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* update gomake version

* update gomake version

* fix: seq conversion bug

* fix: redis pipe exec

* fix: ImportFriends

* fix: A large number of logs keysAndValues ​​length is not even

* feat: mark read aggregate write

* feat: online status supports redis cluster

* feat: online status supports redis cluster

* feat: online status supports redis cluster

* merge

* merge

* read seq is written to mongo

* read seq is written to mongo

* fix: invitation to join group notification

* fix: friend op_user_id

* feat: optimizing asynchronous context

* feat: optimizing memamq size

* feat: add GetSeqMessage

* feat: GroupApplicationAgreeMemberEnterNotification

* feat: GroupApplicationAgreeMemberEnterNotification

* feat: go.mod

* feat: go.mod

* feat: join group notification and get seq

* feat: join group notification and get seq

* feat: avoid pulling messages from sessions with a large number of max seq values of 0

* feat: API supports gzip

* go.mod

* fix: nil pointer error on close

* fix: listen error

* fix: listen error

* update go.mod

* feat: add log

* fix: token parse token value

* fix: GetMsgBySeqs boundary issues

* fix: sn_ not sort

* fix: sn_ not sort

* fix: sn_ not sort

* fix: jssdk add

* fix: jssdk support

* fix: jssdk support

* fix: jssdk support

* fix: the message I sent is not set to read seq in mongodb

* fix: cannot modify group member avatars

* fix: MemberEnterNotification

* fix: MemberEnterNotification

* fix: MsgData status

* feat: add ApplicationVersion

* feat: add ApplicationVersion

* feat: add ApplicationVersion

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
pull/2815/head
chao 2 months ago committed by GitHub
parent b85e36e97c
commit ea477fd91f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -12,7 +12,7 @@ require (
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/protocol v0.0.72-alpha.47 github.com/openimsdk/protocol v0.0.72-alpha.48
github.com/openimsdk/tools v0.0.50-alpha.16 github.com/openimsdk/tools v0.0.50-alpha.16
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0 github.com/prometheus/client_golang v1.18.0

@ -319,8 +319,8 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y= github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI= github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.72-alpha.47 h1:FGHnEwsA05GxT3vnz7YH3fbVkuoO3P71ZZgkQQ71MjA= github.com/openimsdk/protocol v0.0.72-alpha.48 h1:DVeT8Kej6OjB9bsxQ0q6FU160anwfPuVmAL/1J6VzqM=
github.com/openimsdk/protocol v0.0.72-alpha.47/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8= github.com/openimsdk/protocol v0.0.72-alpha.48/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/tools v0.0.50-alpha.16 h1:bC1AQvJMuOHtZm8LZRvN8L5mH1Ws2VYdL+TLTs1iGSc= github.com/openimsdk/tools v0.0.50-alpha.16 h1:bC1AQvJMuOHtZm8LZRvN8L5mH1Ws2VYdL+TLTs1iGSc=
github.com/openimsdk/tools v0.0.50-alpha.16/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4= github.com/openimsdk/tools v0.0.50-alpha.16/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=

@ -31,21 +31,38 @@ func (t *thirdServer) db2pbApplication(val *model.Application) *third.Applicatio
Text: val.Text, Text: val.Text,
Force: val.Force, Force: val.Force,
Latest: val.Latest, Latest: val.Latest,
Hot: val.Hot,
CreateTime: val.CreateTime.UnixMilli(), CreateTime: val.CreateTime.UnixMilli(),
} }
} }
func (t *thirdServer) LatestApplicationVersion(ctx context.Context, req *third.LatestApplicationVersionReq) (*third.LatestApplicationVersionResp, error) { func (t *thirdServer) getLatestApplicationVersion(ctx context.Context, platform string, hot bool) (*third.ApplicationVersion, error) {
res, err := t.applicationDatabase.LatestVersion(ctx, req.Platform) res, err := t.applicationDatabase.LatestVersion(ctx, platform, hot)
if err == nil { if err == nil {
return &third.LatestApplicationVersionResp{Version: t.db2pbApplication(res)}, nil return t.db2pbApplication(res), nil
} else if IsNotFound(err) { } else if IsNotFound(err) {
return &third.LatestApplicationVersionResp{}, nil return nil, nil
} else { } else {
return nil, err return nil, err
} }
} }
func (t *thirdServer) LatestApplicationVersion(ctx context.Context, req *third.LatestApplicationVersionReq) (*third.LatestApplicationVersionResp, error) {
var (
resp third.LatestApplicationVersionResp
err error
)
resp.Version, err = t.getLatestApplicationVersion(ctx, req.Platform, false)
if err != nil {
return nil, err
}
resp.Hot, err = t.getLatestApplicationVersion(ctx, req.Platform, true)
if err != nil {
return nil, err
}
return &resp, nil
}
func (t *thirdServer) AddApplicationVersion(ctx context.Context, req *third.AddApplicationVersionReq) (*third.AddApplicationVersionResp, error) { func (t *thirdServer) AddApplicationVersion(ctx context.Context, req *third.AddApplicationVersionReq) (*third.AddApplicationVersionResp, error) {
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil { if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
return nil, err return nil, err
@ -58,6 +75,7 @@ func (t *thirdServer) AddApplicationVersion(ctx context.Context, req *third.AddA
Text: req.Text, Text: req.Text,
Force: req.Force, Force: req.Force,
Latest: req.Latest, Latest: req.Latest,
Hot: req.Hot,
CreateTime: time.Now(), CreateTime: time.Now(),
} }
if err := t.applicationDatabase.AddVersion(ctx, val); err != nil { if err := t.applicationDatabase.AddVersion(ctx, val); err != nil {
@ -81,6 +99,7 @@ func (t *thirdServer) UpdateApplicationVersion(ctx context.Context, req *third.U
putUpdate(update, "text", req.Text) putUpdate(update, "text", req.Text)
putUpdate(update, "force", req.Force) putUpdate(update, "force", req.Force)
putUpdate(update, "latest", req.Latest) putUpdate(update, "latest", req.Latest)
putUpdate(update, "hot", req.Hot)
if err := t.applicationDatabase.UpdateVersion(ctx, oid, update); err != nil { if err := t.applicationDatabase.UpdateVersion(ctx, oid, update); err != nil {
return nil, err return nil, err
} }

@ -6,6 +6,6 @@ import (
) )
type ApplicationCache interface { type ApplicationCache interface {
LatestVersion(ctx context.Context, platform string) (*model.Application, error) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
DeleteCache(ctx context.Context, platforms []string) error DeleteCache(ctx context.Context, platforms []string) error
} }

@ -4,6 +4,12 @@ const (
ApplicationLatestVersion = "APPLICATION_LATEST_VERSION:" ApplicationLatestVersion = "APPLICATION_LATEST_VERSION:"
) )
func GetApplicationLatestVersionKey(platform string) string { func GetApplicationLatestVersionKey(platform string, hot bool) string {
return ApplicationLatestVersion + platform var hotStr string
if hot {
hotStr = "1:"
} else {
hotStr = "0:"
}
return ApplicationLatestVersion + hotStr + platform
} }

@ -6,7 +6,6 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/tools/utils/datautil"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
"time" "time"
) )
@ -27,9 +26,9 @@ type ApplicationRedisCache struct {
expireTime time.Duration expireTime time.Duration
} }
func (a *ApplicationRedisCache) LatestVersion(ctx context.Context, platform string) (*model.Application, error) { func (a *ApplicationRedisCache) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
return getCache(ctx, a.rcClient, cachekey.GetApplicationLatestVersionKey(platform), a.expireTime, func(ctx context.Context) (*model.Application, error) { return getCache(ctx, a.rcClient, cachekey.GetApplicationLatestVersionKey(platform, hot), a.expireTime, func(ctx context.Context) (*model.Application, error) {
return a.db.LatestVersion(ctx, platform) return a.db.LatestVersion(ctx, platform, hot)
}) })
} }
@ -37,7 +36,9 @@ func (a *ApplicationRedisCache) DeleteCache(ctx context.Context, platforms []str
if len(platforms) == 0 { if len(platforms) == 0 {
return nil return nil
} }
return a.deleter.ExecDelWithKeys(ctx, datautil.Slice(platforms, func(platform string) string { keys := make([]string, 0, len(platforms)*2)
return cachekey.GetApplicationLatestVersionKey(platform) for _, platform := range platforms {
})) keys = append(keys, cachekey.GetApplicationLatestVersionKey(platform, true), cachekey.GetApplicationLatestVersionKey(platform, false))
}
return a.deleter.ExecDelWithKeys(ctx, keys)
} }

@ -10,7 +10,7 @@ import (
) )
type ApplicationDatabase interface { type ApplicationDatabase interface {
LatestVersion(ctx context.Context, platform string) (*model.Application, error) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
AddVersion(ctx context.Context, val *model.Application) error AddVersion(ctx context.Context, val *model.Application) error
UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error
DeleteVersion(ctx context.Context, id []primitive.ObjectID) error DeleteVersion(ctx context.Context, id []primitive.ObjectID) error
@ -26,8 +26,8 @@ type applicationDatabase struct {
cache cache.ApplicationCache cache cache.ApplicationCache
} }
func (a *applicationDatabase) LatestVersion(ctx context.Context, platform string) (*model.Application, error) { func (a *applicationDatabase) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
return a.cache.LatestVersion(ctx, platform) return a.cache.LatestVersion(ctx, platform, hot)
} }
func (a *applicationDatabase) AddVersion(ctx context.Context, val *model.Application) error { func (a *applicationDatabase) AddVersion(ctx context.Context, val *model.Application) error {

@ -8,7 +8,7 @@ import (
) )
type Application interface { type Application interface {
LatestVersion(ctx context.Context, platform string) (*model.Application, error) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
AddVersion(ctx context.Context, val *model.Application) error AddVersion(ctx context.Context, val *model.Application) error
UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error
DeleteVersion(ctx context.Context, id []primitive.ObjectID) error DeleteVersion(ctx context.Context, id []primitive.ObjectID) error

@ -18,6 +18,7 @@ func NewApplicationMgo(db *mongo.Database) (*ApplicationMgo, error) {
Keys: bson.D{ Keys: bson.D{
{Key: "platform", Value: 1}, {Key: "platform", Value: 1},
{Key: "version", Value: 1}, {Key: "version", Value: 1},
{Key: "hot", Value: 1},
}, },
Options: options.Index().SetUnique(true), Options: options.Index().SetUnique(true),
}, },
@ -41,8 +42,8 @@ func (a *ApplicationMgo) sort() any {
return bson.D{{"latest", -1}, {"_id", -1}} return bson.D{{"latest", -1}, {"_id", -1}}
} }
func (a *ApplicationMgo) LatestVersion(ctx context.Context, platform string) (*model.Application, error) { func (a *ApplicationMgo) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
return mongoutil.FindOne[*model.Application](ctx, a.coll, bson.M{"platform": platform}, options.FindOne().SetSort(a.sort())) return mongoutil.FindOne[*model.Application](ctx, a.coll, bson.M{"platform": platform, "hot": hot}, options.FindOne().SetSort(a.sort()))
} }
func (a *ApplicationMgo) AddVersion(ctx context.Context, val *model.Application) error { func (a *ApplicationMgo) AddVersion(ctx context.Context, val *model.Application) error {

@ -8,6 +8,7 @@ import (
type Application struct { type Application struct {
ID primitive.ObjectID `bson:"_id"` ID primitive.ObjectID `bson:"_id"`
Platform string `bson:"platform"` Platform string `bson:"platform"`
Hot bool `bson:"hot"`
Version string `bson:"version"` Version string `bson:"version"`
Url string `bson:"url"` Url string `bson:"url"`
Text string `bson:"text"` Text string `bson:"text"`

Loading…
Cancel
Save