Compare commits

...

36 Commits

Author SHA1 Message Date
Xinwei Xiong 71f62080f3 feat: Remove Go Typecheck Tools Implement GitHub Actions Based Typecheck for OpenIM (#2140)
* feat: remove go typecheck tools

* feat: add actions go  typecheck tools

* Update verify-typecheck.sh
2024-03-25 04:27:40 +00:00
Xinwei Xiong f6ab243d2f Update bot-cherry-pick.yml (#2132) 2024-03-20 02:32:41 +00:00
OpenIM Bot 8788515576 cicd: bump League Patch (#2130) 2024-03-20 02:32:00 +00:00
Xinwei Xiong f52a4fe7e5 feat: set git cherry pick and Milestone (#2131) 2024-03-20 02:20:23 +00:00
Xinwei Xiong c50b787c58 Update env-template.yaml (#2128) 2024-03-20 01:25:11 +00:00
skiffer-git 0274d516e0 The check script is not compatible with Mac. (#2119)
* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2054)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug delete data conversion (#2060)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2053)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2056)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* delete data conversion tool

* delete data conversion tool

* delete data conversion tool

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Fix bug redis address (#2062)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2053)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2056)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Fix bug delete data conversion (#2059)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2054)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* delete data conversion tool

* delete data conversion tool

* delete data conversion tool

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* redis address port error

* change go proxy

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Fix bug docker start log (#2066)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* Bug: component check  (#2053)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>

* Bug: component check  (#2056)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Fix bug delete data conversion (#2059)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2054)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* delete data conversion tool

* delete data conversion tool

* delete data conversion tool

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Fix bug redis address (#2063)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* redis address port error

* change go proxy

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* Run in the background

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* optimization: message remove options.

* fix: getConversationInfo

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

* scripts for Mac

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
Co-authored-by: Gordon <1432970085@qq.com>
Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com>
2024-03-19 11:46:10 +00:00
Yibiao He 6d1062bef8 fix: Fix the callback after reading the group message (#2114) 2024-03-19 09:40:30 +00:00
OpenIM Bot c69522b878 cicd: bump League Patch (#2117) 2024-03-19 06:23:50 +00:00
chao 8f218057e4 fix: conversation crash caused by non-existence (#2087)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
2024-03-18 02:49:36 +00:00
Xinwei Xiong 4ed575a53c fix: fix group getGroupMemberIDs is 0 err (#2108) 2024-03-18 02:35:19 +00:00
Xinwei Xiong 4cd42d7e19 fix: create time sort (#2090) 2024-03-18 02:35:00 +00:00
Xinwei Xiong 7c25c91e9b feat: golang fix apt test design (#2084)
* feat: make lint format

* feat: make lint format

* feat: make lint format

* fix: fix make lint

* feat: add scripts verify shell check

* feat: add scripts verify shell check
2024-03-18 02:34:48 +00:00
Xinwei Xiong b67c6bacd0 docs: Update openim version management strategy, detailed design (#2076)
* Update version.md

* Update version.md
2024-03-18 02:34:19 +00:00
Xinwei Xiong 1c2eafce25 add github actions is create code-language-detector.yml (#2113)
* feat: remove tools/codescan catalog

* feat: add code language detector github actions
2024-03-18 02:33:29 +00:00
Xinwei Xiong e795dce696 cicd: update e2e-test fix e2e and api test ci (#2101) 2024-03-18 02:17:21 +00:00
OpenIM Bot 2d2fa99d2c cicd: bump League Patch (#2105) 2024-03-14 02:17:22 +00:00
OpenIM-Gordon e86d1cd742 optimization: message remove options. (#2082)
* fix: remove unnecessary error handling to avoid sending failed notifications.

* fix: remove unnecessary error handling to avoid sending nil resp.

* optimization: message remove options.
2024-03-13 05:42:00 +00:00
Brabem 8501c66d14 fix: fix the protocol version (#2074) 2024-03-13 02:13:15 +00:00
Xinwei Xiong cd7f35452e fix: fix docker file images proxy (#2071)
* fix: fix docker file images proxy

* fix: fix docker file images proxy

* docs: optimize openim go code and logging docs
2024-03-11 07:54:33 +00:00
Xinwei Xiong 5454c512e0 fix: fix docker file images proxy (#2069)
* fix: fix docker file images proxy

* fix: fix docker file images proxy
2024-03-10 05:34:08 +00:00
Xinwei Xiong 3a1615795e feat: add scripts verify shell check (#2068) 2024-03-10 05:03:27 +00:00
OpenIM Bot c12f9dca7c cicd: bump League Patch (#2057) 2024-03-10 02:24:20 +00:00
skiffer-git 572b5acc26 Run in the background (#2065) 2024-03-09 15:25:31 +08:00
skiffer-git 148a2493bb Fix bug redis address (#2063)
* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* redis address port error

* change go proxy

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
2024-03-09 13:52:07 +08:00
skiffer-git 500ebc356d Fix bug delete data conversion (#2059)
* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* Bug: component check  (#2054)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* Delete Data Conversion Tool

* delete data conversion tool

* delete data conversion tool

* delete data conversion tool

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
2024-03-09 12:56:54 +08:00
skiffer-git fdaad704e0 Bug: component check (#2056)
* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

* Exit with code 1 when the check script fails (#2023)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2027)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status. (#2031)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* cicd: bump League Patch (#2025)

* Execute after the component check succeeds   && minio.Enable is not configured to use MinIO (#2026)

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* Log redirection causes incorrect program exit status.

---------

Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* Fix bug Remove duplicate function definitions (#2034)

* Exit with code 1 when the check script fails (#2022)

* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails

* delete

* delete log

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2045)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Feature: delete log for update images  (#2050)

* Error not handled (#2040)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* feat: add local cache for high frequency reads (#2036)

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* Fix bug Remove duplicate function definitions (#2033)

* delete

* delete log

* Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)

* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* delete log (#2047)

* delete log

---------

Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
Co-authored-by: withchao <993506633@qq.com>
Co-authored-by: chao <48119764+withchao@users.noreply.github.com>
Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: OpenIM Bot <124379614+kubbot@users.noreply.github.com>
2024-03-09 00:41:54 +08:00
skiffer-git 8d21225107 Bug: component check (#2053)
* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr

* test

Signed-off-by: unknown <44203734@qq.com>

* fix bug: component check

* fix bug: component check

* fix bug: component check

* fix bug: component check

---------

Signed-off-by: unknown <44203734@qq.com>
2024-03-08 23:19:47 +08:00
skiffer-git fabcb5317f delete log (#2047) 2024-03-08 20:19:33 +08:00
skiffer-git 2acdfde56e Fix bug configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr (#2044)
* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled

* configGetEnv failed,err:string to int failed: strconv.Atoi: parsing "openim_v3": invalid syntaxr
2024-03-08 17:21:50 +08:00
skiffer-git 057884311a Fix bug Remove duplicate function definitions (#2033)
* delete

* delete log
2024-03-08 17:09:19 +08:00
chao b9cf40034c feat: add local cache for high frequency reads (#2036)
* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* feat: msg local cache

* fix: mongo

* fix: mongo

* fix: mongo

* openim.yaml

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* localcache

* local cache

* local cache

* local cache

* local cache

* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: cache add single-flight and timing-wheel.

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* feat: msg rpc local cache

* refactor: refactor the code of push and optimization.

* cicd: robot automated Change

* refactor: rename cache.

* merge

* fix: refactor project dir avoid import cycle.

* update tools

* merge

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* feat: conversation FindRecvMsgNotNotifyUserIDs

* merge

* merge the latest main

---------

Co-authored-by: Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
2024-03-08 16:30:47 +08:00
skiffer-git 291443dd6b Error not handled (#2040)
* delete

* add context deadline exceeded

* Error not handled

* Error not handled

* Error not handled

* Error not handled
2024-03-08 16:29:26 +08:00
skiffer-git 16799648dc del log (#2030) 2024-03-08 14:06:27 +08:00
skiffer-git 42482e7eb4 Execute after the component check succeeds && minio.Enable is not configured to use MinIO (#2026)
* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Exit with code 1 when the check script fails

* Handle the return value of pre-start

* Handle the return value of pre-start

* Handle the return value of pre-start

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked

* minio.Enable is not configured to use MinIO, therefore the image server is not checked
2024-03-08 12:19:04 +08:00
OpenIM Bot a93615d3e0 cicd: bump League Patch (#2025) 2024-03-08 02:28:48 +00:00
skiffer-git a1f0eb2e3e Exit with code 1 when the check script fails (#2022)
* Optimize script logs

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Optimizing Docker Log Output Detection

* Exit with code 1 when the check script fails
2024-03-08 08:56:22 +08:00
191 changed files with 3124 additions and 16543 deletions
+1 -1
View File
@@ -25,6 +25,7 @@ jobs:
- name: Comment cherry-pick command - name: Comment cherry-pick command
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
script: | script: |
const pr = context.payload.pull_request; const pr = context.payload.pull_request;
if (!pr.merged) { if (!pr.merged) {
@@ -64,4 +65,3 @@ jobs:
issue_number: pr.number, issue_number: pr.number,
body: cherryPickCmd body: cherryPickCmd
}); });
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
+37 -3
View File
@@ -12,23 +12,57 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
name: Github Rebot for Cherry Pick On Comment name: Github Robot for Cherry Pick On Comment
on: on:
issue_comment: issue_comment:
types: [created] types: [created]
jobs: jobs:
cherry-pick: cherry-pick:
name: Cherry Pick name: Cherry Pick
# && github.event.comment.user.login=='kubbot'
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/cherry-pick') if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/cherry-pick')
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the latest code - name: Checkout the latest code
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
token: ${{ secrets.BOT_GITHUB_TOKEN }} token: ${{ secrets.BOT_GITHUB_TOKEN }}
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo fetch-depth: 0 # To ensure all history is available for cherry-picking
- name: Automatic Cherry Pick - name: Automatic Cherry Pick
uses: vendoo/gha-cherry-pick@v1 uses: vendoo/gha-cherry-pick@v1
with:
# Assuming the cherry-pick commit SHA is passed in the comment like '/cherry-pick sha'
commit-sha: ${{ github.event.comment.body }}
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
- name: Create a new branch for PR
run: |
PR_BRANCH="cherry-pick-${GITHUB_SHA}-to-${{ github.base_ref }}"
git checkout -b $PR_BRANCH
git push origin $PR_BRANCH
env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
- name: Create Pull Request
uses: actions/github-script@v5
with:
script: |
const prTitle = "Cherry-pick to ${{ github.base_ref }}"
const prBody = "Automated cherry-pick of ${{ github.event.comment.body }}\n\n/cc @kubbot"
const base = "${{ github.base_ref }}"
const head = "cherry-pick-${{ github.sha }}-to-${{ github.base_ref }}"
const createPr = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: prTitle,
body: prBody,
head: head,
base: base,
maintainer_can_modify: true, // Allows maintainers to edit the PR
})
env: env:
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
@@ -0,0 +1,27 @@
# Copyright © 2024 OpenIM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Language Check Workflow Test
on: [pull_request]
jobs:
comment-language-detector:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Code Language Detector
uses: kubecub/comment-lang-detector@v1.0.0
+8 -6
View File
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
name: OpenIM Linux System E2E Test name: OpenIM E2E And API Test
on: on:
workflow_dispatch: workflow_dispatch:
@@ -82,7 +82,7 @@ jobs:
sudo make tidy sudo make tidy
sudo make tools.verify.go-gitlint sudo make tools.verify.go-gitlint
- name: Build, Start - name: Build, Start(make build && make start)
run: | run: |
sudo ./scripts/install/install.sh -i sudo ./scripts/install/install.sh -i
@@ -90,9 +90,8 @@ jobs:
run: | run: |
sudo ./scripts/install/install.sh -s sudo ./scripts/install/install.sh -s
- name: Exec OpenIM API test - name: Exec OpenIM API test (make test-api)
run: | run: |
sudo make test-api
mkdir -p ./tmp mkdir -p ./tmp
touch ./tmp/test.md touch ./tmp/test.md
echo "# OpenIM Test" >> ./tmp/test.md echo "# OpenIM Test" >> ./tmp/test.md
@@ -103,9 +102,10 @@ jobs:
echo "</code></pre>" >> ./tmp/test.md echo "</code></pre>" >> ./tmp/test.md
echo "</details>" >> ./tmp/test.md echo "</details>" >> ./tmp/test.md
- name: Exec OpenIM E2E Test sudo make test-api
- name: Exec OpenIM E2E Test (make test-e2e)
run: | run: |
sudo make test-e2e
echo "" >> ./tmp/test.md echo "" >> ./tmp/test.md
echo "## OpenIM E2E Test" >> ./tmp/test.md echo "## OpenIM E2E Test" >> ./tmp/test.md
echo "<details><summary>Command Output for OpenIM E2E Test</summary>" >> ./tmp/test.md echo "<details><summary>Command Output for OpenIM E2E Test</summary>" >> ./tmp/test.md
@@ -114,6 +114,8 @@ jobs:
echo "</code></pre>" >> ./tmp/test.md echo "</code></pre>" >> ./tmp/test.md
echo "</details>" >> ./tmp/test.md echo "</details>" >> ./tmp/test.md
sudo make test-e2e
- name: Comment PR with file - name: Comment PR with file
uses: thollander/actions-comment-pull-request@v2 uses: thollander/actions-comment-pull-request@v2
with: with:
+4 -2
View File
@@ -41,6 +41,7 @@ jobs:
steps: steps:
- uses: actions/github-script@v7 # v6 - uses: actions/github-script@v7 # v6
with: with:
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
script: | script: |
if (!context.payload.pull_request.merged) { if (!context.payload.pull_request.merged) {
console.log('PR was not merged, skipping.'); console.log('PR was not merged, skipping.');
@@ -56,9 +57,10 @@ jobs:
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
state: 'open', state: 'open',
sort: 'due_on', sort: 'title',
direction: 'asc' direction: 'desc'
}) })
if (milestones.data.length === 0) { if (milestones.data.length === 0) {
console.log('There are no milestones, skipping.'); console.log('There are no milestones, skipping.');
return; return;
+3
View File
@@ -70,6 +70,9 @@ jobs:
version: '3.x' # If available, use the latest major version that's compatible version: '3.x' # If available, use the latest major version that's compatible
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Code Typecheck Detector
uses: kubecub/typecheck@main
- name: Module Operations - name: Module Operations
run: | run: |
sudo make tidy sudo make tidy
+1 -1
View File
@@ -745,7 +745,7 @@ linters:
- misspell # Spelling mistakes - misspell # Spelling mistakes
- staticcheck # Static analysis - staticcheck # Static analysis
- unused # Checks for unused code - unused # Checks for unused code
- goimports # Checks if imports are correctly sorted and formatted # - goimports # Checks if imports are correctly sorted and formatted
- godot # Checks for comment punctuation - godot # Checks for comment punctuation
- bodyclose # Ensures HTTP response body is closed - bodyclose # Ensures HTTP response body is closed
- stylecheck # Style checker for Go code - stylecheck # Style checker for Go code
+20
View File
@@ -0,0 +1,20 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.6.0"></a>
## v3.6.0 - 2024-03-07
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
### Pull Requests
- Merge branch 'tuoyun'
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v3.6.0...HEAD
+2 -3
View File
@@ -3,15 +3,14 @@ FROM golang:1.20 AS builder
# Set go mod installation source and proxy # Set go mod installation source and proxy
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
ENV GO111MODULE=$GO111MODULE ENV GO111MODULE=$GO111MODULE
ENV GOPROXY=$GOPROXY ENV GOPROXY=$GOPROXY
# Set up the working directory # Set up the working directory
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
COPY go.mod go.sum ./
RUN go mod download
# Copy all files to the container # Copy all files to the container
ADD . . ADD . .
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1 -1
View File
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
@@ -19,7 +19,7 @@
FROM golang:1.20 AS builder FROM golang:1.20 AS builder
ARG GO111MODULE=on ARG GO111MODULE=on
ARG GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://goproxy.io,direct
WORKDIR /openim/openim-server WORKDIR /openim/openim-server
+1
View File
@@ -118,6 +118,7 @@ MONGO_OPENIM_PASSWORD=openIM123
# Default: MONGO_DATABASE=openim_v3 # Default: MONGO_DATABASE=openim_v3
MONGO_DATABASE=openim_v3 MONGO_DATABASE=openim_v3
MONGO_MAX_POOL_SIZE=100
# ----- Redis Configuration ----- # ----- Redis Configuration -----
# Port on which Redis in-memory data structure store is running. # Port on which Redis in-memory data structure store is running.
+36
View File
@@ -535,3 +535,39 @@ prometheus:
rtcPrometheusPort: [ ${RTC_PROM_PORT} ] rtcPrometheusPort: [ ${RTC_PROM_PORT} ]
thirdPrometheusPort: [ ${THIRD_PROM_PORT} ] thirdPrometheusPort: [ ${THIRD_PROM_PORT} ]
messageTransferPrometheusPort: [ ${MSG_TRANSFER_PROM_PORT} ] # List of ports messageTransferPrometheusPort: [ ${MSG_TRANSFER_PROM_PORT} ] # List of ports
###################### LocalCache configuration information ######################
# topic: redis subscriber channel
# slotNum: number of slots, multiple slots can prevent too many keys from competing for a lock
# slotSize: number of slots, the number of cached keys per slot, the overall cache quantity is slotNum * slotSize
# successExpire: successful cache time seconds
# failedExpire: failed cache time seconds
# disable local caching and annotate topic, slotNum, and slotSize
localCache:
user:
topic: DELETE_CACHE_USER
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
group:
topic: DELETE_CACHE_GROUP
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
friend:
topic: DELETE_CACHE_FRIEND
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
conversation:
topic: DELETE_CACHE_CONVERSATION
slotNum: 100
slotSize: 2000
successExpire: 300
failedExpire: 5
+2 -1
View File
@@ -118,6 +118,7 @@ MONGO_OPENIM_PASSWORD=${MONGO_OPENIM_PASSWORD}
# Default: MONGO_DATABASE=openim_v3 # Default: MONGO_DATABASE=openim_v3
MONGO_DATABASE=${MONGO_DATABASE} MONGO_DATABASE=${MONGO_DATABASE}
MONGO_MAX_POOL_SIZE=${MONGO_MAX_POOL_SIZE}
# ----- Redis Configuration ----- # ----- Redis Configuration -----
# Port on which Redis in-memory data structure store is running. # Port on which Redis in-memory data structure store is running.
@@ -142,7 +143,7 @@ KAFKA_LATESTMSG_REDIS_TOPIC=${KAFKA_LATESTMSG_REDIS_TOPIC}
# MINIO_PORT # MINIO_PORT
# ---------- # ----------
# MINIO_PORT sets the port for the MinIO object storage service. # MINIO_PORT sets the port for the MinIO object storage service.
# Upon changing this port, the MinIO endpoint URLs in the `config/config.yaml` file must be updated # Upon changing this port, the MinIO endpoint URLs in the config/config.yaml file must be updated
# to reflect this change. The endpoints include both the 'endpoint' and 'signEndpoint' # to reflect this change. The endpoints include both the 'endpoint' and 'signEndpoint'
# under the MinIO configuration. # under the MinIO configuration.
# #
-17
View File
@@ -186,23 +186,6 @@ services:
# server: # server:
# ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS:-172.28.0.8} # ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS:-172.28.0.8}
### TODO: mysql is required to deploy the openim-chat component
# mysql:
# image: mysql:${MYSQL_IMAGE_VERSION:-5.7}
# platform: linux/amd64
# ports:
# - "${MYSQL_PORT:-13306}:3306"
# container_name: mysql
# volumes:
# - "${DATA_DIR:-./}/components/mysql/data:/var/lib/mysql"
# - "/etc/localtime:/etc/localtime"
# environment:
# MYSQL_ROOT_PASSWORD: "${MYSQL_PASSWORD:-openIM123}"
# restart: always
# networks:
# server:
# ipv4_address: ${MYSQL_NETWORK_ADDRESS:-172.28.0.15}
# openim-chat: # openim-chat:
# image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-main} # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-main}
# container_name: openim-chat # container_name: openim-chat
+2
View File
@@ -2,6 +2,8 @@
**PATH:** `scripts/lib/logging.sh` **PATH:** `scripts/lib/logging.sh`
### Introduction ### Introduction
OpenIM, an intricate project, requires a robust logging mechanism to diagnose issues, maintain system health, and provide insights. A custom-built logging system embedded within OpenIM ensures consistent and structured logs. Let's delve into the design of this logging system and understand its various functions and their usage scenarios. OpenIM, an intricate project, requires a robust logging mechanism to diagnose issues, maintain system health, and provide insights. A custom-built logging system embedded within OpenIM ensures consistent and structured logs. Let's delve into the design of this logging system and understand its various functions and their usage scenarios.
+276 -10
View File
@@ -266,13 +266,61 @@ errors.New("redis connection failed")
- When specifying ranges of numbers, use inclusive ranges whenever possible. - When specifying ranges of numbers, use inclusive ranges whenever possible.
- Go 1.13 or above is recommended, and the error generation method is `fmt.Errorf("module xxx: %w", err)`. - Go 1.13 or above is recommended, and the error generation method is `fmt.Errorf("module xxx: %w", err)`.
### 1.4 panic processing ### 1.4 Panic Processing
The use of `panic` should be carefully controlled in Go applications to ensure program stability and predictable error handling. Following are revised guidelines emphasizing the restriction on using `panic` and promoting alternative strategies for error handling and program termination.
- **Prohibited in Business Logic:** Using `panic` within business logic processing is strictly prohibited. Business logic should handle errors gracefully and use error returns to propagate issues up the call stack.
- **Restricted Use in Main Package:** In the main package, the use of `panic` should be reserved for situations where the program is entirely inoperable, such as failure to open essential files, inability to connect to the database, or other critical startup issues. Even in these scenarios, prefer using structured error handling to terminate the program.
- **Use `log.Fatal` for Critical Errors:** Instead of panicking, use `log.Fatal` to log critical errors that prevent the program from operating normally. This approach allows the program to terminate while ensuring the error is properly logged for troubleshooting.
- **Prohibition on Exportable Interfaces:** Exportable interfaces must not invoke `panic`. They should handle errors gracefully and return errors as part of their contract.
- **Prefer Errors Over Panic:** It is recommended to use error returns instead of panic to convey errors within a package. This approach promotes error handling that integrates smoothly with Go's error handling idioms.
#### Alternative to Panic: Structured Program Termination
To enforce these guidelines, consider implementing structured functions to terminate the program gracefully in the face of unrecoverable errors, while providing clear error messages. Here are two recommended functions:
```go
// ExitWithError logs an error message and exits the program with a non-zero status.
func ExitWithError(err error) {
progName := filepath.Base(os.Args[0])
fmt.Fprintf(os.Stderr, "%s exit -1: %+v\n", progName, err)
os.Exit(-1)
}
// SIGTERMExit logs a warning message when the program receives a SIGTERM signal and exits with status 0.
func SIGTERMExit() {
progName := filepath.Base(os.Args[0])
fmt.Fprintf(os.Stderr, "Warning %s receive process terminal SIGTERM exit 0\n", progName)
}
```
#### Example Usage:
```go
import (
_ "net/http/pprof"
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
)
func main() {
apiCmd := cmd.NewApiCmd()
apiCmd.AddPortFlag()
apiCmd.AddPrometheusPortFlag()
if err := apiCmd.Execute(); err != nil {
util.ExitWithError(err)
}
}
```
In this example, `ExitWithError` is used to terminate the program when an unrecoverable error occurs, providing a clear error message to stderr and exiting with a non-zero status. This approach ensures that critical errors are logged and the program exits in a controlled manner, facilitating troubleshooting and maintaining the stability of the application.
- Panic is prohibited in business logic processing.
- In the main package, panic is only used when the program is completely inoperable, for example, the file cannot be opened, the database cannot be connected, and the program cannot run normally.
- In the main package, use `log.Fatal` to record errors, so that the program can be terminated by the log, or the exception thrown by the panic can be recorded in the log file, which is convenient for troubleshooting.
- An exportable interface must not panic.
- It is recommended to use error instead of panic to convey errors in the package.
### 1.5 Unit Tests ### 1.5 Unit Tests
@@ -439,10 +487,15 @@ var allowGitHook bool
- Local variables should be as short as possible, for example, use buf to refer to buffer, and use i to refer to index. - Local variables should be as short as possible, for example, use buf to refer to buffer, and use i to refer to index.
- The code automatically generated by the code generation tool can exclude this rule (such as the Id in `xxx.pb.go`) - The code automatically generated by the code generation tool can exclude this rule (such as the Id in `xxx.pb.go`)
### 2.7 Constant naming ### 2.7 Constant Naming
- The constant name must follow the camel case, and the initial letter is uppercase or lowercase according to the access control decision. In Go, constants play a critical role in defining values that do not change throughout the execution of a program. Adhering to best practices in naming constants can significantly improve the readability and maintainability of your code. Here are some guidelines for constant naming:
- If it is a constant of enumeration type, you need to create the corresponding type first:
- **Camel Case Naming:** The name of a constant must follow the camel case notation. The initial letter should be uppercase or lowercase based on the access control requirements. Uppercase indicates that the constant is exported (visible outside the package), while lowercase indicates package-private visibility (visible only within its own package).
- **Enumeration Type Constants:** For constants that represent a set of enumerated values, it's recommended to define a corresponding type first. This approach not only enhances type safety but also improves code readability by clearly indicating the purpose of the enumeration.
**Example:**
```go ```go
// Code defines an error code type. // Code defines an error code type.
@@ -452,11 +505,40 @@ type Code int
const ( const (
// ErrUnknown - 0: An unknown error occurred. // ErrUnknown - 0: An unknown error occurred.
ErrUnknown Code = iota ErrUnknown Code = iota
// ErrFatal - 1: An fatal error occurred. // ErrFatal - 1: A fatal error occurred.
ErrFatal ErrFatal
) )
``` ```
In the example above, `Code` is defined as a new type based on `int`. The enumerated constants `ErrUnknown` and `ErrFatal` are then defined with explicit comments to indicate their purpose and values. This pattern is particularly useful for grouping related constants and providing additional context.
### Global Variables and Constants Across Packages
- **Use Constants for Global Variables:** When defining variables that are intended to be accessed across packages, prefer using constants to ensure immutability. This practice avoids unintended modifications to the value, which can lead to unpredictable behavior or hard-to-track bugs.
- **Lowercase for Package-Private Usage:** If a global variable or constant is intended for use only within its own package, it should start with a lowercase letter. This clearly signals its limited scope of visibility, adhering to Go's access control mechanism based on naming conventions.
**Guideline:**
- For global constants that need to be accessed across packages, declare them with an uppercase initial letter. This makes them exported, adhering to Go's visibility rules.
- For constants used within the same package, start their names with a lowercase letter to limit their scope to the package.
**Example:**
```go
package config
// MaxConnections - the maximum number of allowed connections. Visible across packages.
const MaxConnections int = 100
// minIdleTime - the minimum idle time before a connection is considered stale. Only visible within the config package.
const minIdleTime int = 30
```
In this example, `MaxConnections` is a global constant meant to be accessed across packages, hence it starts with an uppercase letter. On the other hand, `minIdleTime` is intended for use only within the `config` package, so it starts with a lowercase letter.
Following these guidelines ensures that your Go code is more readable, maintainable, and consistent with Go's design philosophy and access control mechanisms.
### 2.8 Error naming ### 2.8 Error naming
- The Error type should be written in the form of FooError. - The Error type should be written in the form of FooError.
@@ -473,6 +555,190 @@ type ExitError struct {
var ErrFormat = errors. New("unknown format") var ErrFormat = errors. New("unknown format")
``` ```
For non-standard Err naming, CICD will report an error
### 2.9 Handling Errors Properly
In Go, proper error handling is crucial for creating reliable and maintainable applications. It's important to ensure that errors are not ignored or discarded, as this can lead to unpredictable behavior and difficult-to-debug issues. Here are the guidelines and examples regarding the proper handling of errors.
#### Guideline: Do Not Discard Errors
- **Mandatory Error Propagation:** When calling a function that returns an error, the calling function must handle or propagate the error, instead of ignoring it. This approach ensures that errors are not silently ignored, allowing higher-level logic to make informed decisions about error handling.
#### Incorrect Example: Discarding an Error
```go
package main
import (
"io/ioutil"
"log"
)
func ReadFileContent(filename string) string {
content, _ := ioutil.ReadFile(filename) // Incorrect: Error is ignored
return string(content)
}
func main() {
content := ReadFileContent("example.txt")
log.Println(content)
}
```
In this incorrect example, the error returned by `ioutil.ReadFile` is ignored. This can lead to situations where the program continues execution even if the file doesn't exist or cannot be accessed, potentially causing more cryptic errors downstream.
#### Correct Example: Propagating an Error
```go
package main
import (
"io/ioutil"
"log"
)
// ReadFileContent attempts to read and return the content of the specified file.
// It returns an error if reading fails.
func ReadFileContent(filename string) (string, error) {
content, err := ioutil.ReadFile(filename)
if err != nil {
// Correct: Propagate the error
return "", err
}
return string(content), nil
}
func main() {
content, err := ReadFileContent("example.txt")
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
log.Println(content)
}
```
In the correct example, the error returned by `ioutil.ReadFile` is propagated back to the caller. The `main` function then checks the error and terminates the program with an appropriate error message if an error occurred. This approach ensures that errors are handled appropriately, and the program does not proceed with invalid state.
### Best Practices for Error Handling
1. **Always check the error returned by a function.** Do not ignore it.
2. **Propagate errors up the call stack unless they can be handled gracefully at the current level.**
3. **Provide context for errors when propagating them, making it easier to trace the source of the error.** This can be achieved using `fmt.Errorf` with the `%w` verb or dedicated wrapping functions provided by some error handling packages.
4. **Log the error at the point where it is handled or makes the program to terminate, to provide insight into the failure.**
By following these guidelines, you ensure that your Go applications handle errors in a consistent and effective manner, improving their reliability and maintainability.
### 2.10 Using Context with IO or Inter-Process Communication (IPC)
In Go, `context.Context` is a powerful construct for managing deadlines, cancellation signals, and other request-scoped values across API boundaries and between processes. It is particularly important in I/O operations or inter-process communication (IPC), where operations might need to be cancelled or timed out.
#### Guideline: Use Context for IO and IPC
- **Mandatory Use of Context:** When performing I/O operations or inter-process communication, it's crucial to use `context.Context` to manage the lifecycle of these operations. This includes setting deadlines, handling cancellation signals, and passing request-scoped values.
#### Incorrect Example: Ignoring Context in an HTTP Call
```go
package main
import (
"io/ioutil"
"net/http"
"log"
)
// FetchData makes an HTTP GET request to the specified URL and returns the response body.
// This function does not use context, making it impossible to cancel the request or set a deadline.
func FetchData(url string) (string, error) {
resp, err := http.Get(url) // Incorrect: Ignoring context
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
func main() {
data, err := FetchData("http://example.com")
if err != nil {
log.Fatalf("Failed to fetch data: %v", err)
}
log.Println(data)
}
```
In this incorrect example, the `FetchData` function makes an HTTP GET request without using a `context`. This approach does not allow the request to be cancelled or a timeout to be set, potentially leading to resources being wasted if the server takes too long to respond or if the operation needs to be aborted for any reason.
#### Correct Example: Using Context in an HTTP Call
```go
package main
import (
"context"
"io/ioutil"
"net/http"
"log"
"time"
)
// FetchDataWithContext makes an HTTP GET request to the specified URL using the provided context.
// This allows the request to be cancelled or timed out according to the context's deadline.
func FetchDataWithContext(ctx context.Context, url string) (string, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return "", err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}
func main() {
// Create a context with a 5-second timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
data, err := FetchDataWithContext(ctx, "http://example.com")
if err != nil {
log.Fatalf("Failed to fetch data: %v", err)
}
log.Println(data)
}
```
In the correct example, `FetchDataWithContext` uses a context to make the HTTP GET request. This allows the operation to be cancelled or subjected to a timeout, as dictated by the context passed to it. The `context.WithTimeout` function is used in `main` to create a context that cancels the request if it takes longer than 5 seconds, demonstrating a practical use of context to manage operation lifecycle.
### Best Practices for Using Context
1. **Pass context as the first parameter of a function**, following the convention `func(ctx context.Context, ...)`.
2. **Never ignore the context** provided to you in functions that support it. Always use it in your I/O or IPC operations.
3. **Avoid storing context in a struct**. Contexts are meant to be passed around within the call stack, not stored.
4. **Use context's cancellation and deadline features** to control the lifecycle of blocking operations, especially in network I/O and IPC scenarios.
5. **Propagate context down the call stack** to any function that supports it, ensuring that your application can respond to cancellation signals and deadlines effectively.
By adhering to these guidelines and examples, you can ensure that your Go applications handle I/O and IPC operations more reliably and efficiently, with proper support for cancellation, timeouts, and request-scoped values.
## 3. Comment specification ## 3. Comment specification
- Each exportable name must have a comment, which briefly introduces the exported variables, functions, structures, interfaces, etc. - Each exportable name must have a comment, which briefly introduces the exported variables, functions, structures, interfaces, etc.
+384 -18
View File
@@ -1,20 +1,386 @@
## Log Standards # OpenIM Logging and Error Handling Documentation
### Log Standards ## Script Logging Documentation Link
- The unified log package `github.com/openimsdk/open-im-server/internal/pkg/log` should be used for all logging; If you wish to view the script's logging documentation, you can click on this link: [Logging Documentation](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/contrib/bash-log.md).
- Use structured logging formats: `log.Infow`, `log.Warnw`, `log.Errorw`, etc. For example: `log.Infow("Update post function called")`;
- All logs should start with an uppercase letter and should not end with a `.`. For example: `log.Infow("Update post function called")`; Below is the documentation for logging and error handling in the OpenIM Go project.
- Use past tense. For example, use `Could not delete B` instead of `Cannot delete B`;
- Adhere to log level standards: To create a standard set of documentation that is quick to read and easy to understand, we will highlight key information about the `Logger` interface and the `CodeError` interface. This includes the purpose of each interface, key methods, and their use cases. This will help developers quickly grasp how to effectively use logging and error handling within the project.
- Debug level logs use `log.Debugw`;
- Info level logs use `log.Infow`; ## Logging (`Logger` Interface)
- Warning level logs use `log.Warnw`;
- Error level logs use `log.Errorw`; ### Purpose
- Panic level logs use `log.Panicw`; The `Logger` interface aims to provide the OpenIM project with a unified and flexible logging mechanism, supporting structured logging formats for efficient log management and analysis.
- Fatal level logs use `log.Fatalw`.
- Log settings: ### Key Methods
- Development and test environments: The log level is set to `debug`, the log format can be set to `console` / `json` as needed, and caller is enabled;
- Production environment: The log level is set to `info`, the log format is set to `json`, and caller is enabled. (**Note**: In the early stages of going online, to facilitate troubleshooting, the log level can be set to `debug`) - **Debug, Info, Warn, Error**
- When logging, avoid outputting sensitive information, such as passwords, keys, etc. Log messages of different levels to suit various logging needs and scenarios. These methods accept a context (`context.Context`), a message (`string`), and key-value pairs (`...interface{}`), allowing the log to carry rich context information.
- If you are calling a logging function in a function/method with a `context.Context` parameter, it is recommended to use `log.L(ctx).Infow()` for logging.
- **WithValues**
Append key-value pair information to log messages, returning a new `Logger` instance. This helps in adding consistent context information.
- **WithName**
Set the name of the logger, which helps in identifying the source of the logs.
- **WithCallDepth**
Adjust the call stack depth to accurately identify the source of the log message.
### Use Cases
- Developers should choose the appropriate logging level (such as `Debug`, `Info`, `Warn`, `Error`) based on the importance of the information when logging.
- Use `WithValues` and `WithName` to add richer context information to logs, facilitating subsequent tracking and analysis.
## Error Handling (`CodeError` Interface)
### Purpose
The `CodeError` interface is designed to provide a unified mechanism for error handling and wrapping, making error information more detailed and manageable.
### Key Methods
- **Code**
Return the error code to distinguish between different types of errors.
- **Msg**
Return the error message description to display to the user.
- **Detail**
Return detailed information about the error for further debugging by developers.
- **WithDetail**
Add detailed information to the error, returning a new `CodeError` instance.
- **Is**
Determine whether the current error matches a specified error, supporting a flexible error comparison mechanism.
- **Wrap**
Wrap another error with additional message description, facilitating the tracing of the error's cause.
### Use Cases
- When defining errors with specific codes and messages, use error types that implement the `CodeError` interface.
- Use `WithDetail` to add additional context information to errors for more accurate problem localization.
- Use the `Is` method to judge the type of error for conditional branching.
- Use the `Wrap` method to wrap underlying errors while adding more contextual descriptions.
## Logging Standards and Code Examples
In the OpenIM project, we use the unified logging package `github.com/OpenIMSDK/tools/log` for logging to achieve efficient log management and analysis. This logging package supports structured logging formats, making it easier for developers to handle log information.
### Logger Interface and Implementation
The logger interface is defined as follows:
```go
type Logger interface {
Debug(ctx context.Context, msg string, keysAndValues ...interface{})
Info(ctx context.Context, msg string, keysAndValues ...interface{})
Warn(ctx context.Context, msg string, err error, keysAndValues ...interface{})
Error(ctx context.Context, msg string, err error, keysAndValues ...interface{})
WithValues(keysAndValues ...interface{}) Logger
WithName(name string) Logger
WithCallDepth(depth int) Logger
}
```
Example code: Using the `Logger` interface to log at the info level.
```go
func main() {
logger := log.NewLogger().WithName("MyService")
ctx := context.Background()
logger.Info(ctx, "Service started", "port", "8080")
}
```
## Error Handling and Code Examples
We use the `github.com/OpenIMSDK/tools/errs` package for unified error handling and wrapping.
### CodeError Interface and Implementation
The error interface is defined as follows:
```go
type CodeError interface {
Code() int
Msg() string
Detail() string
WithDetail(detail string) CodeError
Is(err error, loose ...bool) bool
Wrap(msg ...string) error
error
}
```
Example code: Creating and using the `CodeError` interface to handle errors.
```go
package main
import (
"fmt"
"github.com/OpenIMSDK/tools/errs"
)
func main() {
err := errs.New(404, "Resource not found")
err = err.WithDetail("
More details")
if e, ok := err.(errs.CodeError); ok {
fmt.Println(e.Code(), e.Msg(), e.Detail())
}
}
```
### Detailed Logging Standards and Code Examples
1. **Print key information at startup**
It is crucial to print entry parameters and key process information at program startup. This helps understand the startup state and configuration of the program.
**Code Example**:
```go
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println("Program startup, version: 1.0.0")
fmt.Printf("Connecting to database: %s\n", os.Getenv("DATABASE_URL"))
}
```
2. **Use `tools/log` and `fmt` for logging**
Logging should be done using a specialized logging library for unified management and formatted log output.
**Code Example**: Logging an info level message with `tools/log`.
```go
package main
import (
"context"
"github.com/OpenIMSDK/tools/log"
)
func main() {
ctx := context.Background()
log.Info(ctx, "Application started successfully")
}
```
3. **Use standard error output for startup failures or critical information**
Critical error messages or program startup failures should be indicated to the user through standard error output.
**Code Example**:
```go
package main
import (
"fmt"
"os"
)
func checkEnvironment() bool {
return os.Getenv("REQUIRED_ENV") != ""
}
func main() {
if !checkEnvironment() {
fmt.Fprintln(os.Stderr, "Missing required environment variable")
os.Exit(1)
}
}
```
We encapsulate it into separate tools, which can output error information through the `tools/log` package.
```go
package main
import (
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
)
func main() {
if err := apiCmd.Execute(); err != nil {
util.ExitWithError(err)
}
}
```
4. **Use `tools/log` package for runtime logging**
This ensures consistency and control over logging.
**Code Example**: Same as the above example using `tools/log`. When `tools/log` is not initialized, consider using `fmt` for standard output.
5. **Error logs should be printed by the top-level caller**
This is to avoid duplicate logging of errors, typically errors are caught and logged at the application's outermost level.
**Code Example**:
```go
package main
import (
"github.com/OpenIMSDK/tools/log"
"context"
)
func doSomething() error {
// An error occurs here
return errs.Wrap(errors.New("An error occurred"))
}
func controller() error {
err := doSomething()
if err != nil {
return err
}
return nil
}
func main() {
err := controller()
if err != nil {
log.Error(context.Background(), "Operation failed", err)
}
}
```
6. **Handling logs for API RPC calls and non-RPC applications**
For API RPC calls using gRPC, logs at the information level are printed by middleware on the gRPC server side, reducing the need to manually log in each RPC method. For non-RPC applications, it's recommended to manually log key execution paths to track the application's execution flow.
**gRPC Server-Side Logging Middleware:**
In gRPC, `UnaryInterceptor` and `StreamInterceptor` can intercept Unary and Stream type RPC calls, respectively. Here's an example of how to implement a simple Unary RPC logging middleware:
```go
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"log"
"time"
)
// unaryServerInterceptor returns a new unary server interceptor that logs each request.
func unaryServerInterceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
// Record the start time of the request
start := time.Now()
// Call the actual RPC method
resp, err = handler(ctx, req)
// After the request ends, log the duration and other information
log.Printf("Request method: %s, duration: %s, error status: %v", info.FullMethod, time.Since(start), status.Code(err))
return resp, err
}
}
func main() {
// Create a gRPC server and add the middleware
s := grpc.NewServer
(grpc.UnaryInterceptor(unaryServerInterceptor()))
// Register your service
// Start the gRPC server
log.Println("Starting gRPC server...")
// ...
}
```
**Logging for Non-RPC Applications:**
For non-RPC applications, the key is to log at appropriate places in the code to maintain an execution trace. Here's a simple example showing how to log when handling a task:
```go
package main
import (
"log"
)
func processTask(taskID string) {
// Log the start of task processing
log.Printf("Starting task processing: %s", taskID)
// Suppose this is where the task is processed
// Log after the task is completed
log.Printf("Task processing completed: %s", taskID)
}
func main() {
// Example task ID
taskID := "task123"
processTask(taskID)
}
```
In both scenarios, appropriate logging can help developers and operators monitor the health of the system, trace the source of issues, and quickly locate and resolve problems. For gRPC logging, using middleware can effectively centralize log management and control. For non-RPC applications, ensuring logs are placed at critical execution points can help understand the program's operational flow and state changes.
### When to Wrap Errors?
1. **Wrap errors generated within the function**
When an error occurs within a function, use `errs.Wrap` to add context information to the original error.
**Code Example**:
```go
func doSomething() error {
// Suppose an error occurs here
err, _ := someFunc()
if err != nil {
return errs.Wrap(err, "doSomething failed")
}
}
```
2. **Wrap errors from system calls or other packages**
When calling external libraries or system functions that return errors, also add context information to wrap the error.
**Code Example**:
```go
func readConfig(file string) error {
_, err := os.ReadFile(file)
if err != nil {
return errs.Wrap(err, "Failed to read config file")
}
return nil
}
```
3. **No need to re-wrap errors for internal module calls**
If an error has been appropriately wrapped with sufficient context information in an internal module call, there's no need to wrap it again.
**Code Example**:
```go
func doSomething() error {
err := doAnotherThing()
if err != nil {
return err
}
return nil
}
```
4. **Ensure comprehensive wrapping of errors with detailed messages**
When wrapping errors, ensure to provide ample context information to make the error more understandable and easier to debug.
**Code Example**:
```go
func connectDatabase() error {
err := db.Connect(config.DatabaseURL)
if err != nil {
return errs.Wrap(err, fmt.Sprintf("Failed to connect to database, URL: %s", config.DatabaseURL))
}
return nil
}
```
+5 -3
View File
@@ -96,7 +96,6 @@ We reinforce our approach to branch management and versioning with stringent tes
This document describes the maximum version skew supported between various openim components. Specific cluster deployment tools may place additional restrictions on version skew. This document describes the maximum version skew supported between various openim components. Specific cluster deployment tools may place additional restrictions on version skew.
### Supported version skew ### Supported version skew
In highly-available (HA) clusters, the newest and oldest `openim-api` instances must be within one minor version. In highly-available (HA) clusters, the newest and oldest `openim-api` instances must be within one minor version.
@@ -210,6 +209,7 @@ git merge release-v3.1
# Push the updates to the main branch # Push the updates to the main branch
git push origin main git push origin main
``` ```
## Release Process ## Release Process
``` ```
@@ -232,5 +232,7 @@ For more details on managing Docker image versions, visit [OpenIM Docker Images
More on multi-branch version management design and version management design at helm charts More on multi-branch version management design and version management design at helm charts
+ https://github.com/openimsdk/open-im-server/issues/1695 About Helm's version management strategy for Multiple Apps and multiple Services:
+ https://github.com/openimsdk/open-im-server/issues/1662
+ [中文版本管理文档](https://github.com/openimsdk/helm-charts/blob/main/docs/contrib/version-zh.md)
+ [English version management documents](https://github.com/openimsdk/helm-charts/blob/main/docs/contrib/version.md)
+5 -1
View File
@@ -4,7 +4,7 @@ go 1.19
require ( require (
firebase.google.com/go v3.13.0+incompatible firebase.google.com/go v3.13.0+incompatible
github.com/OpenIMSDK/protocol v0.0.55 github.com/OpenIMSDK/protocol v0.0.56
github.com/OpenIMSDK/tools v0.0.37 github.com/OpenIMSDK/tools v0.0.37
github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/dtm-labs/rockscache v0.1.1 github.com/dtm-labs/rockscache v0.1.1
@@ -18,6 +18,7 @@ require (
github.com/minio/minio-go/v7 v7.0.67 github.com/minio/minio-go/v7 v7.0.67
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/openimsdk/localcache v0.0.1
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
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
@@ -84,6 +85,7 @@ require (
github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect
@@ -162,3 +164,5 @@ require (
golang.org/x/crypto v0.19.0 // indirect golang.org/x/crypto v0.19.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
) )
replace github.com/openimsdk/localcache => ./pkg/localcache
+4 -2
View File
@@ -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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/IBM/sarama v1.42.2 h1:VoY4hVIZ+WQJ8G9KNY/SQlWguBQXQ9uvFPOnrcu8hEw= github.com/IBM/sarama v1.42.2 h1:VoY4hVIZ+WQJ8G9KNY/SQlWguBQXQ9uvFPOnrcu8hEw=
github.com/IBM/sarama v1.42.2/go.mod h1:FLPGUGwYqEs62hq2bVG6Io2+5n+pS6s/WOXVKWSLFtE= github.com/IBM/sarama v1.42.2/go.mod h1:FLPGUGwYqEs62hq2bVG6Io2+5n+pS6s/WOXVKWSLFtE=
github.com/OpenIMSDK/protocol v0.0.55 h1:eBjg8DyuhxGmuCUjpoZjg6MJJJXU/xJ3xJwFhrn34yA= github.com/OpenIMSDK/protocol v0.0.56 h1:mbVFyDBachEsmJLfYW5AU1z2KL8AUEpoHG8RPCIxjgg=
github.com/OpenIMSDK/protocol v0.0.55/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/protocol v0.0.56/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.37 h1:qvDqmA4RbEJtPjZouWCkVuf/pjm6Y8nUrG5iH2gcnOg= github.com/OpenIMSDK/tools v0.0.37 h1:qvDqmA4RbEJtPjZouWCkVuf/pjm6Y8nUrG5iH2gcnOg=
github.com/OpenIMSDK/tools v0.0.37/go.mod h1:wBfR5CYmEyvxl03QJbTkhz1CluK6J4/lX0lviu8JAjE= github.com/OpenIMSDK/tools v0.0.37/go.mod h1:wBfR5CYmEyvxl03QJbTkhz1CluK6J4/lX0lviu8JAjE=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
@@ -178,6 +178,8 @@ 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.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 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-4
View File
@@ -2,17 +2,13 @@ go 1.19
use ( use (
. .
./test/typecheck
./tools/codescan
./tools/changelog ./tools/changelog
./tools/component ./tools/component
./tools/data-conversion
./tools/formitychecker ./tools/formitychecker
./tools/imctl ./tools/imctl
./tools/infra ./tools/infra
./tools/ncpu ./tools/ncpu
./tools/openim-web ./tools/openim-web
./tools/up35
./tools/url2im ./tools/url2im
./tools/versionchecker ./tools/versionchecker
./tools/yamlfmt ./tools/yamlfmt
+2 -5
View File
@@ -215,25 +215,22 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
// Set the receiver ID in the message data. // Set the receiver ID in the message data.
sendMsgReq.MsgData.RecvID = req.RecvID sendMsgReq.MsgData.RecvID = req.RecvID
// Declare a variable to store the message sending status.
var status int
// Attempt to send the message using the client. // Attempt to send the message using the client.
respPb, err := m.Client.SendMsg(c, sendMsgReq) respPb, err := m.Client.SendMsg(c, sendMsgReq)
if err != nil { if err != nil {
// Set the status to failed and respond with an error if sending fails. // Set the status to failed and respond with an error if sending fails.
status = constant.MsgSendFailed
apiresp.GinError(c, err) apiresp.GinError(c, err)
return return
} }
// Set the status to successful if the message is sent. // Set the status to successful if the message is sent.
status = constant.MsgSendSuccessed var status int = constant.MsgSendSuccessed
// Attempt to update the message sending status in the system. // Attempt to update the message sending status in the system.
_, err = m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{ _, err = m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{
Status: int32(status), Status: int32(status),
}) })
if err != nil { if err != nil {
// Log the error if updating the status fails. // Log the error if updating the status fails.
apiresp.GinError(c, err) apiresp.GinError(c, err)
-1
View File
@@ -50,7 +50,6 @@ import (
) )
func Start(config *config.GlobalConfig, port int, proPort int) error { func Start(config *config.GlobalConfig, port int, proPort int) error {
log.ZDebug(context.Background(), "configAPI1111111111111111111", config, "port", port, "javafdasfs")
if port == 0 || proPort == 0 { if port == 0 || proPort == 0 {
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort) err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
return errs.Wrap(fmt.Errorf(err)) return errs.Wrap(fmt.Errorf(err))
+3 -3
View File
@@ -100,7 +100,7 @@ func CallbackUserKickOff(ctx context.Context, globalConfig *config.GlobalConfig,
// func callbackUserOnline(operationID, userID string, platformID int, token string, isAppBackground bool, connID // func callbackUserOnline(operationID, userID string, platformID int, token string, isAppBackground bool, connID
// string) cbApi.CommonCallbackResp { // string) cbApi.CommonCallbackResp {
// callbackResp := cbApi.CommonCallbackResp{OperationID: operationID} // callbackResp := cbApi.CommonCallbackResp{OperationID: operationID}
// if !config.Config.Callback.CallbackUserOnline.Enable { // if !config.Config.Callback.CallbackUserOnline.WithEnable {
// return callbackResp // return callbackResp
// } // }
// callbackUserOnlineReq := cbApi.CallbackUserOnlineReq{ // callbackUserOnlineReq := cbApi.CallbackUserOnlineReq{
@@ -129,7 +129,7 @@ func CallbackUserKickOff(ctx context.Context, globalConfig *config.GlobalConfig,
//} //}
//func callbackUserOffline(operationID, userID string, platformID int, connID string) cbApi.CommonCallbackResp { //func callbackUserOffline(operationID, userID string, platformID int, connID string) cbApi.CommonCallbackResp {
// callbackResp := cbApi.CommonCallbackResp{OperationID: operationID} // callbackResp := cbApi.CommonCallbackResp{OperationID: operationID}
// if !config.Config.Callback.CallbackUserOffline.Enable { // if !config.Config.Callback.CallbackUserOffline.WithEnable {
// return callbackResp // return callbackResp
// } // }
// callbackOfflineReq := cbApi.CallbackUserOfflineReq{ // callbackOfflineReq := cbApi.CallbackUserOfflineReq{
@@ -156,7 +156,7 @@ func CallbackUserKickOff(ctx context.Context, globalConfig *config.GlobalConfig,
//} //}
//func callbackUserKickOff(operationID string, userID string, platformID int) cbApi.CommonCallbackResp { //func callbackUserKickOff(operationID string, userID string, platformID int) cbApi.CommonCallbackResp {
// callbackResp := cbApi.CommonCallbackResp{OperationID: operationID} // callbackResp := cbApi.CommonCallbackResp{OperationID: operationID}
// if !config.Config.Callback.CallbackUserKickOff.Enable { // if !config.Config.Callback.CallbackUserKickOff.WithEnable {
// return callbackResp // return callbackResp
// } // }
// callbackUserKickOffReq := cbApi.CallbackUserKickOffReq{ // callbackUserKickOffReq := cbApi.CallbackUserKickOffReq{
+1 -2
View File
@@ -141,7 +141,6 @@ func (c *UserConnContext) GetBackground() bool {
b, err := strconv.ParseBool(c.Req.URL.Query().Get(BackgroundStatus)) b, err := strconv.ParseBool(c.Req.URL.Query().Get(BackgroundStatus))
if err != nil { if err != nil {
return false return false
} else {
return b
} }
return b
} }
+12 -15
View File
@@ -23,7 +23,6 @@ import (
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/mcontext" "github.com/OpenIMSDK/tools/mcontext"
"github.com/OpenIMSDK/tools/utils"
"github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/authverify"
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
@@ -58,22 +57,25 @@ type Server struct {
rpcPort int rpcPort int
prometheusPort int prometheusPort int
LongConnServer LongConnServer LongConnServer LongConnServer
pushTerminal []int
config *config.GlobalConfig config *config.GlobalConfig
pushTerminal map[int]struct{}
} }
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) { func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
s.LongConnServer = LongConnServer s.LongConnServer = LongConnServer
} }
func NewServer(rpcPort int, proPort int, longConnServer LongConnServer, config *config.GlobalConfig) *Server { func NewServer(rpcPort int, proPort int, longConnServer LongConnServer, conf *config.GlobalConfig) *Server {
return &Server{ s := &Server{
rpcPort: rpcPort, rpcPort: rpcPort,
prometheusPort: proPort, prometheusPort: proPort,
LongConnServer: longConnServer, LongConnServer: longConnServer,
pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID}, pushTerminal: make(map[int]struct{}),
config: config, config: conf,
} }
s.pushTerminal[constant.IOSPlatformID] = struct{}{}
s.pushTerminal[constant.AndroidPlatformID] = struct{}{}
return s
} }
func (s *Server) OnlinePushMsg( func (s *Server) OnlinePushMsg(
@@ -127,13 +129,9 @@ func (s *Server) OnlineBatchPushOneMsg(
panic("implement me") panic("implement me")
} }
func (s *Server) SuperGroupOnlineBatchPushOneMsg( func (s *Server) SuperGroupOnlineBatchPushOneMsg(ctx context.Context, req *msggateway.OnlineBatchPushOneMsgReq,
ctx context.Context,
req *msggateway.OnlineBatchPushOneMsgReq,
) (*msggateway.OnlineBatchPushOneMsgResp, error) { ) (*msggateway.OnlineBatchPushOneMsgResp, error) {
var singleUserResults []*msggateway.SingleMsgToUserResults var singleUserResults []*msggateway.SingleMsgToUserResults
for _, v := range req.PushToUserIDs { for _, v := range req.PushToUserIDs {
var resp []*msggateway.SingleMsgToUserPlatform var resp []*msggateway.SingleMsgToUserPlatform
results := &msggateway.SingleMsgToUserResults{ results := &msggateway.SingleMsgToUserResults{
@@ -154,23 +152,22 @@ func (s *Server) SuperGroupOnlineBatchPushOneMsg(
} }
userPlatform := &msggateway.SingleMsgToUserPlatform{ userPlatform := &msggateway.SingleMsgToUserPlatform{
RecvID: v,
RecvPlatFormID: int32(client.PlatformID), RecvPlatFormID: int32(client.PlatformID),
} }
if !client.IsBackground || if !client.IsBackground ||
(client.IsBackground && client.PlatformID != constant.IOSPlatformID) { (client.IsBackground && client.PlatformID != constant.IOSPlatformID) {
err := client.PushMessage(ctx, req.MsgData) err := client.PushMessage(ctx, req.MsgData)
if err != nil { if err != nil {
userPlatform.ResultCode = -2 userPlatform.ResultCode = int64(errs.ErrPushMsgErr.Code())
resp = append(resp, userPlatform) resp = append(resp, userPlatform)
} else { } else {
if utils.IsContainInt(client.PlatformID, s.pushTerminal) { if _, ok := s.pushTerminal[client.PlatformID]; ok {
results.OnlinePush = true results.OnlinePush = true
resp = append(resp, userPlatform) resp = append(resp, userPlatform)
} }
} }
} else { } else {
userPlatform.ResultCode = -3 userPlatform.ResultCode = int64(errs.ErrIOSBackgroundPushErr.Code())
resp = append(resp, userPlatform) resp = append(resp, userPlatform)
} }
} }
+51 -35
View File
@@ -19,7 +19,6 @@ import (
"sync" "sync"
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils"
) )
type UserMap struct { type UserMap struct {
@@ -71,48 +70,65 @@ func (u *UserMap) Set(key string, v *Client) {
} }
func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) { func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) {
// Attempt to load the clients associated with the key.
allClients, existed := u.m.Load(key) allClients, existed := u.m.Load(key)
if existed { if !existed {
oldClients := allClients.([]*Client) // Return false immediately if the key does not exist.
var a []*Client return false
for _, client := range oldClients { }
if client.ctx.GetRemoteAddr() != connRemoteAddr {
a = append(a, client) // Convert allClients to a slice of *Client.
} oldClients := allClients.([]*Client)
} var remainingClients []*Client
if len(a) == 0 { for _, client := range oldClients {
u.m.Delete(key) // Keep clients that do not match the connRemoteAddr.
return true if client.ctx.GetRemoteAddr() != connRemoteAddr {
} else { remainingClients = append(remainingClients, client)
u.m.Store(key, a)
return false
} }
} }
return existed
// If no clients remain after filtering, delete the key from the map.
if len(remainingClients) == 0 {
u.m.Delete(key)
return true
}
// Otherwise, update the key with the remaining clients.
u.m.Store(key, remainingClients)
return false
} }
func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser bool) { func (u *UserMap) deleteClients(key string, clientsToDelete []*Client) (isDeleteUser bool) {
m := utils.SliceToMapAny(clients, func(c *Client) (string, struct{}) { // Convert the slice of clients to delete into a map for efficient lookup.
return c.ctx.GetRemoteAddr(), struct{}{} deleteMap := make(map[string]struct{})
}) for _, client := range clientsToDelete {
deleteMap[client.ctx.GetRemoteAddr()] = struct{}{}
}
// Load the current clients associated with the key.
allClients, existed := u.m.Load(key) allClients, existed := u.m.Load(key)
if existed { if !existed {
oldClients := allClients.([]*Client) // If the key doesn't exist, return false.
var a []*Client return false
for _, client := range oldClients { }
if _, ok := m[client.ctx.GetRemoteAddr()]; !ok {
a = append(a, client) // Filter out clients that are in the deleteMap.
} oldClients := allClients.([]*Client)
} var remainingClients []*Client
if len(a) == 0 { for _, client := range oldClients {
u.m.Delete(key) if _, shouldBeDeleted := deleteMap[client.ctx.GetRemoteAddr()]; !shouldBeDeleted {
return true remainingClients = append(remainingClients, client)
} else {
u.m.Store(key, a)
return false
} }
} }
return existed
// Update or delete the key based on the remaining clients.
if len(remainingClients) == 0 {
u.m.Delete(key)
return true
}
u.m.Store(key, remainingClients)
return false
} }
func (u *UserMap) DeleteAll(key string) { func (u *UserMap) DeleteAll(key string) {
@@ -184,12 +184,11 @@ func (och *OnlineHistoryRedisConsumerHandler) getPushStorageMsgList(
options2 := msgprocessor.Options(msg.Options) options2 := msgprocessor.Options(msg.Options)
if options2.IsHistory() { if options2.IsHistory() {
return true return true
} else {
// if !(!options2.IsSenderSync() && conversationID == msg.MsgData.SendID) {
// return false
// }
return false
} }
// if !(!options2.IsSenderSync() && conversationID == msg.MsgData.SendID) {
// return false
// }
return false
} }
for _, v := range totalMsgs { for _, v := range totalMsgs {
options := msgprocessor.Options(v.message.Options) options := msgprocessor.Options(v.message.Options)
+1 -2
View File
@@ -90,9 +90,8 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
for i, v := range s.GetSplitResult() { for i, v := range s.GetSplitResult() {
go func(index int, userIDs []string) { go func(index int, userIDs []string) {
defer wg.Done() defer wg.Done()
if err := g.batchPush(ctx, token, userIDs, pushReq); err != nil { if err = g.batchPush(ctx, token, userIDs, pushReq); err != nil {
log.ZError(ctx, "batchPush failed", err, "index", index, "token", token, "req", pushReq) log.ZError(ctx, "batchPush failed", err, "index", index, "token", token, "req", pushReq)
err = err
} }
}(i, v.Item) }(i, v.Item)
} }
+4 -5
View File
@@ -25,7 +25,7 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpccache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@@ -51,8 +51,8 @@ func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryReg
client, client,
offlinePusher, offlinePusher,
database, database,
localcache.NewGroupLocalCache(&groupRpcClient), rpccache.NewGroupLocalCache(groupRpcClient, rdb),
localcache.NewConversationLocalCache(&conversationRpcClient), rpccache.NewConversationLocalCache(conversationRpcClient, rdb),
&conversationRpcClient, &conversationRpcClient,
&groupRpcClient, &groupRpcClient,
&msgRpcClient, &msgRpcClient,
@@ -90,9 +90,8 @@ func (r *pushServer) PushMsg(ctx context.Context, pbData *pbpush.PushMsgReq) (re
if err != nil { if err != nil {
if err != errNoOfflinePusher { if err != errNoOfflinePusher {
return nil, err return nil, err
} else {
log.ZWarn(ctx, "offline push failed", err, "msg", pbData.String())
} }
log.ZWarn(ctx, "offline push failed", err, "msg", pbData.String())
} }
return &pbpush.PushMsgResp{}, nil return &pbpush.PushMsgResp{}, nil
} }
+4 -4
View File
@@ -36,9 +36,9 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"google.golang.org/grpc" "google.golang.org/grpc"
@@ -49,8 +49,8 @@ type Pusher struct {
database controller.PushDatabase database controller.PushDatabase
discov discoveryregistry.SvcDiscoveryRegistry discov discoveryregistry.SvcDiscoveryRegistry
offlinePusher offlinepush.OfflinePusher offlinePusher offlinepush.OfflinePusher
groupLocalCache *localcache.GroupLocalCache groupLocalCache *rpccache.GroupLocalCache
conversationLocalCache *localcache.ConversationLocalCache conversationLocalCache *rpccache.ConversationLocalCache
msgRpcClient *rpcclient.MessageRpcClient msgRpcClient *rpcclient.MessageRpcClient
conversationRpcClient *rpcclient.ConversationRpcClient conversationRpcClient *rpcclient.ConversationRpcClient
groupRpcClient *rpcclient.GroupRpcClient groupRpcClient *rpcclient.GroupRpcClient
@@ -59,7 +59,7 @@ type Pusher struct {
var errNoOfflinePusher = errors.New("no offlinePusher is configured") var errNoOfflinePusher = errors.New("no offlinePusher is configured")
func NewPusher(config *config.GlobalConfig, discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase, func NewPusher(config *config.GlobalConfig, discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache, groupLocalCache *rpccache.GroupLocalCache, conversationLocalCache *rpccache.ConversationLocalCache,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
) *Pusher { ) *Pusher {
return &Pusher{ return &Pusher{
+1 -2
View File
@@ -26,7 +26,6 @@ func GetContent(msg *sdkws.MsgData) string {
_ = proto.Unmarshal(msg.Content, &tips) _ = proto.Unmarshal(msg.Content, &tips)
content := tips.JsonDetail content := tips.JsonDetail
return content return content
} else {
return string(msg.Content)
} }
return string(msg.Content)
} }
+37 -26
View File
@@ -48,14 +48,6 @@ type conversationServer struct {
config *config.GlobalConfig config *config.GlobalConfig
} }
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
ctx context.Context,
req *pbconversation.GetConversationNotReceiveMessageUserIDsReq,
) (*pbconversation.GetConversationNotReceiveMessageUserIDsResp, error) {
//TODO implement me
panic("implement me")
}
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis(config) rdb, err := cache.NewRedis(config)
if err != nil { if err != nil {
@@ -96,11 +88,11 @@ func (c *conversationServer) GetConversation(ctx context.Context, req *pbconvers
return resp, nil return resp, nil
} }
func (m *conversationServer) GetSortedConversationList(ctx context.Context, req *pbconversation.GetSortedConversationListReq) (resp *pbconversation.GetSortedConversationListResp, err error) { func (c *conversationServer) GetSortedConversationList(ctx context.Context, req *pbconversation.GetSortedConversationListReq) (resp *pbconversation.GetSortedConversationListResp, err error) {
log.ZDebug(ctx, "GetSortedConversationList", "seqs", req, "userID", req.UserID) log.ZDebug(ctx, "GetSortedConversationList", "seqs", req, "userID", req.UserID)
var conversationIDs []string var conversationIDs []string
if len(req.ConversationIDs) == 0 { if len(req.ConversationIDs) == 0 {
conversationIDs, err = m.conversationDatabase.GetConversationIDs(ctx, req.UserID) conversationIDs, err = c.conversationDatabase.GetConversationIDs(ctx, req.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -108,7 +100,7 @@ func (m *conversationServer) GetSortedConversationList(ctx context.Context, req
conversationIDs = req.ConversationIDs conversationIDs = req.ConversationIDs
} }
conversations, err := m.conversationDatabase.FindConversations(ctx, req.UserID, conversationIDs) conversations, err := c.conversationDatabase.FindConversations(ctx, req.UserID, conversationIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -116,22 +108,22 @@ func (m *conversationServer) GetSortedConversationList(ctx context.Context, req
return nil, errs.ErrRecordNotFound.Wrap() return nil, errs.ErrRecordNotFound.Wrap()
} }
maxSeqs, err := m.msgRpcClient.GetMaxSeqs(ctx, conversationIDs) maxSeqs, err := c.msgRpcClient.GetMaxSeqs(ctx, conversationIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
chatLogs, err := m.msgRpcClient.GetMsgByConversationIDs(ctx, conversationIDs, maxSeqs) chatLogs, err := c.msgRpcClient.GetMsgByConversationIDs(ctx, conversationIDs, maxSeqs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
conversationMsg, err := m.getConversationInfo(ctx, chatLogs, req.UserID) conversationMsg, err := c.getConversationInfo(ctx, chatLogs, req.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
hasReadSeqs, err := m.msgRpcClient.GetHasReadSeqs(ctx, req.UserID, conversationIDs) hasReadSeqs, err := c.msgRpcClient.GetHasReadSeqs(ctx, req.UserID, conversationIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -163,8 +155,8 @@ func (m *conversationServer) GetSortedConversationList(ctx context.Context, req
UnreadTotal: unreadTotal, UnreadTotal: unreadTotal,
} }
m.conversationSort(conversation_isPinTime, resp, conversation_unreadCount, conversationMsg) c.conversationSort(conversation_isPinTime, resp, conversation_unreadCount, conversationMsg)
m.conversationSort(conversation_notPinTime, resp, conversation_unreadCount, conversationMsg) c.conversationSort(conversation_notPinTime, resp, conversation_unreadCount, conversationMsg)
resp.ConversationElems = utils.Paginate(resp.ConversationElems, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber())) resp.ConversationElems = utils.Paginate(resp.ConversationElems, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber()))
return resp, nil return resp, nil
@@ -514,19 +506,27 @@ func (c *conversationServer) getConversationInfo(
switch chatLog.SessionType { switch chatLog.SessionType {
case constant.SingleChatType: case constant.SingleChatType:
if chatLog.SendID == userID { if chatLog.SendID == userID {
msgInfo.FaceURL = sendMap[chatLog.RecvID].FaceURL if recv, ok := sendMap[chatLog.RecvID]; ok {
msgInfo.SenderName = sendMap[chatLog.RecvID].Nickname msgInfo.FaceURL = recv.FaceURL
msgInfo.SenderName = recv.Nickname
}
break break
} }
msgInfo.FaceURL = sendMap[chatLog.SendID].FaceURL if send, ok := sendMap[chatLog.SendID]; ok {
msgInfo.SenderName = sendMap[chatLog.SendID].Nickname msgInfo.FaceURL = send.FaceURL
msgInfo.SenderName = send.Nickname
}
case constant.GroupChatType, constant.SuperGroupChatType: case constant.GroupChatType, constant.SuperGroupChatType:
msgInfo.GroupName = groupMap[chatLog.GroupID].GroupName
msgInfo.GroupFaceURL = groupMap[chatLog.GroupID].FaceURL
msgInfo.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount
msgInfo.GroupID = chatLog.GroupID msgInfo.GroupID = chatLog.GroupID
msgInfo.GroupType = groupMap[chatLog.GroupID].GroupType if group, ok := groupMap[chatLog.GroupID]; ok {
msgInfo.SenderName = sendMap[chatLog.SendID].Nickname msgInfo.GroupName = group.GroupName
msgInfo.GroupFaceURL = group.FaceURL
msgInfo.GroupMemberCount = group.MemberCount
msgInfo.GroupType = group.GroupType
}
if send, ok := sendMap[chatLog.SendID]; ok {
msgInfo.SenderName = send.Nickname
}
} }
pbchatLog.ConversationID = conversationID pbchatLog.ConversationID = conversationID
msgInfo.LatestMsgRecvTime = chatLog.SendTime msgInfo.LatestMsgRecvTime = chatLog.SendTime
@@ -535,3 +535,14 @@ func (c *conversationServer) getConversationInfo(
} }
return conversationMsg, nil return conversationMsg, nil
} }
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
ctx context.Context,
req *pbconversation.GetConversationNotReceiveMessageUserIDsReq,
) (*pbconversation.GetConversationNotReceiveMessageUserIDsResp, error) {
userIDs, err := c.conversationDatabase.GetConversationNotReceiveMessageUserIDs(ctx, req.ConversationID)
if err != nil {
return nil, err
}
return &pbconversation.GetConversationNotReceiveMessageUserIDsResp{UserIDs: userIDs}, nil
}
+6 -1
View File
@@ -79,9 +79,14 @@ func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq)
CreateTime: time.Now(), CreateTime: time.Now(),
Ex: req.Ex, Ex: req.Ex,
} }
if err := s.blackDatabase.Create(ctx, []*relation.BlackModel{&black}); err != nil { if err := s.blackDatabase.Create(ctx, []*relation.BlackModel{&black}); err != nil {
return nil, err return nil, err
} }
s.notificationSender.BlackAddedNotification(ctx, req)
if err := s.notificationSender.BlackAddedNotification(ctx, req); err != nil {
return nil, err
}
return &pbfriend.AddBlackResp{}, nil return &pbfriend.AddBlackResp{}, nil
} }
+14 -2
View File
@@ -114,26 +114,36 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
if err := authverify.CheckAccessV3(ctx, req.FromUserID, s.config); err != nil { if err := authverify.CheckAccessV3(ctx, req.FromUserID, s.config); err != nil {
return nil, err return nil, err
} }
if req.ToUserID == req.FromUserID { if req.ToUserID == req.FromUserID {
return nil, errs.ErrCanNotAddYourself.Wrap("req.ToUserID", req.ToUserID) return nil, errs.ErrCanNotAddYourself.Wrap("req.ToUserID", req.ToUserID)
} }
if err = CallbackBeforeAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue { if err = CallbackBeforeAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
return nil, err return nil, err
} }
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil { if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
return nil, err return nil, err
} }
in1, in2, err := s.friendDatabase.CheckIn(ctx, req.FromUserID, req.ToUserID) in1, in2, err := s.friendDatabase.CheckIn(ctx, req.FromUserID, req.ToUserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if in1 && in2 { if in1 && in2 {
return nil, errs.ErrRelationshipAlready.Wrap() return nil, errs.ErrRelationshipAlready.Wrap()
} }
if err = s.friendDatabase.AddFriendRequest(ctx, req.FromUserID, req.ToUserID, req.ReqMsg, req.Ex); err != nil { if err = s.friendDatabase.AddFriendRequest(ctx, req.FromUserID, req.ToUserID, req.ReqMsg, req.Ex); err != nil {
return nil, err return nil, err
} }
s.notificationSender.FriendApplicationAddNotification(ctx, req)
if err = s.notificationSender.FriendApplicationAddNotification(ctx, req); err != nil {
return nil, err
}
if err = CallbackAfterAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue { if err = CallbackAfterAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
return nil, err return nil, err
} }
@@ -197,7 +207,9 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
if err != nil { if err != nil {
return nil, err return nil, err
} }
s.notificationSender.FriendApplicationAgreedNotification(ctx, req) if err := s.notificationSender.FriendApplicationAgreedNotification(ctx, req); err != nil {
return nil, err
}
return resp, nil return resp, nil
} }
if req.HandleResult == constant.FriendResponseRefuse { if req.HandleResult == constant.FriendResponseRefuse {
+1 -4
View File
@@ -33,10 +33,7 @@ func (s *groupServer) GetGroupInfoCache(
return resp, nil return resp, nil
} }
func (s *groupServer) GetGroupMemberCache( func (s *groupServer) GetGroupMemberCache(ctx context.Context, req *pbgroup.GetGroupMemberCacheReq) (resp *pbgroup.GetGroupMemberCacheResp, err error) {
ctx context.Context,
req *pbgroup.GetGroupMemberCacheReq,
) (resp *pbgroup.GetGroupMemberCacheResp, err error) {
members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID) members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID)
if err != nil { if err != nil {
return nil, err return nil, err
+8 -10
View File
@@ -637,6 +637,7 @@ func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG
return resp, nil return resp, nil
} }
// GetGroupApplicationList handles functions that get a list of group requests.
func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.GetGroupApplicationListReq) (*pbgroup.GetGroupApplicationListResp, error) { func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup.GetGroupApplicationListReq) (*pbgroup.GetGroupApplicationListResp, error) {
groupIDs, err := s.db.FindUserManagedGroupID(ctx, req.FromUserID) groupIDs, err := s.db.FindUserManagedGroupID(ctx, req.FromUserID)
if err != nil { if err != nil {
@@ -951,6 +952,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
return nil, errs.Wrap(errs.ErrDismissedAlready) return nil, errs.Wrap(errs.ErrDismissedAlready)
} }
resp := &pbgroup.SetGroupInfoResp{} resp := &pbgroup.SetGroupInfoResp{}
count, err := s.db.FindGroupMemberNum(ctx, group.GroupID) count, err := s.db.FindGroupMemberNum(ctx, group.GroupID)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -1068,6 +1070,7 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq)
group []*relationtb.GroupModel group []*relationtb.GroupModel
err error err error
) )
if req.GroupID != "" { if req.GroupID != "" {
group, err = s.db.FindGroup(ctx, []string{req.GroupID}) group, err = s.db.FindGroup(ctx, []string{req.GroupID})
resp.Total = uint32(len(group)) resp.Total = uint32(len(group))
@@ -1076,25 +1079,20 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq)
total, group, err = s.db.SearchGroup(ctx, req.GroupName, req.Pagination) total, group, err = s.db.SearchGroup(ctx, req.GroupName, req.Pagination)
resp.Total = uint32(total) resp.Total = uint32(total)
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
var groups []*relationtb.GroupModel groupIDs := utils.Slice(group, func(e *relationtb.GroupModel) string {
for _, v := range group {
if v.Status == constant.GroupStatusDismissed {
resp.Total--
continue
}
groups = append(groups, v)
}
groupIDs := utils.Slice(groups, func(e *relationtb.GroupModel) string {
return e.GroupID return e.GroupID
}) })
ownerMembers, err := s.db.FindGroupsOwner(ctx, groupIDs) ownerMembers, err := s.db.FindGroupsOwner(ctx, groupIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
ownerMemberMap := utils.SliceToMap(ownerMembers, func(e *relationtb.GroupMemberModel) string { ownerMemberMap := utils.SliceToMap(ownerMembers, func(e *relationtb.GroupMemberModel) string {
return e.GroupID return e.GroupID
}) })
@@ -1102,7 +1100,7 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp.Groups = utils.Slice(groups, func(group *relationtb.GroupModel) *pbgroup.CMSGroup { resp.Groups = utils.Slice(group, func(group *relationtb.GroupModel) *pbgroup.CMSGroup {
var ( var (
userID string userID string
username string username string
+3 -3
View File
@@ -41,7 +41,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
if err != nil { if err != nil {
return nil, err return nil, err
} }
conversations, err := m.Conversation.GetConversations(ctx, req.UserID, conversationIDs) conversations, err := m.ConversationLocalCache.GetConversations(ctx, req.UserID, conversationIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -104,7 +104,7 @@ func (m *msgServer) MarkMsgsAsRead(
if hasReadSeq > maxSeq { if hasReadSeq > maxSeq {
return nil, errs.ErrArgs.Wrap("hasReadSeq must not be bigger than maxSeq") return nil, errs.ErrArgs.Wrap("hasReadSeq must not be bigger than maxSeq")
} }
conversation, err := m.Conversation.GetConversation(ctx, req.UserID, req.ConversationID) conversation, err := m.ConversationLocalCache.GetConversation(ctx, req.UserID, req.ConversationID)
if err != nil { if err != nil {
return return
} }
@@ -144,7 +144,7 @@ func (m *msgServer) MarkConversationAsRead(
ctx context.Context, ctx context.Context,
req *msg.MarkConversationAsReadReq, req *msg.MarkConversationAsReadReq,
) (resp *msg.MarkConversationAsReadResp, err error) { ) (resp *msg.MarkConversationAsReadResp, err error) {
conversation, err := m.Conversation.GetConversation(ctx, req.UserID, req.ConversationID) conversation, err := m.ConversationLocalCache.GetConversation(ctx, req.UserID, req.ConversationID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+4 -4
View File
@@ -156,27 +156,27 @@ func callbackMsgModify(ctx context.Context, globalConfig *config.GlobalConfig, m
return nil return nil
} }
func CallbackGroupMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackGroupMsgReadReq) error { func CallbackGroupMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackGroupMsgReadReq) error {
if !globalConfig.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text { if !globalConfig.Callback.CallbackGroupMsgRead.Enable {
return nil return nil
} }
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
resp := &cbapi.CallbackGroupMsgReadResp{} resp := &cbapi.CallbackGroupMsgReadResp{}
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil { if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackGroupMsgRead); err != nil {
return err return err
} }
return nil return nil
} }
func CallbackSingleMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackSingleMsgReadReq) error { func CallbackSingleMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackSingleMsgReadReq) error {
if !globalConfig.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text { if !globalConfig.Callback.CallbackSingleMsgRead.Enable {
return nil return nil
} }
req.CallbackCommand = cbapi.CallbackSingleMsgRead req.CallbackCommand = cbapi.CallbackSingleMsgRead
resp := &cbapi.CallbackSingleMsgReadResp{} resp := &cbapi.CallbackSingleMsgReadResp{}
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil { if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackSingleMsgRead); err != nil {
return err return err
} }
return nil return nil
+2 -7
View File
@@ -44,7 +44,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil { if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
return nil, err return nil, err
} }
user, err := m.User.GetUserInfo(ctx, req.UserID) user, err := m.UserLocalCache.GetUserInfo(ctx, req.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -70,12 +70,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
} }
role = user.AppMangerLevel role = user.AppMangerLevel
case constant.SuperGroupChatType: case constant.SuperGroupChatType:
members, err := m.Group.GetGroupMemberInfoMap( members, err := m.GroupLocalCache.GetGroupMemberInfoMap(ctx, msgs[0].GroupID, utils.Distinct([]string{req.UserID, msgs[0].SendID}))
ctx,
msgs[0].GroupID,
utils.Distinct([]string{req.UserID, msgs[0].SendID}),
true,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+2 -1
View File
@@ -97,7 +97,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
} }
tagAll := utils.IsContain(constant.AtAllString, msg.AtUserIDList) tagAll := utils.IsContain(constant.AtAllString, msg.AtUserIDList)
if tagAll { if tagAll {
memberUserIDList, err := m.Group.GetGroupMemberIDs(ctx, msg.GroupID) memberUserIDList, err := m.GroupLocalCache.GetGroupMemberIDs(ctx, msg.GroupID)
if err != nil { if err != nil {
log.ZWarn(ctx, "GetGroupMemberIDs", err) log.ZWarn(ctx, "GetGroupMemberIDs", err)
return return
@@ -143,6 +143,7 @@ func (m *msgServer) sendMsgNotification(
} }
func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, err error) { func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, err error) {
log.ZDebug(ctx, "sendMsgSingleChat return")
if err := m.messageVerification(ctx, req); err != nil { if err := m.messageVerification(ctx, req); err != nil {
return nil, err return nil, err
} }
+9 -11
View File
@@ -22,8 +22,8 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
"github.com/openimsdk/open-im-server/v3/pkg/rpccache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@@ -33,12 +33,11 @@ type (
msgServer struct { msgServer struct {
RegisterCenter discoveryregistry.SvcDiscoveryRegistry RegisterCenter discoveryregistry.SvcDiscoveryRegistry
MsgDatabase controller.CommonMsgDatabase MsgDatabase controller.CommonMsgDatabase
Group *rpcclient.GroupRpcClient
User *rpcclient.UserRpcClient
Conversation *rpcclient.ConversationRpcClient Conversation *rpcclient.ConversationRpcClient
friend *rpcclient.FriendRpcClient UserLocalCache *rpccache.UserLocalCache
GroupLocalCache *localcache.GroupLocalCache FriendLocalCache *rpccache.FriendLocalCache
ConversationLocalCache *localcache.ConversationLocalCache GroupLocalCache *rpccache.GroupLocalCache
ConversationLocalCache *rpccache.ConversationLocalCache
Handlers MessageInterceptorChain Handlers MessageInterceptorChain
notificationSender *rpcclient.NotificationSender notificationSender *rpcclient.NotificationSender
config *config.GlobalConfig config *config.GlobalConfig
@@ -84,13 +83,12 @@ func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryReg
} }
s := &msgServer{ s := &msgServer{
Conversation: &conversationClient, Conversation: &conversationClient,
User: &userRpcClient,
Group: &groupRpcClient,
MsgDatabase: msgDatabase, MsgDatabase: msgDatabase,
RegisterCenter: client, RegisterCenter: client,
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient), UserLocalCache: rpccache.NewUserLocalCache(userRpcClient, rdb),
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient), GroupLocalCache: rpccache.NewGroupLocalCache(groupRpcClient, rdb),
friend: &friendRpcClient, ConversationLocalCache: rpccache.NewConversationLocalCache(conversationClient, rdb),
FriendLocalCache: rpccache.NewFriendLocalCache(friendRpcClient, rdb),
config: config, config: config,
} }
s.notificationSender = rpcclient.NewNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg)) s.notificationSender = rpcclient.NewNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg))
+2 -2
View File
@@ -40,7 +40,7 @@ func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq
var pbUsers []*msg.ActiveUser var pbUsers []*msg.ActiveUser
if len(users) > 0 { if len(users) > 0 {
userIDs := utils.Slice(users, func(e *unrelation.UserCount) string { return e.UserID }) userIDs := utils.Slice(users, func(e *unrelation.UserCount) string { return e.UserID })
userMap, err := m.User.GetUsersInfoMap(ctx, userIDs) userMap, err := m.UserLocalCache.GetUsersInfoMap(ctx, userIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -82,7 +82,7 @@ func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupR
var pbgroups []*msg.ActiveGroup var pbgroups []*msg.ActiveGroup
if len(groups) > 0 { if len(groups) > 0 {
groupIDs := utils.Slice(groups, func(e *unrelation.GroupCount) string { return e.GroupID }) groupIDs := utils.Slice(groups, func(e *unrelation.GroupCount) string { return e.GroupID })
resp, err := m.Group.GetGroupInfos(ctx, groupIDs, false) resp, err := m.GroupLocalCache.GetGroupInfos(ctx, groupIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
+22 -13
View File
@@ -35,7 +35,7 @@ func (m *msgServer) PullMessageBySeqs(
resp.NotificationMsgs = make(map[string]*sdkws.PullMsgs) resp.NotificationMsgs = make(map[string]*sdkws.PullMsgs)
for _, seq := range req.SeqRanges { for _, seq := range req.SeqRanges {
if !msgprocessor.IsNotification(seq.ConversationID) { if !msgprocessor.IsNotification(seq.ConversationID) {
conversation, err := m.Conversation.GetConversation(ctx, req.UserID, seq.ConversationID) conversation, err := m.ConversationLocalCache.GetConversation(ctx, req.UserID, seq.ConversationID)
if err != nil { if err != nil {
log.ZError(ctx, "GetConversation error", err, "conversationID", seq.ConversationID) log.ZError(ctx, "GetConversation error", err, "conversationID", seq.ConversationID)
continue continue
@@ -131,14 +131,15 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
sendIDs = append(sendIDs, chatLog.SendID) sendIDs = append(sendIDs, chatLog.SendID)
} }
switch chatLog.SessionType { switch chatLog.SessionType {
case constant.SingleChatType: case constant.SingleChatType, constant.NotificationChatType:
recvIDs = append(recvIDs, chatLog.RecvID) recvIDs = append(recvIDs, chatLog.RecvID)
case constant.GroupChatType, constant.SuperGroupChatType: case constant.GroupChatType, constant.SuperGroupChatType:
groupIDs = append(groupIDs, chatLog.GroupID) groupIDs = append(groupIDs, chatLog.GroupID)
} }
} }
// Retrieve sender and receiver information
if len(sendIDs) != 0 { if len(sendIDs) != 0 {
sendInfos, err := m.User.GetUsersInfo(ctx, sendIDs) sendInfos, err := m.UserLocalCache.GetUsersInfo(ctx, sendIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -147,7 +148,7 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
} }
} }
if len(recvIDs) != 0 { if len(recvIDs) != 0 {
recvInfos, err := m.User.GetUsersInfo(ctx, recvIDs) recvInfos, err := m.UserLocalCache.GetUsersInfo(ctx, recvIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -155,15 +156,23 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
recvMap[recvInfo.UserID] = recvInfo.Nickname recvMap[recvInfo.UserID] = recvInfo.Nickname
} }
} }
// Retrieve group information including member counts
if len(groupIDs) != 0 { if len(groupIDs) != 0 {
groupInfos, err := m.Group.GetGroupInfos(ctx, groupIDs, true) groupInfos, err := m.GroupLocalCache.GetGroupInfos(ctx, groupIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, groupInfo := range groupInfos { for _, groupInfo := range groupInfos {
groupMap[groupInfo.GroupID] = groupInfo groupMap[groupInfo.GroupID] = groupInfo
// Get actual member count
memberIDs, err := m.GroupLocalCache.GetGroupMemberIDs(ctx, groupInfo.GroupID)
if err == nil {
groupInfo.MemberCount = uint32(len(memberIDs)) // Update the member count with actual number
}
} }
} }
// Construct response with updated information
for _, chatLog := range chatLogs { for _, chatLog := range chatLogs {
pbchatLog := &msg.ChatLog{} pbchatLog := &msg.ChatLog{}
utils.CopyStructFields(pbchatLog, chatLog) utils.CopyStructFields(pbchatLog, chatLog)
@@ -173,16 +182,16 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
pbchatLog.SenderNickname = sendMap[chatLog.SendID] pbchatLog.SenderNickname = sendMap[chatLog.SendID]
} }
switch chatLog.SessionType { switch chatLog.SessionType {
case constant.SingleChatType: case constant.SingleChatType, constant.NotificationChatType:
pbchatLog.RecvNickname = recvMap[chatLog.RecvID] pbchatLog.RecvNickname = recvMap[chatLog.RecvID]
case constant.GroupChatType, constant.SuperGroupChatType: case constant.GroupChatType, constant.SuperGroupChatType:
pbchatLog.SenderFaceURL = groupMap[chatLog.GroupID].FaceURL groupInfo := groupMap[chatLog.GroupID]
pbchatLog.GroupMemberCount = groupMap[chatLog.GroupID].MemberCount pbchatLog.SenderFaceURL = groupInfo.FaceURL
pbchatLog.RecvID = groupMap[chatLog.GroupID].GroupID pbchatLog.GroupMemberCount = groupInfo.MemberCount // Reflects actual member count
pbchatLog.GroupName = groupMap[chatLog.GroupID].GroupName pbchatLog.RecvID = groupInfo.GroupID
pbchatLog.GroupOwner = groupMap[chatLog.GroupID].OwnerUserID pbchatLog.GroupName = groupInfo.GroupName
pbchatLog.GroupType = groupMap[chatLog.GroupID].GroupType pbchatLog.GroupOwner = groupInfo.OwnerUserID
pbchatLog.GroupType = groupInfo.GroupType
} }
resp.ChatLogs = append(resp.ChatLogs, pbchatLog) resp.ChatLogs = append(resp.ChatLogs, pbchatLog)
} }
+18 -16
View File
@@ -24,6 +24,7 @@ import (
"github.com/OpenIMSDK/protocol/msg" "github.com/OpenIMSDK/protocol/msg"
"github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/protocol/sdkws"
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"
) )
@@ -59,15 +60,15 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
data.MsgData.ContentType >= constant.NotificationBegin { data.MsgData.ContentType >= constant.NotificationBegin {
return nil return nil
} }
black, err := m.friend.IsBlocked(ctx, data.MsgData.SendID, data.MsgData.RecvID) black, err := m.FriendLocalCache.IsBlack(ctx, data.MsgData.SendID, data.MsgData.RecvID)
if err != nil { if err != nil {
return err return err
} }
if black { if black {
return errs.ErrBlockedByPeer.Wrap() return errs.ErrBlockedByPeer.Wrap()
} }
if *m.config.MessageVerify.FriendVerify { if m.config.MessageVerify.FriendVerify != nil && *m.config.MessageVerify.FriendVerify {
friend, err := m.friend.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID) friend, err := m.FriendLocalCache.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
if err != nil { if err != nil {
return err return err
} }
@@ -78,7 +79,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
} }
return nil return nil
case constant.SuperGroupChatType: case constant.SuperGroupChatType:
groupInfo, err := m.Group.GetGroupInfoCache(ctx, data.MsgData.GroupID) groupInfo, err := m.GroupLocalCache.GetGroupInfo(ctx, data.MsgData.GroupID)
if err != nil { if err != nil {
return err return err
} }
@@ -99,17 +100,17 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
data.MsgData.ContentType >= constant.NotificationBegin { data.MsgData.ContentType >= constant.NotificationBegin {
return nil return nil
} }
// memberIDs, err := m.GroupLocalCache.GetGroupMemberIDs(ctx, data.MsgData.GroupID) memberIDs, err := m.GroupLocalCache.GetGroupMemberIDMap(ctx, data.MsgData.GroupID)
// if err != nil {
// return err
// }
// if !utils.IsContain(data.MsgData.SendID, memberIDs) {
// return errs.ErrNotInGroupYet.Wrap()
// }
groupMemberInfo, err := m.Group.GetGroupMemberCache(ctx, data.MsgData.GroupID, data.MsgData.SendID)
if err != nil { if err != nil {
if err == errs.ErrRecordNotFound { return err
}
if _, ok := memberIDs[data.MsgData.SendID]; !ok {
return errs.ErrNotInGroupYet.Wrap()
}
groupMemberInfo, err := m.GroupLocalCache.GetGroupMember(ctx, data.MsgData.GroupID, data.MsgData.SendID)
if err != nil {
if errs.ErrRecordNotFound.Is(err) {
return errs.ErrNotInGroupYet.Wrap(err.Error()) return errs.ErrNotInGroupYet.Wrap(err.Error())
} }
return err return err
@@ -187,7 +188,8 @@ func (m *msgServer) modifyMessageByUserMessageReceiveOpt(
sessionType int, sessionType int,
pb *msg.SendMsgReq, pb *msg.SendMsgReq,
) (bool, error) { ) (bool, error) {
opt, err := m.User.GetUserGlobalMsgRecvOpt(ctx, userID) defer log.ZDebug(ctx, "modifyMessageByUserMessageReceiveOpt return")
opt, err := m.UserLocalCache.GetUserGlobalMsgRecvOpt(ctx, userID)
if err != nil { if err != nil {
return false, err return false, err
} }
@@ -203,7 +205,7 @@ func (m *msgServer) modifyMessageByUserMessageReceiveOpt(
return true, nil return true, nil
} }
// conversationID := utils.GetConversationIDBySessionType(conversationID, sessionType) // conversationID := utils.GetConversationIDBySessionType(conversationID, sessionType)
singleOpt, err := m.Conversation.GetSingleConversationRecvMsgOpt(ctx, userID, conversationID) singleOpt, err := m.ConversationLocalCache.GetSingleConversationRecvMsgOpt(ctx, userID, conversationID)
if errs.ErrRecordNotFound.Is(err) { if errs.ErrRecordNotFound.Is(err) {
return true, nil return true, nil
} else if err != nil { } else if err != nil {
+7
View File
@@ -133,6 +133,13 @@ func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq)
if req.StartTime > req.EndTime { if req.StartTime > req.EndTime {
return nil, errs.ErrArgs.Wrap("startTime>endTime") return nil, errs.ErrArgs.Wrap("startTime>endTime")
} }
if req.StartTime == 0 && req.EndTime == 0 {
t := time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)
timestampMills := t.UnixNano() / int64(time.Millisecond)
req.StartTime = timestampMills
req.EndTime = time.Now().UnixNano() / int64(time.Millisecond)
}
total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination) total, logs, err := t.thirdDatabase.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination)
if err != nil { if err != nil {
return nil, err return nil, err
+1
View File
@@ -60,6 +60,7 @@ func CheckAdmin(ctx context.Context, config *config.GlobalConfig) error {
} }
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx))) return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
} }
func CheckIMAdmin(ctx context.Context, config *config.GlobalConfig) error { func CheckIMAdmin(ctx context.Context, config *config.GlobalConfig) error {
if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) { if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) {
return nil return nil
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -12,23 +12,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package cachekey
import ( const (
"flag" BlackIDsKey = "BLACK_IDS:"
"log" IsBlackKey = "IS_BLACK:" // local cache
"os"
"github.com/openimsdk/open-im-server/v3/tools/up35/pkg"
) )
func main() { func GetBlackIDsKey(ownerUserID string) string {
var path string return BlackIDsKey + ownerUserID
flag.StringVar(&path, "c", "", "path config file")
flag.Parse() }
if err := pkg.Main(path); err != nil {
log.Fatal(err) func GetIsBlackIDsKey(possibleBlackUserID, userID string) string {
return return IsBlackKey + userID + "-" + possibleBlackUserID
}
os.Exit(0)
} }
+58
View File
@@ -0,0 +1,58 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cachekey
const (
ConversationKey = "CONVERSATION:"
ConversationIDsKey = "CONVERSATION_IDS:"
ConversationIDsHashKey = "CONVERSATION_IDS_HASH:"
ConversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:"
RecvMsgOptKey = "RECV_MSG_OPT:"
SuperGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:"
SuperGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:"
ConversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MESSAGE_USER_IDS:"
)
func GetConversationKey(ownerUserID, conversationID string) string {
return ConversationKey + ownerUserID + ":" + conversationID
}
func GetConversationIDsKey(ownerUserID string) string {
return ConversationIDsKey + ownerUserID
}
func GetSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
return SuperGroupRecvMsgNotNotifyUserIDsKey + groupID
}
func GetRecvMsgOptKey(ownerUserID, conversationID string) string {
return RecvMsgOptKey + ownerUserID + ":" + conversationID
}
func GetSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string {
return SuperGroupRecvMsgNotNotifyUserIDsHashKey + groupID
}
func GetConversationHasReadSeqKey(ownerUserID, conversationID string) string {
return ConversationHasReadSeqKey + ownerUserID + ":" + conversationID
}
func GetConversationNotReceiveMessageUserIDsKey(conversationID string) string {
return ConversationNotReceiveMessageUserIDsKey + conversationID
}
func GetUserConversationIDsHashKey(ownerUserID string) string {
return ConversationIDsHashKey + ownerUserID
}
+38
View File
@@ -0,0 +1,38 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cachekey
const (
FriendIDsKey = "FRIEND_IDS:"
TwoWayFriendsIDsKey = "COMMON_FRIENDS_IDS:"
FriendKey = "FRIEND_INFO:"
IsFriendKey = "IS_FRIEND:" // local cache key
)
func GetFriendIDsKey(ownerUserID string) string {
return FriendIDsKey + ownerUserID
}
func GetTwoWayFriendsIDsKey(ownerUserID string) string {
return TwoWayFriendsIDsKey + ownerUserID
}
func GetFriendKey(ownerUserID, friendUserID string) string {
return FriendKey + ownerUserID + "-" + friendUserID
}
func GetIsFriendKey(possibleFriendUserID, userID string) string {
return IsFriendKey + possibleFriendUserID + "-" + userID
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cachekey
import (
"strconv"
"time"
)
const (
groupExpireTime = time.Second * 60 * 60 * 12
GroupInfoKey = "GROUP_INFO:"
GroupMemberIDsKey = "GROUP_MEMBER_IDS:"
GroupMembersHashKey = "GROUP_MEMBERS_HASH2:"
GroupMemberInfoKey = "GROUP_MEMBER_INFO:"
JoinedGroupsKey = "JOIN_GROUPS_KEY:"
GroupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
GroupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
)
func GetGroupInfoKey(groupID string) string {
return GroupInfoKey + groupID
}
func GetJoinedGroupsKey(userID string) string {
return JoinedGroupsKey + userID
}
func GetGroupMembersHashKey(groupID string) string {
return GroupMembersHashKey + groupID
}
func GetGroupMemberIDsKey(groupID string) string {
return GroupMemberIDsKey + groupID
}
func GetGroupMemberInfoKey(groupID, userID string) string {
return GroupMemberInfoKey + groupID + "-" + userID
}
func GetGroupMemberNumKey(groupID string) string {
return GroupMemberNumKey + groupID
}
func GetGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string {
return GroupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel))
}
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -12,18 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package common package cachekey
import "fmt" const (
UserInfoKey = "USER_INFO:"
UserGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
)
func ErrorPrint(s string) { func GetUserInfoKey(userID string) string {
fmt.Printf("\x1b[%dm%v\x1b[0m\n", 31, s) return UserInfoKey + userID
} }
func SuccessPrint(s string) { func GetUserGlobalRecvMsgOptKey(userID string) string {
fmt.Printf("\x1b[%dm%v\x1b[0m\n", 32, s) return UserGlobalRecvMsgOptKey + userID
}
func WarningPrint(s string) {
fmt.Printf("\x1b[%dmWarning: But %v\x1b[0m\n", 33, s)
} }
+30
View File
@@ -16,6 +16,7 @@ package config
import ( import (
"bytes" "bytes"
"time"
"github.com/OpenIMSDK/tools/discoveryregistry" "github.com/OpenIMSDK/tools/discoveryregistry"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -266,6 +267,8 @@ type GlobalConfig struct {
FriendVerify *bool `yaml:"friendVerify"` FriendVerify *bool `yaml:"friendVerify"`
} `yaml:"messageVerify"` } `yaml:"messageVerify"`
LocalCache localCache `yaml:"localCache"`
IOSPush struct { IOSPush struct {
PushSound string `yaml:"pushSound"` PushSound string `yaml:"pushSound"`
BadgeCount bool `yaml:"badgeCount"` BadgeCount bool `yaml:"badgeCount"`
@@ -382,6 +385,33 @@ type notification struct {
ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"` ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"`
} }
type LocalCache struct {
Topic string `yaml:"topic"`
SlotNum int `yaml:"slotNum"`
SlotSize int `yaml:"slotSize"`
SuccessExpire int `yaml:"successExpire"` // second
FailedExpire int `yaml:"failedExpire"` // second
}
func (l LocalCache) Failed() time.Duration {
return time.Second * time.Duration(l.FailedExpire)
}
func (l LocalCache) Success() time.Duration {
return time.Second * time.Duration(l.SuccessExpire)
}
func (l LocalCache) Enable() bool {
return l.Topic != "" && l.SlotNum > 0 && l.SlotSize > 0
}
type localCache struct {
User LocalCache `yaml:"user"`
Group LocalCache `yaml:"group"`
Friend LocalCache `yaml:"friend"`
Conversation LocalCache `yaml:"conversation"`
}
func (c *GlobalConfig) GetServiceNames() []string { func (c *GlobalConfig) GetServiceNames() []string {
return []string{ return []string{
c.RpcRegisterName.OpenImUserName, c.RpcRegisterName.OpenImUserName,
+13
View File
@@ -16,9 +16,12 @@ package config
import ( import (
_ "embed" _ "embed"
"fmt"
"reflect" "reflect"
"testing" "testing"
"gopkg.in/yaml.v3"
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
) )
@@ -116,3 +119,13 @@ func TestInitConfig(t *testing.T) {
}) })
} }
} }
func TestName(t *testing.T) {
Config.LocalCache.Friend.Topic = "friend"
Config.LocalCache.Friend.SlotNum = 500
Config.LocalCache.Friend.SlotSize = 20000
data, _ := yaml.Marshal(&Config)
fmt.Println(string(data))
}
+1 -1
View File
@@ -1 +1 @@
3.5.1 3.6.0
+11 -4
View File
@@ -18,7 +18,10 @@ import (
"context" "context"
"time" "time"
"github.com/OpenIMSDK/tools/log"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
@@ -47,11 +50,15 @@ type BlackCacheRedis struct {
func NewBlackCacheRedis(rdb redis.UniversalClient, blackDB relationtb.BlackModelInterface, options rockscache.Options) BlackCache { func NewBlackCacheRedis(rdb redis.UniversalClient, blackDB relationtb.BlackModelInterface, options rockscache.Options) BlackCache {
rcClient := rockscache.NewClient(rdb, options) rcClient := rockscache.NewClient(rdb, options)
mc := NewMetaCacheRedis(rcClient)
b := config.Config.LocalCache.Friend
log.ZDebug(context.Background(), "black local cache init", "Topic", b.Topic, "SlotNum", b.SlotNum, "SlotSize", b.SlotSize, "enable", b.Enable())
mc.SetTopic(b.Topic)
mc.SetRawRedisClient(rdb)
return &BlackCacheRedis{ return &BlackCacheRedis{
expireTime: blackExpireTime, expireTime: blackExpireTime,
rcClient: rcClient, rcClient: rcClient,
metaCache: NewMetaCacheRedis(rcClient), metaCache: mc,
blackDB: blackDB, blackDB: blackDB,
} }
} }
@@ -61,12 +68,12 @@ func (b *BlackCacheRedis) NewCache() BlackCache {
expireTime: b.expireTime, expireTime: b.expireTime,
rcClient: b.rcClient, rcClient: b.rcClient,
blackDB: b.blackDB, blackDB: b.blackDB,
metaCache: NewMetaCacheRedis(b.rcClient, b.metaCache.GetPreDelKeys()...), metaCache: b.Copy(),
} }
} }
func (b *BlackCacheRedis) getBlackIDsKey(ownerUserID string) string { func (b *BlackCacheRedis) getBlackIDsKey(ownerUserID string) string {
return blackIDsKey + ownerUserID return cachekey.GetBlackIDsKey(ownerUserID)
} }
func (b *BlackCacheRedis) GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) { func (b *BlackCacheRedis) GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) {
+81
View File
@@ -0,0 +1,81 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cache
import (
"strings"
"sync"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
)
var (
once sync.Once
subscribe map[string][]string
)
func getPublishKey(topic string, key []string) []string {
if topic == "" || len(key) == 0 {
return nil
}
once.Do(func() {
list := []struct {
Local config.LocalCache
Keys []string
}{
{
Local: config.Config.LocalCache.User,
Keys: []string{cachekey.UserInfoKey, cachekey.UserGlobalRecvMsgOptKey},
},
{
Local: config.Config.LocalCache.Group,
Keys: []string{cachekey.GroupMemberIDsKey, cachekey.GroupInfoKey, cachekey.GroupMemberInfoKey},
},
{
Local: config.Config.LocalCache.Friend,
Keys: []string{cachekey.FriendIDsKey, cachekey.BlackIDsKey},
},
{
Local: config.Config.LocalCache.Conversation,
Keys: []string{cachekey.ConversationKey, cachekey.ConversationIDsKey, cachekey.ConversationNotReceiveMessageUserIDsKey},
},
}
subscribe = make(map[string][]string)
for _, v := range list {
if v.Local.Enable() {
subscribe[v.Local.Topic] = v.Keys
}
}
})
prefix, ok := subscribe[topic]
if !ok {
return nil
}
res := make([]string, 0, len(key))
for _, k := range key {
var exist bool
for _, p := range prefix {
if strings.HasPrefix(k, p) {
exist = true
break
}
}
if exist {
res = append(res, k)
}
}
return res
}
+29 -22
View File
@@ -20,21 +20,24 @@ import (
"strings" "strings"
"time" "time"
"github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
const ( const (
conversationKey = "CONVERSATION:" //conversationKey = "CONVERSATION:"
conversationIDsKey = "CONVERSATION_IDS:" //conversationIDsKey = "CONVERSATION_IDS:"
conversationIDsHashKey = "CONVERSATION_IDS_HASH:" //conversationIDsHashKey = "CONVERSATION_IDS_HASH:"
conversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:" //conversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:"
recvMsgOptKey = "RECV_MSG_OPT:" //recvMsgOptKey = "RECV_MSG_OPT:"
superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:" //superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:"
superGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:" //superGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:"
conversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MESSAGE_USER_IDS:" //conversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MESSAGE_USER_IDS:".
conversationExpireTime = time.Second * 60 * 60 * 12 conversationExpireTime = time.Second * 60 * 60 * 12
) )
@@ -81,10 +84,14 @@ type ConversationCache interface {
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) rcClient := rockscache.NewClient(rdb, opts)
mc := NewMetaCacheRedis(rcClient)
c := config.Config.LocalCache.Conversation
log.ZDebug(context.Background(), "black local cache init", "Topic", c.Topic, "SlotNum", c.SlotNum, "SlotSize", c.SlotSize, "enable", c.Enable())
mc.SetTopic(c.Topic)
mc.SetRawRedisClient(rdb)
return &ConversationRedisCache{ return &ConversationRedisCache{
rcClient: rcClient, rcClient: rcClient,
metaCache: NewMetaCacheRedis(rcClient), metaCache: mc,
conversationDB: db, conversationDB: db,
expireTime: conversationExpireTime, expireTime: conversationExpireTime,
} }
@@ -115,38 +122,42 @@ type ConversationRedisCache struct {
func (c *ConversationRedisCache) NewCache() ConversationCache { func (c *ConversationRedisCache) NewCache() ConversationCache {
return &ConversationRedisCache{ return &ConversationRedisCache{
rcClient: c.rcClient, rcClient: c.rcClient,
metaCache: NewMetaCacheRedis(c.rcClient, c.metaCache.GetPreDelKeys()...), metaCache: c.Copy(),
conversationDB: c.conversationDB, conversationDB: c.conversationDB,
expireTime: c.expireTime, expireTime: c.expireTime,
} }
} }
func (c *ConversationRedisCache) getConversationKey(ownerUserID, conversationID string) string { func (c *ConversationRedisCache) getConversationKey(ownerUserID, conversationID string) string {
return conversationKey + ownerUserID + ":" + conversationID return cachekey.GetConversationKey(ownerUserID, conversationID)
} }
func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) string { func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) string {
return conversationIDsKey + ownerUserID return cachekey.GetConversationIDsKey(ownerUserID)
} }
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string { func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string {
return superGroupRecvMsgNotNotifyUserIDsKey + groupID return cachekey.GetSuperGroupRecvNotNotifyUserIDsKey(groupID)
} }
func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, conversationID string) string { func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, conversationID string) string {
return recvMsgOptKey + ownerUserID + ":" + conversationID return cachekey.GetRecvMsgOptKey(ownerUserID, conversationID)
} }
func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string { func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string {
return superGroupRecvMsgNotNotifyUserIDsHashKey + groupID return cachekey.GetSuperGroupRecvNotNotifyUserIDsHashKey(groupID)
} }
func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUserID, conversationID string) string { func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUserID, conversationID string) string {
return conversationHasReadSeqKey + ownerUserID + ":" + conversationID return cachekey.GetConversationHasReadSeqKey(ownerUserID, conversationID)
} }
func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conversationID string) string { func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conversationID string) string {
return conversationNotReceiveMessageUserIDsKey + conversationID return cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID)
}
func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUserID string) string {
return cachekey.GetUserConversationIDsHashKey(ownerUserID)
} }
func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) {
@@ -166,10 +177,6 @@ func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) Conversat
return cache return cache
} }
func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUserID string) string {
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( return getCache(
ctx, ctx,
+17 -9
View File
@@ -18,17 +18,20 @@ import (
"context" "context"
"time" "time"
"github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
const ( const (
friendExpireTime = time.Second * 60 * 60 * 12 friendExpireTime = time.Second * 60 * 60 * 12
friendIDsKey = "FRIEND_IDS:" //friendIDsKey = "FRIEND_IDS:"
TwoWayFriendsIDsKey = "COMMON_FRIENDS_IDS:" //TwoWayFriendsIDsKey = "COMMON_FRIENDS_IDS:"
friendKey = "FRIEND_INFO:" //friendKey = "FRIEND_INFO:".
) )
// FriendCache is an interface for caching friend-related data. // FriendCache is an interface for caching friend-related data.
@@ -58,8 +61,13 @@ type FriendCacheRedis struct {
func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface, func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendModelInterface,
options rockscache.Options) FriendCache { options rockscache.Options) FriendCache {
rcClient := rockscache.NewClient(rdb, options) rcClient := rockscache.NewClient(rdb, options)
mc := NewMetaCacheRedis(rcClient)
f := config.Config.LocalCache.Friend
log.ZDebug(context.Background(), "friend local cache init", "Topic", f.Topic, "SlotNum", f.SlotNum, "SlotSize", f.SlotSize, "enable", f.Enable())
mc.SetTopic(f.Topic)
mc.SetRawRedisClient(rdb)
return &FriendCacheRedis{ return &FriendCacheRedis{
metaCache: NewMetaCacheRedis(rcClient), metaCache: mc,
friendDB: friendDB, friendDB: friendDB,
expireTime: friendExpireTime, expireTime: friendExpireTime,
rcClient: rcClient, rcClient: rcClient,
@@ -70,7 +78,7 @@ func NewFriendCacheRedis(rdb redis.UniversalClient, friendDB relationtb.FriendMo
func (f *FriendCacheRedis) NewCache() FriendCache { func (f *FriendCacheRedis) NewCache() FriendCache {
return &FriendCacheRedis{ return &FriendCacheRedis{
rcClient: f.rcClient, rcClient: f.rcClient,
metaCache: NewMetaCacheRedis(f.rcClient, f.metaCache.GetPreDelKeys()...), metaCache: f.Copy(),
friendDB: f.friendDB, friendDB: f.friendDB,
expireTime: f.expireTime, expireTime: f.expireTime,
} }
@@ -78,17 +86,17 @@ func (f *FriendCacheRedis) NewCache() FriendCache {
// getFriendIDsKey returns the key for storing friend IDs in the cache. // getFriendIDsKey returns the key for storing friend IDs in the cache.
func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string { func (f *FriendCacheRedis) getFriendIDsKey(ownerUserID string) string {
return friendIDsKey + ownerUserID return cachekey.GetFriendIDsKey(ownerUserID)
} }
// getTwoWayFriendsIDsKey returns the key for storing two-way friend IDs in the cache. // getTwoWayFriendsIDsKey returns the key for storing two-way friend IDs in the cache.
func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) string { func (f *FriendCacheRedis) getTwoWayFriendsIDsKey(ownerUserID string) string {
return TwoWayFriendsIDsKey + ownerUserID return cachekey.GetTwoWayFriendsIDsKey(ownerUserID)
} }
// getFriendKey returns the key for storing friend info in the cache. // getFriendKey returns the key for storing friend info in the cache.
func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string { func (f *FriendCacheRedis) getFriendKey(ownerUserID, friendUserID string) string {
return friendKey + ownerUserID + "-" + friendUserID return cachekey.GetFriendKey(ownerUserID, friendUserID)
} }
// GetFriendIDs retrieves friend IDs from the cache or the database if not found. // GetFriendIDs retrieves friend IDs from the cache or the database if not found.
+24 -20
View File
@@ -17,7 +17,6 @@ package cache
import ( import (
"context" "context"
"fmt" "fmt"
"strconv"
"time" "time"
"github.com/OpenIMSDK/protocol/constant" "github.com/OpenIMSDK/protocol/constant"
@@ -25,20 +24,21 @@ import (
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
const ( const (
groupExpireTime = time.Second * 60 * 60 * 12 groupExpireTime = time.Second * 60 * 60 * 12
groupInfoKey = "GROUP_INFO:" //groupInfoKey = "GROUP_INFO:"
groupMemberIDsKey = "GROUP_MEMBER_IDS:" //groupMemberIDsKey = "GROUP_MEMBER_IDS:"
groupMembersHashKey = "GROUP_MEMBERS_HASH2:" //groupMembersHashKey = "GROUP_MEMBERS_HASH2:"
groupMemberInfoKey = "GROUP_MEMBER_INFO:" //groupMemberInfoKey = "GROUP_MEMBER_INFO:"
//groupOwnerInfoKey = "GROUP_OWNER_INFO:". //joinedGroupsKey = "JOIN_GROUPS_KEY:"
joinedGroupsKey = "JOIN_GROUPS_KEY:" //groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:"
groupMemberNumKey = "GROUP_MEMBER_NUM_CACHE:" //groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:".
groupRoleLevelMemberIDsKey = "GROUP_ROLE_LEVEL_MEMBER_IDS:"
) )
type GroupHash interface { type GroupHash interface {
@@ -101,12 +101,16 @@ func NewGroupCacheRedis(
opts rockscache.Options, opts rockscache.Options,
) GroupCache { ) GroupCache {
rcClient := rockscache.NewClient(rdb, opts) rcClient := rockscache.NewClient(rdb, opts)
mc := NewMetaCacheRedis(rcClient)
g := config.Config.LocalCache.Group
mc.SetTopic(g.Topic)
log.ZDebug(context.Background(), "group local cache init", "Topic", g.Topic, "SlotNum", g.SlotNum, "SlotSize", g.SlotSize, "enable", g.Enable())
mc.SetRawRedisClient(rdb)
return &GroupCacheRedis{ return &GroupCacheRedis{
rcClient: rcClient, expireTime: groupExpireTime, rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
groupHash: hashCode, groupHash: hashCode,
metaCache: NewMetaCacheRedis(rcClient), metaCache: mc,
} }
} }
@@ -117,36 +121,36 @@ func (g *GroupCacheRedis) NewCache() GroupCache {
groupDB: g.groupDB, groupDB: g.groupDB,
groupMemberDB: g.groupMemberDB, groupMemberDB: g.groupMemberDB,
groupRequestDB: g.groupRequestDB, groupRequestDB: g.groupRequestDB,
metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...), metaCache: g.Copy(),
} }
} }
func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string { func (g *GroupCacheRedis) getGroupInfoKey(groupID string) string {
return groupInfoKey + groupID return cachekey.GetGroupInfoKey(groupID)
} }
func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string { func (g *GroupCacheRedis) getJoinedGroupsKey(userID string) string {
return joinedGroupsKey + userID return cachekey.GetJoinedGroupsKey(userID)
} }
func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string { func (g *GroupCacheRedis) getGroupMembersHashKey(groupID string) string {
return groupMembersHashKey + groupID return cachekey.GetGroupMembersHashKey(groupID)
} }
func (g *GroupCacheRedis) getGroupMemberIDsKey(groupID string) string { func (g *GroupCacheRedis) getGroupMemberIDsKey(groupID string) string {
return groupMemberIDsKey + groupID return cachekey.GetGroupMemberIDsKey(groupID)
} }
func (g *GroupCacheRedis) getGroupMemberInfoKey(groupID, userID string) string { func (g *GroupCacheRedis) getGroupMemberInfoKey(groupID, userID string) string {
return groupMemberInfoKey + groupID + "-" + userID return cachekey.GetGroupMemberInfoKey(groupID, userID)
} }
func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string { func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
return groupMemberNumKey + groupID return cachekey.GetGroupMemberNumKey(groupID)
} }
func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string { func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLevel int32) string {
return groupRoleLevelMemberIDsKey + groupID + "-" + strconv.Itoa(int(roleLevel)) return cachekey.GetGroupRoleLevelMemberIDsKey(groupID, roleLevel)
} }
func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) { func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) {
+41 -24
View File
@@ -26,6 +26,7 @@ import (
"github.com/OpenIMSDK/tools/mw/specialerror" "github.com/OpenIMSDK/tools/mw/specialerror"
"github.com/OpenIMSDK/tools/utils" "github.com/OpenIMSDK/tools/utils"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/redis/go-redis/v9"
) )
const ( const (
@@ -43,6 +44,9 @@ type metaCache interface {
AddKeys(keys ...string) AddKeys(keys ...string)
ClearKeys() ClearKeys()
GetPreDelKeys() []string GetPreDelKeys() []string
SetTopic(topic string)
SetRawRedisClient(cli redis.UniversalClient)
Copy() metaCache
} }
func NewMetaCacheRedis(rcClient *rockscache.Client, keys ...string) metaCache { func NewMetaCacheRedis(rcClient *rockscache.Client, keys ...string) metaCache {
@@ -50,10 +54,36 @@ func NewMetaCacheRedis(rcClient *rockscache.Client, keys ...string) metaCache {
} }
type metaCacheRedis struct { type metaCacheRedis struct {
topic string
rcClient *rockscache.Client rcClient *rockscache.Client
keys []string keys []string
maxRetryTimes int maxRetryTimes int
retryInterval time.Duration retryInterval time.Duration
redisClient redis.UniversalClient
}
func (m *metaCacheRedis) Copy() metaCache {
var keys []string
if len(m.keys) > 0 {
keys = make([]string, 0, len(m.keys)*2)
keys = append(keys, m.keys...)
}
return &metaCacheRedis{
topic: m.topic,
rcClient: m.rcClient,
keys: keys,
maxRetryTimes: m.maxRetryTimes,
retryInterval: m.retryInterval,
redisClient: redisClient,
}
}
func (m *metaCacheRedis) SetTopic(topic string) {
m.topic = topic
}
func (m *metaCacheRedis) SetRawRedisClient(cli redis.UniversalClient) {
m.redisClient = cli
} }
func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error { func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error {
@@ -61,7 +91,7 @@ func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error {
m.keys = utils.Distinct(m.keys) m.keys = utils.Distinct(m.keys)
} }
if len(m.keys) > 0 { if len(m.keys) > 0 {
log.ZDebug(ctx, "delete cache", "keys", m.keys) log.ZDebug(ctx, "delete cache", "topic", m.topic, "keys", m.keys)
for _, key := range m.keys { for _, key := range m.keys {
for i := 0; i < m.maxRetryTimes; i++ { for i := 0; i < m.maxRetryTimes; i++ {
if err := m.rcClient.TagAsDeleted(key); err != nil { if err := m.rcClient.TagAsDeleted(key); err != nil {
@@ -71,31 +101,18 @@ func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error {
} }
break break
} }
}
//retryTimes := 0 if pk := getPublishKey(m.topic, m.keys); len(pk) > 0 {
//for { data, err := json.Marshal(pk)
// m.rcClient.TagAsDeleted() if err != nil {
// if err := m.rcClient.TagAsDeletedBatch2(ctx, []string{key}); err != nil { log.ZError(ctx, "keys json marshal failed", err, "topic", m.topic, "keys", pk)
// if retryTimes >= m.maxRetryTimes { } else {
// err = errs.ErrInternalServer.Wrap( if err := m.redisClient.Publish(ctx, m.topic, string(data)).Err(); err != nil {
// fmt.Sprintf( log.ZError(ctx, "redis publish cache delete error", err, "topic", m.topic, "keys", pk)
// "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 return nil
} }
+10 -10
View File
@@ -38,12 +38,12 @@ const (
conversationUserMinSeq = "CON_USER_MIN_SEQ:" conversationUserMinSeq = "CON_USER_MIN_SEQ:"
hasReadSeq = "HAS_READ_SEQ:" hasReadSeq = "HAS_READ_SEQ:"
appleDeviceToken = "DEVICE_TOKEN" //appleDeviceToken = "DEVICE_TOKEN".
getuiToken = "GETUI_TOKEN" getuiToken = "GETUI_TOKEN"
getuiTaskID = "GETUI_TASK_ID" getuiTaskID = "GETUI_TASK_ID"
signalCache = "SIGNAL_CACHE:" //signalCache = "SIGNAL_CACHE:"
signalListCache = "SIGNAL_LIST_CACHE:" //signalListCache = "SIGNAL_LIST_CACHE:".
FCM_TOKEN = "FCM_TOKEN:" FCM_TOKEN = "FCM_TOKEN:"
messageCache = "MESSAGE_CACHE:" messageCache = "MESSAGE_CACHE:"
messageDelUserList = "MESSAGE_DEL_USER_LIST:" messageDelUserList = "MESSAGE_DEL_USER_LIST:"
@@ -143,6 +143,10 @@ func (c *msgCache) getHasReadSeqKey(conversationID string, userID string) string
return hasReadSeq + userID + ":" + conversationID return hasReadSeq + userID + ":" + conversationID
} }
func (c *msgCache) getConversationUserMinSeqKey(conversationID, userID string) string {
return conversationUserMinSeq + conversationID + "u:" + userID
}
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 errs.Wrap(c.rdb.Set(ctx, getkey(conversationID), seq, 0).Err()) return errs.Wrap(c.rdb.Set(ctx, getkey(conversationID), seq, 0).Err())
} }
@@ -208,10 +212,6 @@ func (c *msgCache) GetMinSeq(ctx context.Context, conversationID string) (int64,
return c.getSeq(ctx, conversationID, c.getMinSeqKey) return c.getSeq(ctx, conversationID, c.getMinSeqKey)
} }
func (c *msgCache) getConversationUserMinSeqKey(conversationID, userID string) string {
return conversationUserMinSeq + conversationID + "u:" + userID
}
func (c *msgCache) GetConversationUserMinSeq(ctx context.Context, conversationID string, userID string) (int64, error) { func (c *msgCache) GetConversationUserMinSeq(ctx context.Context, conversationID string, userID string) (int64, error) {
val, err := c.rdb.Get(ctx, c.getConversationUserMinSeqKey(conversationID, userID)).Int64() val, err := c.rdb.Get(ctx, c.getConversationUserMinSeqKey(conversationID, userID)).Int64()
if err != nil { if err != nil {
+13 -8
View File
@@ -27,13 +27,15 @@ import (
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/log" "github.com/OpenIMSDK/tools/log"
"github.com/dtm-labs/rockscache" "github.com/dtm-labs/rockscache"
"github.com/openimsdk/open-im-server/v3/pkg/common/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
const ( const (
userExpireTime = time.Second * 60 * 60 * 12 userExpireTime = time.Second * 60 * 60 * 12
userInfoKey = "USER_INFO:" //userInfoKey = "USER_INFO:".
userGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:" userGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:"
olineStatusKey = "ONLINE_STATUS:" olineStatusKey = "ONLINE_STATUS:"
userOlineStatusExpireTime = time.Second * 60 * 60 * 24 userOlineStatusExpireTime = time.Second * 60 * 60 * 24
@@ -68,7 +70,11 @@ func NewUserCacheRedis(
options rockscache.Options, options rockscache.Options,
) UserCache { ) UserCache {
rcClient := rockscache.NewClient(rdb, options) rcClient := rockscache.NewClient(rdb, options)
mc := NewMetaCacheRedis(rcClient)
u := config.Config.LocalCache.User
log.ZDebug(context.Background(), "user local cache init", "Topic", u.Topic, "SlotNum", u.SlotNum, "SlotSize", u.SlotSize, "enable", u.Enable())
mc.SetTopic(u.Topic)
mc.SetRawRedisClient(rdb)
return &UserCacheRedis{ return &UserCacheRedis{
rdb: rdb, rdb: rdb,
metaCache: NewMetaCacheRedis(rcClient), metaCache: NewMetaCacheRedis(rcClient),
@@ -81,7 +87,7 @@ func NewUserCacheRedis(
func (u *UserCacheRedis) NewCache() UserCache { func (u *UserCacheRedis) NewCache() UserCache {
return &UserCacheRedis{ return &UserCacheRedis{
rdb: u.rdb, rdb: u.rdb,
metaCache: NewMetaCacheRedis(u.rcClient, u.metaCache.GetPreDelKeys()...), metaCache: u.Copy(),
userDB: u.userDB, userDB: u.userDB,
expireTime: u.expireTime, expireTime: u.expireTime,
rcClient: u.rcClient, rcClient: u.rcClient,
@@ -89,18 +95,17 @@ func (u *UserCacheRedis) NewCache() UserCache {
} }
func (u *UserCacheRedis) getUserInfoKey(userID string) string { func (u *UserCacheRedis) getUserInfoKey(userID string) string {
return userInfoKey + userID return cachekey.GetUserInfoKey(userID)
} }
func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string { func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string {
return userGlobalRecvMsgOptKey + userID return cachekey.GetUserGlobalRecvMsgOptKey(userID)
} }
func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) { func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) {
return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) { return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) {
return u.userDB.Take(ctx, userID) return u.userDB.Take(ctx, userID)
}, })
)
} }
func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) { func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) {
-86
View File
@@ -1,86 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache
import (
"context"
"sync"
"github.com/OpenIMSDK/protocol/conversation"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
)
type ConversationLocalCache struct {
lock sync.Mutex
superGroupRecvMsgNotNotifyUserIDs map[string]Hash
conversationIDs map[string]Hash
client *rpcclient.ConversationRpcClient
}
type Hash struct {
hash uint64
ids []string
}
func NewConversationLocalCache(client *rpcclient.ConversationRpcClient) *ConversationLocalCache {
return &ConversationLocalCache{
superGroupRecvMsgNotNotifyUserIDs: make(map[string]Hash),
conversationIDs: make(map[string]Hash),
client: client,
}
}
func (g *ConversationLocalCache) GetRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) {
resp, err := g.client.Client.GetRecvMsgNotNotifyUserIDs(ctx, &conversation.GetRecvMsgNotNotifyUserIDsReq{
GroupID: groupID,
})
if err != nil {
return nil, err
}
return resp.UserIDs, nil
}
func (g *ConversationLocalCache) GetConversationIDs(ctx context.Context, userID string) ([]string, error) {
resp, err := g.client.Client.GetUserConversationIDsHash(ctx, &conversation.GetUserConversationIDsHashReq{
OwnerUserID: userID,
})
if err != nil {
return nil, err
}
g.lock.Lock()
hash, ok := g.conversationIDs[userID]
g.lock.Unlock()
if !ok || hash.hash != resp.Hash {
conversationIDsResp, err := g.client.Client.GetConversationIDs(ctx, &conversation.GetConversationIDsReq{
UserID: userID,
})
if err != nil {
return nil, err
}
g.lock.Lock()
defer g.lock.Unlock()
g.conversationIDs[userID] = Hash{
hash: resp.Hash,
ids: conversationIDsResp.ConversationIDs,
}
return conversationIDsResp.ConversationIDs, nil
}
return hash.ids, nil
}
-15
View File
@@ -1,15 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
-77
View File
@@ -1,77 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache
import (
"context"
"sync"
"github.com/OpenIMSDK/protocol/group"
"github.com/OpenIMSDK/tools/errs"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
)
type GroupLocalCache struct {
lock sync.Mutex
cache map[string]GroupMemberIDsHash
client *rpcclient.GroupRpcClient
}
type GroupMemberIDsHash struct {
memberListHash uint64
userIDs []string
}
func NewGroupLocalCache(client *rpcclient.GroupRpcClient) *GroupLocalCache {
return &GroupLocalCache{
cache: make(map[string]GroupMemberIDsHash, 0),
client: client,
}
}
func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string) ([]string, error) {
resp, err := g.client.Client.GetGroupAbstractInfo(ctx, &group.GetGroupAbstractInfoReq{
GroupIDs: []string{groupID},
})
if err != nil {
return nil, err
}
if len(resp.GroupAbstractInfos) < 1 {
return nil, errs.ErrGroupIDNotFound
}
g.lock.Lock()
localHashInfo, ok := g.cache[groupID]
if ok && localHashInfo.memberListHash == resp.GroupAbstractInfos[0].GroupMemberListHash {
g.lock.Unlock()
return localHashInfo.userIDs, nil
}
g.lock.Unlock()
groupMembersResp, err := g.client.Client.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{
GroupID: groupID,
})
if err != nil {
return nil, err
}
g.lock.Lock()
defer g.lock.Unlock()
g.cache[groupID] = GroupMemberIDsHash{
memberListHash: resp.GroupAbstractInfos[0].GroupMemberListHash,
userIDs: groupMembersResp.UserIDs,
}
return g.cache[groupID].userIDs, nil
}
+8 -2
View File
@@ -96,8 +96,14 @@ func (c *ConversationMgo) FindUserIDAllConversations(ctx context.Context, userID
return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID}) return mgoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID})
} }
func (c *ConversationMgo) FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) { func (c *ConversationMgo) FindRecvMsgUserIDs(ctx context.Context, conversationID string, recvOpts []int) ([]string, error) {
return mgoutil.Find[string](ctx, c.coll, bson.M{"group_id": groupID, "recv_msg_opt": constant.ReceiveNotNotifyMessage}, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1})) var filter any
if len(recvOpts) == 0 {
filter = bson.M{"conversation_id": conversationID}
} else {
filter = bson.M{"conversation_id": conversationID, "recv_msg_opt": bson.M{"$in": recvOpts}}
}
return mgoutil.Find[string](ctx, c.coll, filter, options.Find().SetProjection(bson.M{"_id": 0, "owner_user_id": 1}))
} }
func (c *ConversationMgo) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) { func (c *ConversationMgo) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) {
+7 -1
View File
@@ -18,6 +18,7 @@ import (
"context" "context"
"time" "time"
"github.com/OpenIMSDK/protocol/constant"
"github.com/OpenIMSDK/tools/errs" "github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/mgoutil" "github.com/OpenIMSDK/tools/mgoutil"
"github.com/OpenIMSDK/tools/pagination" "github.com/OpenIMSDK/tools/pagination"
@@ -69,7 +70,12 @@ func (g *GroupMgo) Take(ctx context.Context, groupID string) (group *relation.Gr
} }
func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*relation.GroupModel, err error) { func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*relation.GroupModel, err error) {
return mgoutil.FindPage[*relation.GroupModel](ctx, g.coll, bson.M{"group_name": bson.M{"$regex": keyword}}, pagination) opts := options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}})
return mgoutil.FindPage[*relation.GroupModel](ctx, g.coll, bson.M{
"group_name": bson.M{"$regex": keyword},
"status": bson.M{"$ne": constant.GroupStatusDismissed},
}, pagination, opts)
} }
func (g *GroupMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { func (g *GroupMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {
+1 -1
View File
@@ -53,7 +53,7 @@ type ConversationModelInterface interface {
Take(ctx context.Context, userID, conversationID string) (conversation *ConversationModel, err error) Take(ctx context.Context, userID, conversationID string) (conversation *ConversationModel, err error)
FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error)
FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error) FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error)
FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) FindRecvMsgUserIDs(ctx context.Context, conversationID string, recvOpts []int) ([]string, error)
GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error)
GetAllConversationIDs(ctx context.Context) ([]string, error) GetAllConversationIDs(ctx context.Context) ([]string, error)
GetAllConversationIDsNumber(ctx context.Context) (int64, error) GetAllConversationIDsNumber(ctx context.Context) (int64, error)
+2 -2
View File
@@ -1063,8 +1063,8 @@ func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessa
// Changed to keyed fields for bson.M to avoid govet errors // Changed to keyed fields for bson.M to avoid govet errors
condition = append(condition, bson.M{"$eq": bson.A{bson.M{"$dateToString": bson.M{"format": "%Y-%m-%d", "date": bson.M{"$toDate": "$$item.msg.send_time"}}}, req.SendTime}}) condition = append(condition, bson.M{"$eq": bson.A{bson.M{"$dateToString": bson.M{"format": "%Y-%m-%d", "date": bson.M{"$toDate": "$$item.msg.send_time"}}}, req.SendTime}})
} }
if req.MsgType != 0 { if req.ContentType != 0 {
condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.content_type", req.MsgType}}) condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.content_type", req.ContentType}})
} }
if req.SessionType != 0 { if req.SessionType != 0 {
condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.session_type", req.SessionType}}) condition = append(condition, bson.M{"$eq": bson.A{"$$item.msg.session_type", req.SessionType}})
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM open source community. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -12,18 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package admin package redispubsub
import ( import "github.com/redis/go-redis/v9"
"time"
)
// RegisterAddGroup Indicates the default group for registration. type Publisher struct {
type RegisterAddGroup struct { client redis.UniversalClient
GroupID string `gorm:"column:group_id;primary_key;type:char(64)"` channel string
CreateTime time.Time `gorm:"column:create_time"`
} }
func (RegisterAddGroup) TableName() string { func NewPublisher(client redis.UniversalClient, channel string) *Publisher {
return "register_add_groups" return &Publisher{client: client, channel: channel}
}
func (p *Publisher) Publish(message string) error {
return p.client.Publish(ctx, p.channel, message).Err()
} }
@@ -12,38 +12,38 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package config package redispubsub
import ( import (
"flag" "context"
"log"
"os"
"gopkg.in/yaml.v2" "github.com/redis/go-redis/v9"
) )
type Config struct { var ctx = context.Background()
Directory string `yaml:"directory"`
FileTypes []string `yaml:"file_types"` type Subscriber struct {
Languages []string `yaml:"languages"` client redis.UniversalClient
channel string
} }
func ParseConfig() (Config, error) { func NewSubscriber(client redis.UniversalClient, channel string) *Subscriber {
var configPath string return &Subscriber{client: client, channel: channel}
flag.StringVar(&configPath, "config", "./", "Path to config file") }
flag.Parse()
func (s *Subscriber) OnMessage(ctx context.Context, callback func(string)) error {
var config Config messageChannel := s.client.Subscribe(ctx, s.channel).Channel()
if configPath != "" {
configFile, err := os.ReadFile(configPath) go func() {
if err != nil { for {
return Config{}, err select {
} case <-ctx.Done():
if err := yaml.Unmarshal(configFile, &config); err != nil { return
return Config{}, err case msg := <-messageChannel:
} callback(msg.Payload)
} else { }
log.Fatal("Config file must be provided") }
} }()
return config, nil
return nil
} }
+127
View File
@@ -0,0 +1,127 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache
import (
"context"
"hash/fnv"
"unsafe"
"github.com/openimsdk/localcache/link"
"github.com/openimsdk/localcache/lru"
)
type Cache[V any] interface {
Get(ctx context.Context, key string, fetch func(ctx context.Context) (V, error)) (V, error)
GetLink(ctx context.Context, key string, fetch func(ctx context.Context) (V, error), link ...string) (V, error)
Del(ctx context.Context, key ...string)
DelLocal(ctx context.Context, key ...string)
Stop()
}
func New[V any](opts ...Option) Cache[V] {
opt := defaultOption()
for _, o := range opts {
o(opt)
}
c := cache[V]{opt: opt}
if opt.localSlotNum > 0 && opt.localSlotSize > 0 {
createSimpleLRU := func() lru.LRU[string, V] {
if opt.expirationEvict {
return lru.NewExpirationLRU[string, V](opt.localSlotSize, opt.localSuccessTTL, opt.localFailedTTL, opt.target, c.onEvict)
} else {
return lru.NewLayLRU[string, V](opt.localSlotSize, opt.localSuccessTTL, opt.localFailedTTL, opt.target, c.onEvict)
}
}
if opt.localSlotNum == 1 {
c.local = createSimpleLRU()
} else {
c.local = lru.NewSlotLRU[string, V](opt.localSlotNum, func(key string) uint64 {
h := fnv.New64a()
h.Write(*(*[]byte)(unsafe.Pointer(&key)))
return h.Sum64()
}, createSimpleLRU)
}
if opt.linkSlotNum > 0 {
c.link = link.New(opt.linkSlotNum)
}
}
return &c
}
type cache[V any] struct {
opt *option
link link.Link
local lru.LRU[string, V]
}
func (c *cache[V]) onEvict(key string, value V) {
if c.link != nil {
lks := c.link.Del(key)
for k := range lks {
if key != k { // prevent deadlock
c.local.Del(k)
}
}
}
}
func (c *cache[V]) del(key ...string) {
if c.local == nil {
return
}
for _, k := range key {
c.local.Del(k)
if c.link != nil {
lks := c.link.Del(k)
for k := range lks {
c.local.Del(k)
}
}
}
}
func (c *cache[V]) Get(ctx context.Context, key string, fetch func(ctx context.Context) (V, error)) (V, error) {
return c.GetLink(ctx, key, fetch)
}
func (c *cache[V]) GetLink(ctx context.Context, key string, fetch func(ctx context.Context) (V, error), link ...string) (V, error) {
if c.local != nil {
return c.local.Get(key, func() (V, error) {
if len(link) > 0 {
c.link.Link(key, link...)
}
return fetch(ctx)
})
} else {
return fetch(ctx)
}
}
func (c *cache[V]) Del(ctx context.Context, key ...string) {
for _, fn := range c.opt.delFn {
fn(ctx, key...)
}
c.del(key...)
}
func (c *cache[V]) DelLocal(ctx context.Context, key ...string) {
c.del(key...)
}
func (c *cache[V]) Stop() {
c.local.Stop()
}
+93
View File
@@ -0,0 +1,93 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache
import (
"context"
"fmt"
"math/rand"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestName(t *testing.T) {
c := New[string](WithExpirationEvict())
//c := New[string]()
ctx := context.Background()
const (
num = 10000
tNum = 10000
kNum = 100000
pNum = 100
)
getKey := func(v uint64) string {
return fmt.Sprintf("key_%d", v%kNum)
}
start := time.Now()
t.Log("start", start)
var (
get atomic.Int64
del atomic.Int64
)
incrGet := func() {
if v := get.Add(1); v%pNum == 0 {
//t.Log("#get count", v/pNum)
}
}
incrDel := func() {
if v := del.Add(1); v%pNum == 0 {
//t.Log("@del count", v/pNum)
}
}
var wg sync.WaitGroup
for i := 0; i < tNum; i++ {
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < num; i++ {
c.Get(ctx, getKey(rand.Uint64()), func(ctx context.Context) (string, error) {
return fmt.Sprintf("index_%d", i), nil
})
incrGet()
}
}()
go func() {
defer wg.Done()
time.Sleep(time.Second / 10)
for i := 0; i < num; i++ {
c.Del(ctx, getKey(rand.Uint64()))
incrDel()
}
}()
}
wg.Wait()
end := time.Now()
t.Log("end", end)
t.Log("time", end.Sub(start))
t.Log("get", get.Load())
t.Log("del", del.Load())
// 137.35s
}
+5
View File
@@ -0,0 +1,5 @@
module github.com/openimsdk/localcache
go 1.19
require github.com/hashicorp/golang-lru/v2 v2.0.7
+123
View File
@@ -0,0 +1,123 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package link
import (
"hash/fnv"
"sync"
"unsafe"
)
type Link interface {
Link(key string, link ...string)
Del(key string) map[string]struct{}
}
func newLinkKey() *linkKey {
return &linkKey{
data: make(map[string]map[string]struct{}),
}
}
type linkKey struct {
lock sync.Mutex
data map[string]map[string]struct{}
}
func (x *linkKey) link(key string, link ...string) {
x.lock.Lock()
defer x.lock.Unlock()
v, ok := x.data[key]
if !ok {
v = make(map[string]struct{})
x.data[key] = v
}
for _, k := range link {
v[k] = struct{}{}
}
}
func (x *linkKey) del(key string) map[string]struct{} {
x.lock.Lock()
defer x.lock.Unlock()
ks, ok := x.data[key]
if !ok {
return nil
}
delete(x.data, key)
return ks
}
func New(n int) Link {
if n <= 0 {
panic("must be greater than 0")
}
slots := make([]*linkKey, n)
for i := 0; i < len(slots); i++ {
slots[i] = newLinkKey()
}
return &slot{
n: uint64(n),
slots: slots,
}
}
type slot struct {
n uint64
slots []*linkKey
}
func (x *slot) index(s string) uint64 {
h := fnv.New64a()
_, _ = h.Write(*(*[]byte)(unsafe.Pointer(&s)))
return h.Sum64() % x.n
}
func (x *slot) Link(key string, link ...string) {
if len(link) == 0 {
return
}
mk := key
lks := make([]string, len(link))
for i, k := range link {
lks[i] = k
}
x.slots[x.index(mk)].link(mk, lks...)
for _, lk := range lks {
x.slots[x.index(lk)].link(lk, mk)
}
}
func (x *slot) Del(key string) map[string]struct{} {
return x.delKey(key)
}
func (x *slot) delKey(k string) map[string]struct{} {
del := make(map[string]struct{})
stack := []string{k}
for len(stack) > 0 {
curr := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if _, ok := del[curr]; ok {
continue
}
del[curr] = struct{}{}
childKeys := x.slots[x.index(curr)].del(curr)
for ck := range childKeys {
stack = append(stack, ck)
}
}
return del
}
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -12,17 +12,23 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package utils package link
import "time" import (
"testing"
)
func TestName(t *testing.T) {
v := New(1)
//v.Link("a:1", "b:1", "c:1", "d:1")
v.Link("a:1", "b:1", "c:1")
v.Link("z:1", "b:1")
//v.DelKey("a:1")
v.Del("z:1")
t.Log(v)
func InitTime(ts ...*time.Time) {
for i := range ts {
if ts[i] == nil {
continue
}
if ts[i].IsZero() || ts[i].UnixMicro() < 0 {
*ts[i] = time.UnixMicro(0)
}
}
} }
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -12,25 +12,23 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package relation package lru
import ( import "github.com/hashicorp/golang-lru/v2/simplelru"
"gorm.io/gorm"
"github.com/OpenIMSDK/tools/utils" type EvictCallback[K comparable, V any] simplelru.EvictCallback[K, V]
)
type BatchUpdateGroupMember struct { type LRU[K comparable, V any] interface {
GroupID string Get(key K, fetch func() (V, error)) (V, error)
UserID string Del(key K) bool
Map map[string]any Stop()
} }
type GroupSimpleUserID struct { type Target interface {
Hash uint64 IncrGetHit()
MemberNum uint32 IncrGetSuccess()
} IncrGetFailed()
func IsNotFound(err error) bool { IncrDelHit()
return utils.Unwrap(err) == gorm.ErrRecordNotFound IncrDelNotFound()
} }
+93
View File
@@ -0,0 +1,93 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package lru
import (
"sync"
"time"
"github.com/hashicorp/golang-lru/v2/expirable"
)
func NewExpirationLRU[K comparable, V any](size int, successTTL, failedTTL time.Duration, target Target, onEvict EvictCallback[K, V]) LRU[K, V] {
var cb expirable.EvictCallback[K, *expirationLruItem[V]]
if onEvict != nil {
cb = func(key K, value *expirationLruItem[V]) {
onEvict(key, value.value)
}
}
core := expirable.NewLRU[K, *expirationLruItem[V]](size, cb, successTTL)
return &ExpirationLRU[K, V]{
core: core,
successTTL: successTTL,
failedTTL: failedTTL,
target: target,
}
}
type expirationLruItem[V any] struct {
lock sync.RWMutex
err error
value V
}
type ExpirationLRU[K comparable, V any] struct {
lock sync.Mutex
core *expirable.LRU[K, *expirationLruItem[V]]
successTTL time.Duration
failedTTL time.Duration
target Target
}
func (x *ExpirationLRU[K, V]) Get(key K, fetch func() (V, error)) (V, error) {
x.lock.Lock()
v, ok := x.core.Get(key)
if ok {
x.lock.Unlock()
x.target.IncrGetSuccess()
v.lock.RLock()
defer v.lock.RUnlock()
return v.value, v.err
} else {
v = &expirationLruItem[V]{}
x.core.Add(key, v)
v.lock.Lock()
x.lock.Unlock()
defer v.lock.Unlock()
v.value, v.err = fetch()
if v.err == nil {
x.target.IncrGetSuccess()
} else {
x.target.IncrGetFailed()
x.core.Remove(key)
}
return v.value, v.err
}
}
func (x *ExpirationLRU[K, V]) Del(key K) bool {
x.lock.Lock()
ok := x.core.Remove(key)
x.lock.Unlock()
if ok {
x.target.IncrDelHit()
} else {
x.target.IncrDelNotFound()
}
return ok
}
func (x *ExpirationLRU[K, V]) Stop() {
}
+105
View File
@@ -0,0 +1,105 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package lru
import (
"sync"
"time"
"github.com/hashicorp/golang-lru/v2/simplelru"
)
type layLruItem[V any] struct {
lock sync.Mutex
expires int64
err error
value V
}
func NewLayLRU[K comparable, V any](size int, successTTL, failedTTL time.Duration, target Target, onEvict EvictCallback[K, V]) *LayLRU[K, V] {
var cb simplelru.EvictCallback[K, *layLruItem[V]]
if onEvict != nil {
cb = func(key K, value *layLruItem[V]) {
onEvict(key, value.value)
}
}
core, err := simplelru.NewLRU[K, *layLruItem[V]](size, cb)
if err != nil {
panic(err)
}
return &LayLRU[K, V]{
core: core,
successTTL: successTTL,
failedTTL: failedTTL,
target: target,
}
}
type LayLRU[K comparable, V any] struct {
lock sync.Mutex
core *simplelru.LRU[K, *layLruItem[V]]
successTTL time.Duration
failedTTL time.Duration
target Target
}
func (x *LayLRU[K, V]) Get(key K, fetch func() (V, error)) (V, error) {
x.lock.Lock()
v, ok := x.core.Get(key)
if ok {
x.lock.Unlock()
v.lock.Lock()
expires, value, err := v.expires, v.value, v.err
if expires != 0 && expires > time.Now().UnixMilli() {
v.lock.Unlock()
x.target.IncrGetHit()
return value, err
}
} else {
v = &layLruItem[V]{}
x.core.Add(key, v)
v.lock.Lock()
x.lock.Unlock()
}
defer v.lock.Unlock()
if v.expires > time.Now().UnixMilli() {
return v.value, v.err
}
v.value, v.err = fetch()
if v.err == nil {
v.expires = time.Now().Add(x.successTTL).UnixMilli()
x.target.IncrGetSuccess()
} else {
v.expires = time.Now().Add(x.failedTTL).UnixMilli()
x.target.IncrGetFailed()
}
return v.value, v.err
}
func (x *LayLRU[K, V]) Del(key K) bool {
x.lock.Lock()
ok := x.core.Remove(key)
x.lock.Unlock()
if ok {
x.target.IncrDelHit()
} else {
x.target.IncrDelNotFound()
}
return ok
}
func (x *LayLRU[K, V]) Stop() {
}
+118
View File
@@ -0,0 +1,118 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package lru
import (
"fmt"
"hash/fnv"
"sync"
"sync/atomic"
"testing"
"time"
"unsafe"
)
type cacheTarget struct {
getHit int64
getSuccess int64
getFailed int64
delHit int64
delNotFound int64
}
func (r *cacheTarget) IncrGetHit() {
atomic.AddInt64(&r.getHit, 1)
}
func (r *cacheTarget) IncrGetSuccess() {
atomic.AddInt64(&r.getSuccess, 1)
}
func (r *cacheTarget) IncrGetFailed() {
atomic.AddInt64(&r.getFailed, 1)
}
func (r *cacheTarget) IncrDelHit() {
atomic.AddInt64(&r.delHit, 1)
}
func (r *cacheTarget) IncrDelNotFound() {
atomic.AddInt64(&r.delNotFound, 1)
}
func (r *cacheTarget) String() string {
return fmt.Sprintf("getHit: %d, getSuccess: %d, getFailed: %d, delHit: %d, delNotFound: %d", r.getHit, r.getSuccess, r.getFailed, r.delHit, r.delNotFound)
}
func TestName(t *testing.T) {
target := &cacheTarget{}
l := NewSlotLRU[string, string](100, func(k string) uint64 {
h := fnv.New64a()
h.Write(*(*[]byte)(unsafe.Pointer(&k)))
return h.Sum64()
}, func() LRU[string, string] {
return NewExpirationLRU[string, string](100, time.Second*60, time.Second, target, nil)
})
//l := NewInertiaLRU[string, string](1000, time.Second*20, time.Second*5, target)
fn := func(key string, n int, fetch func() (string, error)) {
for i := 0; i < n; i++ {
//v, err := l.Get(key, fetch)
//if err == nil {
// t.Log("key", key, "value", v)
//} else {
// t.Error("key", key, err)
//}
v, err := l.Get(key, fetch)
//time.Sleep(time.Second / 100)
func(v ...any) {}(v, err)
}
}
tmp := make(map[string]struct{})
var wg sync.WaitGroup
for i := 0; i < 10000; i++ {
wg.Add(1)
key := fmt.Sprintf("key_%d", i%200)
tmp[key] = struct{}{}
go func() {
defer wg.Done()
//t.Log(key)
fn(key, 10000, func() (string, error) {
//time.Sleep(time.Second * 3)
//t.Log(time.Now(), "key", key, "fetch")
//if rand.Uint32()%5 == 0 {
// return "value_" + key, nil
//}
//return "", errors.New("rand error")
return "value_" + key, nil
})
}()
//wg.Add(1)
//go func() {
// defer wg.Done()
// for i := 0; i < 10; i++ {
// l.Del(key)
// time.Sleep(time.Second / 3)
// }
//}()
}
wg.Wait()
t.Log(len(tmp))
t.Log(target.String())
}
+51
View File
@@ -0,0 +1,51 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package lru
func NewSlotLRU[K comparable, V any](slotNum int, hash func(K) uint64, create func() LRU[K, V]) LRU[K, V] {
x := &slotLRU[K, V]{
n: uint64(slotNum),
slots: make([]LRU[K, V], slotNum),
hash: hash,
}
for i := 0; i < slotNum; i++ {
x.slots[i] = create()
}
return x
}
type slotLRU[K comparable, V any] struct {
n uint64
slots []LRU[K, V]
hash func(k K) uint64
}
func (x *slotLRU[K, V]) getIndex(k K) uint64 {
return x.hash(k) % x.n
}
func (x *slotLRU[K, V]) Get(key K, fetch func() (V, error)) (V, error) {
return x.slots[x.getIndex(key)].Get(key, fetch)
}
func (x *slotLRU[K, V]) Del(key K) bool {
return x.slots[x.getIndex(key)].Del(key)
}
func (x *slotLRU[K, V]) Stop() {
for _, slot := range x.slots {
slot.Stop()
}
}
+136
View File
@@ -0,0 +1,136 @@
// Copyright © 2024 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package localcache
import (
"context"
"time"
"github.com/openimsdk/localcache/lru"
)
func defaultOption() *option {
return &option{
localSlotNum: 500,
localSlotSize: 20000,
linkSlotNum: 500,
expirationEvict: false,
localSuccessTTL: time.Minute,
localFailedTTL: time.Second * 5,
delFn: make([]func(ctx context.Context, key ...string), 0, 2),
target: emptyTarget{},
}
}
type option struct {
localSlotNum int
localSlotSize int
linkSlotNum int
// expirationEvict: true means that the cache will be actively cleared when the timer expires,
// false means that the cache will be lazily deleted.
expirationEvict bool
localSuccessTTL time.Duration
localFailedTTL time.Duration
delFn []func(ctx context.Context, key ...string)
target lru.Target
}
type Option func(o *option)
func WithExpirationEvict() Option {
return func(o *option) {
o.expirationEvict = true
}
}
func WithLazy() Option {
return func(o *option) {
o.expirationEvict = false
}
}
func WithLocalDisable() Option {
return WithLinkSlotNum(0)
}
func WithLinkDisable() Option {
return WithLinkSlotNum(0)
}
func WithLinkSlotNum(linkSlotNum int) Option {
return func(o *option) {
o.linkSlotNum = linkSlotNum
}
}
func WithLocalSlotNum(localSlotNum int) Option {
return func(o *option) {
o.localSlotNum = localSlotNum
}
}
func WithLocalSlotSize(localSlotSize int) Option {
return func(o *option) {
o.localSlotSize = localSlotSize
}
}
func WithLocalSuccessTTL(localSuccessTTL time.Duration) Option {
if localSuccessTTL < 0 {
panic("localSuccessTTL should be greater than 0")
}
return func(o *option) {
o.localSuccessTTL = localSuccessTTL
}
}
func WithLocalFailedTTL(localFailedTTL time.Duration) Option {
if localFailedTTL < 0 {
panic("localFailedTTL should be greater than 0")
}
return func(o *option) {
o.localFailedTTL = localFailedTTL
}
}
func WithTarget(target lru.Target) Option {
if target == nil {
panic("target should not be nil")
}
return func(o *option) {
o.target = target
}
}
func WithDeleteKeyBefore(fn func(ctx context.Context, key ...string)) Option {
if fn == nil {
panic("fn should not be nil")
}
return func(o *option) {
o.delFn = append(o.delFn, fn)
}
}
type emptyTarget struct{}
func (e emptyTarget) IncrGetHit() {}
func (e emptyTarget) IncrGetSuccess() {}
func (e emptyTarget) IncrGetFailed() {}
func (e emptyTarget) IncrDelHit() {}
func (e emptyTarget) IncrDelNotFound() {}
@@ -1,4 +1,4 @@
// Copyright © 2023 OpenIM. All rights reserved. // Copyright © 2024 OpenIM. All rights reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@@ -13,3 +13,11 @@
// limitations under the License. // limitations under the License.
package localcache package localcache
func AnyValue[V any](v any, err error) (V, error) {
if err != nil {
var zero V
return zero, err
}
return v.(V), nil
}
@@ -12,23 +12,23 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package main package rpccache
import ( func newListMap[V comparable](values []V, err error) (*listMap[V], error) {
"log"
"github.com/openimsdk/open-im-server/tools/codescan/checker"
"github.com/openimsdk/open-im-server/tools/codescan/config"
)
func main() {
cfg, err := config.ParseConfig()
if err != nil { if err != nil {
log.Fatalf("Error parsing config: %v", err) return nil, err
} }
lm := &listMap[V]{
err = checker.WalkDirAndCheckComments(cfg) List: values,
if err != nil { Map: make(map[V]struct{}, len(values)),
panic(err)
} }
for _, value := range values {
lm.Map[value] = struct{}{}
}
return lm, nil
}
type listMap[V comparable] struct {
List []V
Map map[V]struct{}
} }

Some files were not shown because too many files have changed in this diff Show More