Compare commits

...

31 Commits

Author SHA1 Message Date
Monet Lee 840ddc15fe chore: revert tool pkg version. (#2476)
* feat: update go mod pkg to latest.

* revert tool pkg version.
2024-08-02 12:13:13 +00:00
Monet Lee c45967079e feat: update go mod pkg to latest. (#2475) 2024-08-02 18:30:17 +08:00
chao 84049a1f55 fix: the local cache obtained can be modified (#2473)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* mage

* optimization version log

* optimization version log

* sync

* sync

* sync

* group sync

* sync option

* sync option

* refactor: replace `friend` package with `realtion`.

* refactor: update lastest commit to relation.

* sync option

* sync option

* sync option

* sync

* sync

* go.mod

* seq

* update: go mod

* refactor: change incremental to full

* feat: get full friend user ids

* feat: api and config

* seq

* group version

* merge

* seq

* seq

* seq

* fix: sort by id avoid unstable sort friends.

* group

* group

* group

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* user version

* seq

* seq

* seq user

* user online

* implement minio expire delete.

* user online

* config

* fix

* fix

* implement minio expire delete logic.

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* feat: implement scheduled delete outdated object in minio.

* update gomake version

* update gomake version

* implement FindExpires pagination.

* remove unnesseary incr.

* fix uncorrect args call.

* online push

* online push

* online push

* resolving conflicts

* resolving conflicts

* test

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* rpc prommetrics

* rpc prommetrics

* online status

* online status

* online status

* online status

* sub

* conversation version incremental

* merge seq

* merge online

* merge online

* merge online

* merge seq

* GetOwnerConversation

* fix: change incremental syncer router name.

* rockscache batch get

* rockscache seq batch get

* fix: GetMsgDocModelByIndex bug

* update go.mod

* update go.mod

* merge

* feat: prometheus

* feat: prometheus

* group member sort

* sub

* sub

* fix: seq conversion bug

* fix: redis pipe exec

* sort version

* sort version

* sort version

* remove old version online subscription

* remove old version online subscription

* version log index

* version log index

* batch push

* batch push

* seq void filling

* fix: batchGetMaxSeq

* fix: batchGetMaxSeq

* cache db error log

* 111

* fix bug

* fix: ImportFriends

* add online cache

* add some logs

* add some logs

* fix: onlineUserIDs

* add logs

* test

* test

* test

* test

* add log

* feat: solve the problem that modifying the cached data affects other

* feat: solve the problem that modifying the cached data affects other

* feat: search messages to filter out notifications

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Monet Lee <monet_lee@163.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: icey-yu <1186114839@qq.com>
2024-08-02 08:58:04 +00:00
Monet Lee 51e170ade1 feat: implement scheduled destruct msgs feature in cron task. (#2466)
* update protocol in go mod.

* add debug log in writePongMsg.

* update log level.

* add Warn log in writePongMsg.

* add debug log.

* feat: update webhookBeforeMemberJoinGroup to batch method.

* feat: update version field implement.

* update webhook implement contents.

* update method field and contents.

* update callbackCommand field.

* fix: add correct fields.

* update struct tags.

* refactor: rename friend module to relation.

* feat: implement scheduled destruct msgs feature in cron task.

* update log contents.

* update func name and comments.

* update waitgroup to errgroup.

* update errgroup wait.

* remove unnecessary contents.

* update clearMsg logic.
2024-08-01 08:12:41 +00:00
chao 375f63a447 fix: online status renewal (#2468)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* mage

* optimization version log

* optimization version log

* sync

* sync

* sync

* group sync

* sync option

* sync option

* refactor: replace `friend` package with `realtion`.

* refactor: update lastest commit to relation.

* sync option

* sync option

* sync option

* sync

* sync

* go.mod

* seq

* update: go mod

* refactor: change incremental to full

* feat: get full friend user ids

* feat: api and config

* seq

* group version

* merge

* seq

* seq

* seq

* fix: sort by id avoid unstable sort friends.

* group

* group

* group

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* user version

* seq

* seq

* seq user

* user online

* implement minio expire delete.

* user online

* config

* fix

* fix

* implement minio expire delete logic.

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* feat: implement scheduled delete outdated object in minio.

* update gomake version

* update gomake version

* implement FindExpires pagination.

* remove unnesseary incr.

* fix uncorrect args call.

* online push

* online push

* online push

* resolving conflicts

* resolving conflicts

* test

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* rpc prommetrics

* rpc prommetrics

* online status

* online status

* online status

* online status

* sub

* conversation version incremental

* merge seq

* merge online

* merge online

* merge online

* merge seq

* GetOwnerConversation

* fix: change incremental syncer router name.

* rockscache batch get

* rockscache seq batch get

* fix: GetMsgDocModelByIndex bug

* update go.mod

* update go.mod

* merge

* feat: prometheus

* feat: prometheus

* group member sort

* sub

* sub

* fix: seq conversion bug

* fix: redis pipe exec

* sort version

* sort version

* sort version

* remove old version online subscription

* remove old version online subscription

* version log index

* version log index

* batch push

* batch push

* seq void filling

* fix: batchGetMaxSeq

* fix: batchGetMaxSeq

* cache db error log

* 111

* fix bug

* fix: ImportFriends

* add online cache

* add some logs

* add some logs

* fix: onlineUserIDs

* add logs

* test

* test

* test

* test

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Monet Lee <monet_lee@163.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: icey-yu <1186114839@qq.com>
2024-08-01 07:11:17 +00:00
Monet Lee 5dac91569d refactor: rename friend module to relation. (#2463)
* update protocol in go mod.

* add debug log in writePongMsg.

* update log level.

* add Warn log in writePongMsg.

* add debug log.

* feat: update webhookBeforeMemberJoinGroup to batch method.

* feat: update version field implement.

* update webhook implement contents.

* update method field and contents.

* update callbackCommand field.

* fix: add correct fields.

* update struct tags.

* refactor: rename friend module to relation.
2024-07-31 10:12:19 +00:00
chao 9cfbc3aaff fix: return value (#2462)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* mage

* optimization version log

* optimization version log

* sync

* sync

* sync

* group sync

* sync option

* sync option

* refactor: replace `friend` package with `realtion`.

* refactor: update lastest commit to relation.

* sync option

* sync option

* sync option

* sync

* sync

* go.mod

* seq

* update: go mod

* refactor: change incremental to full

* feat: get full friend user ids

* feat: api and config

* seq

* group version

* merge

* seq

* seq

* seq

* fix: sort by id avoid unstable sort friends.

* group

* group

* group

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* user version

* seq

* seq

* seq user

* user online

* implement minio expire delete.

* user online

* config

* fix

* fix

* implement minio expire delete logic.

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* feat: implement scheduled delete outdated object in minio.

* update gomake version

* update gomake version

* implement FindExpires pagination.

* remove unnesseary incr.

* fix uncorrect args call.

* online push

* online push

* online push

* resolving conflicts

* resolving conflicts

* test

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* rpc prommetrics

* rpc prommetrics

* online status

* online status

* online status

* online status

* sub

* conversation version incremental

* merge seq

* merge online

* merge online

* merge online

* merge seq

* GetOwnerConversation

* fix: change incremental syncer router name.

* rockscache batch get

* rockscache seq batch get

* fix: GetMsgDocModelByIndex bug

* update go.mod

* update go.mod

* merge

* feat: prometheus

* feat: prometheus

* group member sort

* sub

* sub

* fix: seq conversion bug

* fix: redis pipe exec

* sort version

* sort version

* sort version

* remove old version online subscription

* remove old version online subscription

* version log index

* version log index

* batch push

* batch push

* seq void filling

* fix: batchGetMaxSeq

* fix: batchGetMaxSeq

* cache db error log

* 111

* fix bug

* fix: ImportFriends

* add online cache

* add some logs

* add some logs

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Monet Lee <monet_lee@163.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: icey-yu <1186114839@qq.com>
2024-07-31 06:21:19 +00:00
chao d2b02dbabe feat: add some logs (#2461)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* mage

* optimization version log

* optimization version log

* sync

* sync

* sync

* group sync

* sync option

* sync option

* refactor: replace `friend` package with `realtion`.

* refactor: update lastest commit to relation.

* sync option

* sync option

* sync option

* sync

* sync

* go.mod

* seq

* update: go mod

* refactor: change incremental to full

* feat: get full friend user ids

* feat: api and config

* seq

* group version

* merge

* seq

* seq

* seq

* fix: sort by id avoid unstable sort friends.

* group

* group

* group

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* user version

* seq

* seq

* seq user

* user online

* implement minio expire delete.

* user online

* config

* fix

* fix

* implement minio expire delete logic.

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* feat: implement scheduled delete outdated object in minio.

* update gomake version

* update gomake version

* implement FindExpires pagination.

* remove unnesseary incr.

* fix uncorrect args call.

* online push

* online push

* online push

* resolving conflicts

* resolving conflicts

* test

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* rpc prommetrics

* rpc prommetrics

* online status

* online status

* online status

* online status

* sub

* conversation version incremental

* merge seq

* merge online

* merge online

* merge online

* merge seq

* GetOwnerConversation

* fix: change incremental syncer router name.

* rockscache batch get

* rockscache seq batch get

* fix: GetMsgDocModelByIndex bug

* update go.mod

* update go.mod

* merge

* feat: prometheus

* feat: prometheus

* group member sort

* sub

* sub

* fix: seq conversion bug

* fix: redis pipe exec

* sort version

* sort version

* sort version

* remove old version online subscription

* remove old version online subscription

* version log index

* version log index

* batch push

* batch push

* seq void filling

* fix: batchGetMaxSeq

* fix: batchGetMaxSeq

* cache db error log

* 111

* fix bug

* fix: ImportFriends

* add online cache

* add some logs

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Monet Lee <monet_lee@163.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: icey-yu <1186114839@qq.com>
2024-07-31 02:50:55 +00:00
Monet Lee fb689618d8 feat: update webhookBeforeMemberJoinGroup to batch method. (#2459)
* update protocol in go mod.

* add debug log in writePongMsg.

* update log level.

* add Warn log in writePongMsg.

* add debug log.

* feat: update webhookBeforeMemberJoinGroup to batch method.

* feat: update version field implement.

* update webhook implement contents.

* update method field and contents.

* update callbackCommand field.

* fix: add correct fields.

* update struct tags.
2024-07-30 10:09:52 +00:00
chao ed0ab58a9e fix ImportFriends (#2458)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* update gomake version

* update gomake version

* fix: seq conversion bug

* fix: redis pipe exec

* fix: ImportFriends

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
2024-07-29 08:53:26 +00:00
icey-yu 231aac2b8a fix: search log can return platform (#2456)
* fix: search log can return platform

* fix: change platform type to string
2024-07-29 08:37:22 +00:00
printlin b0cc4373a5 fix: #2410 BeforeMemberJoinGroup callback member error (#2423) 2024-07-29 02:08:28 +00:00
Monet Lee ef46abd193 chore: add Warn log in writePongMsg. (#2452)
* update protocol in go mod.

* add debug log in writePongMsg.

* update log level.

* add Warn log in writePongMsg.

* add debug log.
2024-07-28 03:18:23 +00:00
printlin 220a01d7f8 fix: fill notification offlinePush by config (#2422)
* fix: fill notification offlinePush by config

* fix: fill notification OfflinePush by config
2024-07-26 10:24:25 +00:00
blooming ff66e97221 fix: rm e2e in ci (#2449) 2024-07-26 18:20:54 +08:00
blooming e9b3a1952f cicd: add e2e in ci & before build docker image (#2346)
* cicd: add e2e in ci & before build docker image

* cicd: fix env minio addr

* cicd: fix build image timing
2024-07-26 08:36:11 +00:00
skiffer-git 7c3f6db0e3 Merge branch 'coderwander-main1' 2024-07-26 16:33:51 +08:00
skiffer-git caef9a1941 Merge branch 'main' of https://github.com/coderwander/open-im-server into coderwander-main1 2024-07-26 16:33:45 +08:00
skiffer-git 6c0c83eb3b Delete config/templates/env.template 2024-07-26 16:32:36 +08:00
skiffer-git 0a7992faab Update env.template 2024-07-26 16:30:58 +08:00
skiffer-git dd5c7e43d5 Merge branch 'coderwander-main' 2024-07-26 16:24:19 +08:00
skiffer-git a837fecda3 merge: fix some typos in comments 2024-07-26 16:23:45 +08:00
skiffer-git 69296539e2 Merge branch 'main' of https://github.com/openimsdk/open-im-server 2024-07-26 16:18:11 +08:00
chao 5c52840d67 fix: user seq, asynchronous friend notification, message search (#2447)
* fix: GroupApplicationAcceptedNotification

* fix: GroupApplicationAcceptedNotification

* fix: NotificationUserInfoUpdate

* cicd: robot automated Change

* fix: component

* fix: getConversationInfo

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* feat: cron task

* fix: minio config url recognition error

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* new mongo

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* friend incr sync

* mage

* optimization version log

* optimization version log

* sync

* sync

* sync

* group sync

* sync option

* sync option

* refactor: replace `friend` package with `realtion`.

* refactor: update lastest commit to relation.

* sync option

* sync option

* sync option

* sync

* sync

* go.mod

* seq

* update: go mod

* refactor: change incremental to full

* feat: get full friend user ids

* feat: api and config

* seq

* group version

* merge

* seq

* seq

* seq

* fix: sort by id avoid unstable sort friends.

* group

* group

* group

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* fix: sort by id avoid unstable sort friends.

* user version

* seq

* seq

* seq user

* user online

* implement minio expire delete.

* user online

* config

* fix

* fix

* implement minio expire delete logic.

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* online cache

* feat: implement scheduled delete outdated object in minio.

* update gomake version

* update gomake version

* implement FindExpires pagination.

* remove unnesseary incr.

* fix uncorrect args call.

* online push

* online push

* online push

* resolving conflicts

* resolving conflicts

* test

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* api prommetrics

* rpc prommetrics

* rpc prommetrics

* online status

* online status

* online status

* online status

* sub

* conversation version incremental

* merge seq

* merge online

* merge online

* merge online

* merge seq

* GetOwnerConversation

* fix: change incremental syncer router name.

* rockscache batch get

* rockscache seq batch get

* fix: GetMsgDocModelByIndex bug

* update go.mod

* update go.mod

* merge

* feat: prometheus

* feat: prometheus

* group member sort

* sub

* sub

* fix: seq conversion bug

* fix: redis pipe exec

* sort version

* sort version

* sort version

* remove old version online subscription

* remove old version online subscription

* version log index

* version log index

* batch push

* batch push

* seq void filling

* fix: batchGetMaxSeq

* fix: batchGetMaxSeq

* cache db error log

* 111

* fix bug

---------

Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Monet Lee <monet_lee@163.com>
Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com>
Co-authored-by: icey-yu <1186114839@qq.com>
2024-07-26 07:53:25 +00:00
Monet Lee c3c9969f2f chore: add debug log in writePongMsg (#2446)
* update protocol in go mod.

* add debug log in writePongMsg.

* update log level.
2024-07-26 07:52:37 +00:00
icey-yu a8b84911a4 fix: display is read (#2444) 2024-07-26 06:40:36 +00:00
skiffer-git a321303b1b Merge branch 'main' of https://github.com/openimsdk/open-im-server 2024-06-03 18:48:04 +08:00
skiffer-git eb766ebd94 Merge branch 'main' of https://github.com/openimsdk/open-im-server 2024-05-30 14:21:55 +08:00
skiffer-git 6ab1244ad8 merge 2024-05-23 10:19:54 +08:00
skiffer-git 6a721f2eab Merge branch 'main' into main 2024-04-28 11:56:58 +08:00
coderwander 381fd1beeb chore: fix some typos in comments
Signed-off-by: coderwander <770732124@qq.com>
2024-04-16 11:30:20 +08:00
79 changed files with 1358 additions and 1707 deletions
-1
View File
@@ -1,4 +1,3 @@
MONGO_IMAGE=mongo:6.0.2
REDIS_IMAGE=redis:7.0.0
ZOOKEEPER_IMAGE=bitnami/zookeeper:3.8
+127 -91
View File
@@ -19,8 +19,27 @@ on:
branches:
- main
- release-*
paths-ignore:
- "docs/**"
- "README.md"
- "README_zh-CN.md"
- "**.md"
- "docs/**"
- "CONTRIBUTING.md"
tags:
- v*
pull_request:
types: [closed]
branches:
- main
- release-*
paths-ignore:
- "docs/**"
- "README.md"
- "README_zh-CN.md"
- "**.md"
- "docs/**"
- "CONTRIBUTING.md"
workflow_dispatch:
env:
@@ -29,22 +48,112 @@ env:
jobs:
build-dockerhub:
if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true)
runs-on: ubuntu-latest
if: ${{ !(github.event_name == 'pull_request' && github.event.pull_request.merged == false) }}
steps:
- name: Checkout
- name: Checkout main repository
uses: actions/checkout@v4
with:
path: main-repo
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# docker.io/openim/openim-server:latest
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./main-repo
load: true
tags: "openim/openim-server:local"
- name: Checkout compose repository
uses: actions/checkout@v4
with:
repository: "openimsdk/openim-docker"
path: "compose-repo"
- name: Get Internal IP Address
id: get-ip
run: |
IP=$(hostname -I | awk '{print $1}')
echo "The IP Address is: $IP"
echo "::set-output name=ip::$IP"
- name: Update .env to use the local image
run: |
sed -i 's|OPENIM_SERVER_IMAGE=.*|OPENIM_SERVER_IMAGE=openim/openim-server:local|' ${{ github.workspace }}/compose-repo/.env
sed -i 's|MINIO_EXTERNAL_ADDRESS=.*|MINIO_EXTERNAL_ADDRESS=http://${{ steps.get-ip.outputs.ip }}:10005|' ${{ github.workspace }}/compose-repo/.env
- name: Start services using Docker Compose
run: |
cd ${{ github.workspace }}/compose-repo
docker compose up -d
sleep 30
- name: Check openim-server health
run: |
timeout=300
interval=30
elapsed=0
while [[ $elapsed -le $timeout ]]; do
if ! docker exec openim-server mage check; then
echo "openim-server is not ready, waiting..."
sleep $interval
elapsed=$(($elapsed + $interval))
else
echo "Health check successful"
exit 0
fi
done
echo "Health check failed after 5 minutes"
exit 1
- name: Check openim-chat health
if: success()
run: |
if ! docker exec openim-chat mage check; then
echo "openim-chat check failed"
exit 1
else
echo "Health check successful"
exit 0
fi
# - name: Checkout e2e
# if: success()
# uses: actions/checkout@v4
# with:
# repository: "openimsdk/test-e2e"
# path: e2e-repo
# - name: Set up Python 3.9
# uses: actions/setup-python@v4
# with:
# python-version: '3.9'
# - name: Install dependencies
# run: |
# sudo apt-get update
# sudo apt-get install -y xvfb libxi6 libgconf-2-4
# cd ${{ github.workspace }}/e2e-repo
# pip install -r requirements.txt
# - name: Run tests
# run: |
# cd ${{ github.workspace }}/e2e-repo
# xvfb-run --auto-servernum --server-args='-screen 0 1920x1080x24' pytest -v -s ./script
- name: Extract metadata (tags, labels) for Docker
if: success()
id: meta
uses: docker/metadata-action@v5.5.1
with:
images: openim/openim-server
images: |
openim/openim-server
ghcr.io/openimsdk/openim-server
registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=tag
@@ -58,105 +167,32 @@ jobs:
type=sha
- name: Log in to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
# linux/ppc64le,linux/s390x
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-aliyun:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server:latest
- name: Extract metadata (tags, labels) for Docker
id: meta2
uses: docker/metadata-action@v5.5.1
with:
images: registry.cn-hangzhou.aliyuncs.com/openimsdk/openim-server
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Log in to AliYun Docker Hub
uses: docker/login-action@v3
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALIREGISTRY_USERNAME }}
password: ${{ secrets.ALIREGISTRY_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
# linux/ppc64le,linux/s390x
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta2.outputs.tags }}
labels: ${{ steps.meta2.outputs.labels }}
build-ghcr:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# ghcr.io/openimsdk/openim-server:latest
- name: Extract metadata (tags, labels) for Docker
id: meta3
uses: docker/metadata-action@v5.5.1
with:
images: ghcr.io/openimsdk/openim-server
# generate Docker tags based on the following events/attributes
tags: |
type=ref,event=tag
type=schedule
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern=v{{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Log in to Aliyun Container Registry
uses: docker/login-action@v2
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALIREGISTRY_USERNAME }}
password: ${{ secrets.ALIREGISTRY_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
context: ./main-repo
push: true
# linux/ppc64le,linux/s390x
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta3.outputs.tags }}
labels: ${{ steps.meta3.outputs.labels }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
-53
View File
@@ -1,53 +0,0 @@
# Copyright © 2023 OpenIM open source community. 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: Github Rebot for Link check error
# Every Monday at 12:30 p.m
on:
schedule:
- cron: '30 12 * * 1'
jobs:
linkChecker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@v1.9.3
with:
# For parameter description, see https://github.com/lycheeverse/lychee#commandline-parameters
# Actions Link address -> https://github.com/lycheeverse/lychee-action
# -E, --exclude-all-private Exclude all private IPs from checking.
# -i, --insecure Proceed for server connections considered insecure (invalid TLS)
# -n, --no-progress Do not show progress bar.
# -t, --timeout <timeout> Website timeout in seconds from connect to response finished [default:20]
# --max-concurrency <max-concurrency> Maximum number of concurrent network requests [default: 128]
# -a --accept <accept> Comma-separated list of accepted status codes for valid links
# docs/.vitepress/dist the site directory to check
# ./*.md all markdown files in the root directory
args: --verbose -E -i --no-progress --exclude-path './CHANGELOG' './**/*.md'
env:
GITHUB_TOKEN: ${{secrets.BOT_GITHUB_TOKEN}}
- name: Create Issue From File
if: env.lychee_exit_code != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: Bug reports for links in OpenIM docs
content-filepath: ./lychee/out.md
labels: kind/documentation, triage/unresolved, report
token: ${{ secrets.BOT_GITHUB_TOKEN }}
+47 -103
View File
@@ -71,6 +71,18 @@ jobs:
run: sudo bash bootstrap.sh
timeout-minutes: 20
# - name: Get Internal IP Address
# id: get-ip
# run: |
# IP=$(hostname -I | awk '{print $1}')
# echo "The IP Address is: $IP"
# echo "::set-output name=ip::$IP"
# - name: Update .env
# run: |
# sed -i 's|externalAddress:.*|externalAddress: "http://${{ steps.get-ip.outputs.ip }}:10005"|' config/minio.yml
# cat config/minio.yml
- name: Build, Start, Check Services and Print Logs for Linux
run: |
sudo mage
@@ -84,108 +96,40 @@ jobs:
sudo mage start
sudo mage check
- name: Checkout chat repository
uses: actions/checkout@v4
with:
repository: 'openimsdk/chat'
path: 'chat-repo'
# build-mac:
# name: Execute OpenIM Script On macOS
# runs-on: macos-latest
# permissions:
# contents: write
# pull-requests: write
# environment:
# name: openim
# strategy:
# matrix:
# arch: [arm64, armv7, amd64]
#
# steps:
# - uses: actions/checkout@v3
- name: Build and Start Chat Services
run: |
cd ${{ github.workspace }}/chat-repo
sudo mage
sudo mage start
sudo mage check
# - name: Checkout e2e repository
# uses: actions/checkout@v4
# with:
# repository: "openimsdk/test-e2e"
# path: e2e-repo
# - name: Set up Go
# uses: actions/setup-go@v4
# with:
# go-version: '1.21'
# while ! docker system info > /dev/null 2>&1; do
# echo "Waiting for Docker to start..."
# sleep 10 # Increased delay to ensure Docker starts properly
# done
# - name: Install Docker
# run: |
# brew install docker
# brew install docker-compose
# sleep 10
# docker-compose up -d
# sleep 30
# timeout-minutes: 20
#
# - name: init
# run: sudo bash bootstrap.sh
# timeout-minutes: 20
# - name: Build, Start, Check Services and Print Logs for Linux
# run: |
# sudo mage
# sudo mage start
# sudo mage check
# - name: Restart Services and Print Logs
# run: |
# sudo mage stop
# sudo mage start
# sudo mage check
# build-windows:
# name: Execute OpenIM Script On Windows
# runs-on: windows-latest
# permissions:
# contents: write
# pull-requests: write
# environment:
# name: openim
# strategy:
# matrix:
# arch: [arm64, armv7, amd64]
#
# steps:
# - uses: actions/checkout@v3
# - name: Set up Go
# uses: actions/setup-go@v4
# with:
# go-version: '1.21'
# - name: Set up Docker for Windows
# run: |
# $images = @("zookeeper", "redis", "kafka")
# foreach ($image in $images) {
# $tag = "$image:latest"
# docker pull $tag | Out-Null
# if ($LASTEXITCODE -ne 0) {
# Write-Host "Skipping $image as it is not available for Windows"
# } else {
# Write-Host "Successfully pulled $image"
# }
# }
# docker compose up -d
# Start-Sleep -Seconds 30
# timeout-minutes: 20
# shell: pwsh
# - name: init
# run: bootstrap.bat
# timeout-minutes: 20
# - name: Build, Start, Check Services and Print Logs for Linux
# run: |
# mage
# mage start
# mage check
# - name: Restart Services and Print Logs
# run: |
# mage stop
# mage start
# mage check
# - name: Set up Python 3.9
# uses: actions/setup-python@v4
# with:
# python-version: '3.9'
# - name: Install dependencies
# run: |
# sudo apt-get update
# sudo apt-get install -y xvfb libxi6 libgconf-2-4
# cd ${{ github.workspace }}/e2e-repo
# pip install -r requirements.txt
# - name: Run tests
# run: |
# cd ${{ github.workspace }}/e2e-repo
# xvfb-run --auto-servernum --server-args='-screen 0 1920x1080x24' pytest -v -s ./script
-48
View File
@@ -1,48 +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.
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
schedule:
- cron: '0 8 * * 1'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
days-before-stale: 60
days-before-close: 305
stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
stale-pr-message: 'This issue is stale because it has been open 60 days with no activity.'
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity. You can reopen it if you want.'
stale-pr-label: lifecycle/stale
stale-issue-label: lifecycle/stale
exempt-issue-labels: 'openim'
exempt-pr-labels: 'openim'
exempt-draft-pr: true
-56
View File
@@ -1,56 +0,0 @@
# Version logging for OpenIM
> **Note**:
> Deprecated version logging for OpenIM, please refer to [CHANGELOG.md](../CHANGELOG.md)
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM](#version-logging-for-openim)
- [Unreleased](#unreleased)
- [v1.0.7 - 2021-12-17](#v107---2021-12-17)
- [v1.0.6 - 2021-12-10](#v106---2021-12-10)
- [v1.0.5 - 2021-12-03](#v105---2021-12-03)
- [v1.0.4 - 2021-11-25](#v104---2021-11-25)
- [v1.0.3 - 2021-11-12](#v103---2021-11-12)
- [v1.0.1 - 2021-11-04](#v101---2021-11-04)
- [v1.0.0 - 2021-10-28](#v100---2021-10-28)
- [Reverts](#reverts)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v1.0.7"></a>
## [v1.0.7] - 2021-12-17
<a name="v1.0.6"></a>
## [v1.0.6] - 2021-12-10
<a name="v1.0.5"></a>
## [v1.0.5] - 2021-12-03
<a name="v1.0.4"></a>
## [v1.0.4] - 2021-11-25
<a name="v1.0.3"></a>
## [v1.0.3] - 2021-11-12
<a name="v1.0.1"></a>
## [v1.0.1] - 2021-11-04
<a name="v1.0.0"></a>
## v1.0.0 - 2021-10-28
### Reverts
- friend modify
- update
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v1.0.7...HEAD
[v1.0.7]: https://github.com/openimsdk/open-im-server/compare/v1.0.6...v1.0.7
[v1.0.6]: https://github.com/openimsdk/open-im-server/compare/v1.0.5...v1.0.6
[v1.0.5]: https://github.com/openimsdk/open-im-server/compare/v1.0.4...v1.0.5
[v1.0.4]: https://github.com/openimsdk/open-im-server/compare/v1.0.3...v1.0.4
[v1.0.3]: https://github.com/openimsdk/open-im-server/compare/v1.0.1...v1.0.3
[v1.0.1]: https://github.com/openimsdk/open-im-server/compare/v1.0.0...v1.0.1
-87
View File
@@ -1,87 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.0.10"></a>
## [v2.0.10] - 2022-05-13
<a name="v2.0.9"></a>
## [v2.0.9] - 2022-04-29
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.8"></a>
## [v2.0.8] - 2022-04-24
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.7"></a>
## [v2.0.7] - 2022-04-08
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.6"></a>
## [v2.0.6] - 2022-04-01
### Pull Requests
- Merge branch 'tuoyun'
<a name="v2.0.5"></a>
## [v2.0.5] - 2022-03-24
<a name="v2.04"></a>
## [v2.04] - 2022-03-18
<a name="v2.0.3"></a>
## [v2.0.3] - 2022-03-11
<a name="v2.0.2"></a>
## [v2.0.2] - 2022-03-04
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.1"></a>
## [v2.0.1] - 2022-02-25
<a name="v2.0.0"></a>
## v2.0.0 - 2022-02-23
### Reverts
- friend modify
- update
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v2.0.10...HEAD
[v2.0.10]: https://github.com/openimsdk/open-im-server/compare/v2.0.9...v2.0.10
[v2.0.9]: https://github.com/openimsdk/open-im-server/compare/v2.0.8...v2.0.9
[v2.0.8]: https://github.com/openimsdk/open-im-server/compare/v2.0.7...v2.0.8
[v2.0.7]: https://github.com/openimsdk/open-im-server/compare/v2.0.6...v2.0.7
[v2.0.6]: https://github.com/openimsdk/open-im-server/compare/v2.0.5...v2.0.6
[v2.0.5]: https://github.com/openimsdk/open-im-server/compare/v2.04...v2.0.5
[v2.04]: https://github.com/openimsdk/open-im-server/compare/v2.0.3...v2.04
[v2.0.3]: https://github.com/openimsdk/open-im-server/compare/v2.0.2...v2.0.3
[v2.0.2]: https://github.com/openimsdk/open-im-server/compare/v2.0.1...v2.0.2
[v2.0.1]: https://github.com/openimsdk/open-im-server/compare/v2.0.0...v2.0.1
-50
View File
@@ -1,50 +0,0 @@
# Version logging for OpenIM:v2.1
> **Note**:
> Deprecated version logging for OpenIM, please refer to [CHANGELOG.md](../CHANGELOG.md)
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM:v2.1](#version-logging-for-openimv21)
- [Unreleased](#unreleased)
- [v2.1.0 - 2022-06-17](#v210---2022-06-17)
- [Reverts](#reverts)
- [Pull Requests](#pull-requests)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.1.0"></a>
## v2.1.0 - 2022-06-17
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
- friend modify
- update
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v2.1.0...HEAD
-50
View File
@@ -1,50 +0,0 @@
# Version logging for OpenIM:v2.2
> **Note**:
> Deprecated version logging for OpenIM, please refer to [CHANGELOG.md](../CHANGELOG.md)
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM:v2.2](#version-logging-for-openimv22)
- [Unreleased](#unreleased)
- [v2.2.0 - 2022-07-01](#v220---2022-07-01)
- [Reverts](#reverts)
- [Pull Requests](#pull-requests)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.2.0"></a>
## v2.2.0 - 2022-07-01
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
- friend modify
- update
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v2.2.0...HEAD
-70
View File
@@ -1,70 +0,0 @@
# Version logging for OpenIM:v2.3
> **Note**:
> Deprecated version logging for OpenIM, please refer to [CHANGELOG.md](../CHANGELOG.md)
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM:v2.3](#version-logging-for-openimv23)
- [Unreleased](#unreleased)
- [v2.3.3 - 2022-09-18](#v233---2022-09-18)
- [v2.3.2 - 2022-09-09](#v232---2022-09-09)
- [v2.3.0-rc2 - 2022-07-29](#v230-rc2---2022-07-29)
- [v2.3.0-rc1 - 2022-07-25](#v230-rc1---2022-07-25)
- [v2.3.0-rc0 - 2022-07-15](#v230-rc0---2022-07-15)
- [Reverts](#reverts)
- [Pull Requests](#pull-requests)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.3.3"></a>
## [v2.3.3] - 2022-09-18
<a name="v2.3.2"></a>
## [v2.3.2] - 2022-09-09
<a name="v2.3.0-rc2"></a>
## [v2.3.0-rc2] - 2022-07-29
<a name="v2.3.0-rc1"></a>
## [v2.3.0-rc1] - 2022-07-25
<a name="v2.3.0-rc0"></a>
## v2.3.0-rc0 - 2022-07-15
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
- friend modify
- update
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v2.3.3...HEAD
[v2.3.3]: https://github.com/openimsdk/open-im-server/compare/v2.3.2...v2.3.3
[v2.3.2]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc2...v2.3.2
[v2.3.0-rc2]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc1...v2.3.0-rc2
[v2.3.0-rc1]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc0...v2.3.0-rc1
-52
View File
@@ -1,52 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM](#version-logging-for-openim)
- [Unreleased](#unreleased)
- [v2.9.0+1.839643f - 2023-07-07](#v2901839643f---2023-07-07)
- [v2.9.0+2.35f07fe - 2023-07-06](#v290235f07fe---2023-07-06)
- [v2.9.0+1.b5072b1 - 2023-07-05](#v2901b5072b1---2023-07-05)
- [v2.9.0+3.2667a3a - 2023-07-05](#v29032667a3a---2023-07-05)
- [v2.9.0+7.04818ca - 2023-07-05](#v290704818ca---2023-07-05)
- [v2.9.0 - 2023-07-04](#v290---2023-07-04)
- [Reverts](#reverts)
- [Pull Requests](#pull-requests)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.9.0+1.839643f"></a>
## [v2.9.0+1.839643f] - 2023-07-07
<a name="v2.9.0+2.35f07fe"></a>
## [v2.9.0+2.35f07fe] - 2023-07-06
<a name="v2.9.0+1.b5072b1"></a>
## [v2.9.0+1.b5072b1] - 2023-07-05
<a name="v2.9.0+3.2667a3a"></a>
## [v2.9.0+3.2667a3a] - 2023-07-05
<a name="v2.9.0+7.04818ca"></a>
## [v2.9.0+7.04818ca] - 2023-07-05
<a name="v2.9.0"></a>
## v2.9.0 - 2023-07-04
### 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/v2.9.0+1.839643f...HEAD
[v2.9.0+1.839643f]: https://github.com/openimsdk/open-im-server/compare/v2.9.0+2.35f07fe...v2.9.0+1.839643f
[v2.9.0+2.35f07fe]: https://github.com/openimsdk/open-im-server/compare/v2.9.0+1.b5072b1...v2.9.0+2.35f07fe
[v2.9.0+1.b5072b1]: https://github.com/openimsdk/open-im-server/compare/v2.9.0+3.2667a3a...v2.9.0+1.b5072b1
[v2.9.0+3.2667a3a]: https://github.com/openimsdk/open-im-server/compare/v2.9.0+7.04818ca...v2.9.0+3.2667a3a
[v2.9.0+7.04818ca]: https://github.com/openimsdk/open-im-server/compare/v2.9.0...v2.9.0+7.04818ca
-188
View File
@@ -1,188 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
- [Version logging for OpenIM](#version-logging-for-openim)
- [Unreleased](#unreleased)
- [v2.9.0 - 2023-07-04](#v290---2023-07-04)
- [Reverts](#reverts)
- [Pull Requests](#pull-requests)
- [v2.3.3 - 2022-09-18](#v233---2022-09-18)
- [v2.3.2 - 2022-09-09](#v232---2022-09-09)
- [v2.3.0-rc2 - 2022-07-29](#v230-rc2---2022-07-29)
- [v2.3.0-rc1 - 2022-07-25](#v230-rc1---2022-07-25)
- [v2.3.0-rc0 - 2022-07-15](#v230-rc0---2022-07-15)
- [v2.2.0 - 2022-07-01](#v220---2022-07-01)
- [v2.1.0 - 2022-06-17](#v210---2022-06-17)
- [Pull Requests](#pull-requests-1)
- [v2.0.10 - 2022-05-13](#v2010---2022-05-13)
- [v2.0.9 - 2022-04-29](#v209---2022-04-29)
- [Reverts](#reverts-1)
- [Pull Requests](#pull-requests-2)
- [v2.0.7 - 2022-04-08](#v207---2022-04-08)
- [Pull Requests](#pull-requests-3)
- [v2.0.6 - 2022-04-01](#v206---2022-04-01)
- [Pull Requests](#pull-requests-4)
- [v2.0.5 - 2022-03-24](#v205---2022-03-24)
- [v2.04 - 2022-03-18](#v204---2022-03-18)
- [v2.0.3 - 2022-03-11](#v203---2022-03-11)
- [v2.0.2 - 2022-03-04](#v202---2022-03-04)
- [Pull Requests](#pull-requests-5)
- [v2.0.1 - 2022-02-25](#v201---2022-02-25)
- [v2.0.0 - 2022-02-23](#v200---2022-02-23)
- [v1.0.7 - 2021-12-17](#v107---2021-12-17)
- [v1.0.6 - 2021-12-10](#v106---2021-12-10)
- [v1.0.5 - 2021-12-03](#v105---2021-12-03)
- [v1.0.4 - 2021-11-25](#v104---2021-11-25)
- [v1.0.3 - 2021-11-12](#v103---2021-11-12)
- [v1.0.1 - 2021-11-04](#v101---2021-11-04)
- [v1.0.0 - 2021-10-28](#v100---2021-10-28)
- [Reverts](#reverts-2)
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v2.9.0"></a>
## [v2.9.0] - 2023-07-04
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
### Pull Requests
- Merge branch 'tuoyun'
<a name="v2.3.3"></a>
## [v2.3.3] - 2022-09-18
<a name="v2.3.2"></a>
## [v2.3.2] - 2022-09-09
<a name="v2.3.0-rc2"></a>
## [v2.3.0-rc2] - 2022-07-29
<a name="v2.3.0-rc1"></a>
## [v2.3.0-rc1] - 2022-07-25
<a name="v2.3.0-rc0"></a>
## [v2.3.0-rc0] - 2022-07-15
<a name="v2.2.0"></a>
## [v2.2.0] - 2022-07-01
<a name="v2.1.0"></a>
## [v2.1.0] - 2022-06-17
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.10"></a>
## [v2.0.10] - 2022-05-13
<a name="v2.0.9"></a>
## [v2.0.9] - 2022-04-29
### Reverts
- update etcd to v3.5.2 ([#206](https://github.com/openimsdk/open-im-server/issues/206))
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.7"></a>
## [v2.0.7] - 2022-04-08
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.6"></a>
## [v2.0.6] - 2022-04-01
### Pull Requests
- Merge branch 'tuoyun'
<a name="v2.0.5"></a>
## [v2.0.5] - 2022-03-24
<a name="v2.04"></a>
## [v2.04] - 2022-03-18
<a name="v2.0.3"></a>
## [v2.0.3] - 2022-03-11
<a name="v2.0.2"></a>
## [v2.0.2] - 2022-03-04
### Pull Requests
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
- Merge branch 'tuoyun'
<a name="v2.0.1"></a>
## [v2.0.1] - 2022-02-25
<a name="v2.0.0"></a>
## [v2.0.0] - 2022-02-23
<a name="v1.0.7"></a>
## [v1.0.7] - 2021-12-17
<a name="v1.0.6"></a>
## [v1.0.6] - 2021-12-10
<a name="v1.0.5"></a>
## [v1.0.5] - 2021-12-03
<a name="v1.0.4"></a>
## [v1.0.4] - 2021-11-25
<a name="v1.0.3"></a>
## [v1.0.3] - 2021-11-12
<a name="v1.0.1"></a>
## [v1.0.1] - 2021-11-04
<a name="v1.0.0"></a>
## v1.0.0 - 2021-10-28
### Reverts
- friend modify
- update
[Unreleased]: https://github.com/openimsdk/open-im-server/compare/v2.9.0...HEAD
[v2.9.0]: https://github.com/openimsdk/open-im-server/compare/v2.3.3...v2.9.0
[v2.3.3]: https://github.com/openimsdk/open-im-server/compare/v2.3.2...v2.3.3
[v2.3.2]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc2...v2.3.2
[v2.3.0-rc2]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc1...v2.3.0-rc2
[v2.3.0-rc1]: https://github.com/openimsdk/open-im-server/compare/v2.3.0-rc0...v2.3.0-rc1
[v2.3.0-rc0]: https://github.com/openimsdk/open-im-server/compare/v2.2.0...v2.3.0-rc0
[v2.2.0]: https://github.com/openimsdk/open-im-server/compare/v2.1.0...v2.2.0
[v2.1.0]: https://github.com/openimsdk/open-im-server/compare/v2.0.10...v2.1.0
[v2.0.10]: https://github.com/openimsdk/open-im-server/compare/v2.0.9...v2.0.10
[v2.0.9]: https://github.com/openimsdk/open-im-server/compare/v2.0.7...v2.0.9
[v2.0.7]: https://github.com/openimsdk/open-im-server/compare/v2.0.6...v2.0.7
[v2.0.6]: https://github.com/openimsdk/open-im-server/compare/v2.0.5...v2.0.6
[v2.0.5]: https://github.com/openimsdk/open-im-server/compare/v2.04...v2.0.5
[v2.04]: https://github.com/openimsdk/open-im-server/compare/v2.0.3...v2.04
[v2.0.3]: https://github.com/openimsdk/open-im-server/compare/v2.0.2...v2.0.3
[v2.0.2]: https://github.com/openimsdk/open-im-server/compare/v2.0.1...v2.0.2
[v2.0.1]: https://github.com/openimsdk/open-im-server/compare/v2.0.0...v2.0.1
[v2.0.0]: https://github.com/openimsdk/open-im-server/compare/v1.0.7...v2.0.0
[v1.0.7]: https://github.com/openimsdk/open-im-server/compare/v1.0.6...v1.0.7
[v1.0.6]: https://github.com/openimsdk/open-im-server/compare/v1.0.5...v1.0.6
[v1.0.5]: https://github.com/openimsdk/open-im-server/compare/v1.0.4...v1.0.5
[v1.0.4]: https://github.com/openimsdk/open-im-server/compare/v1.0.3...v1.0.4
[v1.0.3]: https://github.com/openimsdk/open-im-server/compare/v1.0.1...v1.0.3
[v1.0.1]: https://github.com/openimsdk/open-im-server/compare/v1.0.0...v1.0.1
-20
View File
@@ -1,20 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.1.0"></a>
## v3.1.0 - 2023-07-28
### 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.1.0...HEAD
-32
View File
@@ -1,32 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.2.2-alpha.0"></a>
## [v3.2.2-alpha.0] - 2023-08-25
<a name="v3.2.0"></a>
## [v3.2.0] - 2023-08-19
<a name="v3.2.0-rc.0"></a>
## [v3.2.0-rc.0] - 2023-08-17
<a name="v3.2.0-alpha.0"></a>
## v3.2.0-alpha.0 - 2023-08-16
### 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.2.2-alpha.0...HEAD
[v3.2.2-alpha.0]: https://github.com/openimsdk/open-im-server/compare/v3.2.0...v3.2.2-alpha.0
[v3.2.0]: https://github.com/openimsdk/open-im-server/compare/v3.2.0-rc.0...v3.2.0
[v3.2.0-rc.0]: https://github.com/openimsdk/open-im-server/compare/v3.2.0-alpha.0...v3.2.0-rc.0
-40
View File
@@ -1,40 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.3.1"></a>
## [v3.3.1] - 2023-09-13
<a name="v3.3.1-beta.0"></a>
## [v3.3.1-beta.0] - 2023-09-11
<a name="v3.3.0-rc.1"></a>
## [v3.3.0-rc.1] - 2023-09-11
<a name="v3.3.0-rc.12"></a>
## [v3.3.0-rc.12] - 2023-09-11
<a name="v3.3.0"></a>
## [v3.3.0] - 2023-09-09
<a name="v3.3.0-rc.0"></a>
## v3.3.0-rc.0 - 2023-09-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.3.1...HEAD
[v3.3.1]: https://github.com/openimsdk/open-im-server/compare/v3.3.1-beta.0...v3.3.1
[v3.3.1-beta.0]: https://github.com/openimsdk/open-im-server/compare/v3.3.0-rc.1...v3.3.1-beta.0
[v3.3.0-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.3.0-rc.12...v3.3.0-rc.1
[v3.3.0-rc.12]: https://github.com/openimsdk/open-im-server/compare/v3.3.0...v3.3.0-rc.12
[v3.3.0]: https://github.com/openimsdk/open-im-server/compare/v3.3.0-rc.0...v3.3.0
-32
View File
@@ -1,32 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.4.2"></a>
## [v3.4.2] - 2023-12-14
<a name="v3.4.0"></a>
## [v3.4.0] - 2023-11-10
<a name="v3.4.0-rc.1"></a>
## [v3.4.0-rc.1] - 2023-11-09
<a name="v3.4.0-rc.0"></a>
## v3.4.0-rc.0 - 2023-11-09
### 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.4.2...HEAD
[v3.4.2]: https://github.com/openimsdk/open-im-server/compare/v3.4.0...v3.4.2
[v3.4.0]: https://github.com/openimsdk/open-im-server/compare/v3.4.0-rc.1...v3.4.0
[v3.4.0-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.4.0-rc.0...v3.4.0-rc.1
-84
View File
@@ -1,84 +0,0 @@
# Version logging for OpenIM
<!-- BEGIN MUNGE: GENERATED_TOC -->
<!-- END MUNGE: GENERATED_TOC -->
<a name="unreleased"></a>
## [Unreleased]
<a name="v3.5.1-alpha.2"></a>
## [v3.5.1-alpha.2] - 2024-01-26
<a name="v3.5.1-rc.1"></a>
## [v3.5.1-rc.1] - 2024-01-23
<a name="v3.5.1-alpha.1"></a>
## [v3.5.1-alpha.1] - 2024-01-09
<a name="v3.5.0"></a>
## [v3.5.0] - 2024-01-02
<a name="v3.5.1"></a>
## [v3.5.1] - 2024-01-02
<a name="v3.5.1-bate.1"></a>
## [v3.5.1-bate.1] - 2024-01-02
<a name="v3.5.1-rc.0"></a>
## [v3.5.1-rc.0] - 2023-12-30
<a name="v3.5.0-rc.8"></a>
## [v3.5.0-rc.8] - 2023-12-28
<a name="v3.5.0-rc.7"></a>
## [v3.5.0-rc.7] - 2023-12-18
<a name="v3.5.0-rc.6"></a>
## [v3.5.0-rc.6] - 2023-12-15
<a name="v3.5.0-rc.5"></a>
## [v3.5.0-rc.5] - 2023-12-15
<a name="v3.5.0-rc.4"></a>
## [v3.5.0-rc.4] - 2023-12-14
<a name="v3.5.0-rc.3"></a>
## [v3.5.0-rc.3] - 2023-12-14
<a name="v3.5.0-rc.2"></a>
## [v3.5.0-rc.2] - 2023-12-14
<a name="v3.5.0-rc.1"></a>
## [v3.5.0-rc.1] - 2023-12-14
<a name="v3.5.0-rc.0"></a>
## [v3.5.0-rc.0] - 2023-12-14
<a name="v3.5.0-beta.1"></a>
## v3.5.0-beta.1 - 2023-11-29
### 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.5.1-alpha.2...HEAD
[v3.5.1-alpha.2]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-rc.1...v3.5.1-alpha.2
[v3.5.1-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-alpha.1...v3.5.1-rc.1
[v3.5.1-alpha.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0...v3.5.1-alpha.1
[v3.5.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.1...v3.5.0
[v3.5.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-bate.1...v3.5.1
[v3.5.1-bate.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.1-rc.0...v3.5.1-bate.1
[v3.5.1-rc.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.8...v3.5.1-rc.0
[v3.5.0-rc.8]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.7...v3.5.0-rc.8
[v3.5.0-rc.7]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.6...v3.5.0-rc.7
[v3.5.0-rc.6]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.5...v3.5.0-rc.6
[v3.5.0-rc.5]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.4...v3.5.0-rc.5
[v3.5.0-rc.4]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.3...v3.5.0-rc.4
[v3.5.0-rc.3]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.2...v3.5.0-rc.3
[v3.5.0-rc.2]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.1...v3.5.0-rc.2
[v3.5.0-rc.1]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-rc.0...v3.5.0-rc.1
[v3.5.0-rc.0]: https://github.com/openimsdk/open-im-server/compare/v3.5.0-beta.1...v3.5.0-rc.0
-20
View File
@@ -1,20 +0,0 @@
# 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
-173
View File
@@ -1,173 +0,0 @@
# Changelog
- [Changelog](#changelog)
- [OpenIM versioning policy](#openim-versioning-policy)
- [command](#command)
- [install](#install)
- [User](#user)
- [create next tag](#create-next-tag)
- [Release version logs](#release-version-logs)
- [Introduction](#introduction)
- [Naming Format](#naming-format)
- [Examples](#examples)
- [Version Modifiers](#version-modifiers)
- [Versioning Strategy](#versioning-strategy)
All notable changes to this project will be documented in this file.
+ [https://github.com/openimsdk/open-im-server/releases](https://github.com/openimsdk/open-im-server/releases)
## OpenIM versioning policy
+ [OpenIM Version](../docs/contrib/version.md)
## command
To use git-chglog you need to configure:
1. CHANGELOG templates
2. git-chglog configuration
### install
```bash
$ go get github.com/git-chglog/git-chglog/cmd/git-chglog
```
## User
```bash
$ git-chglog --init
```
**Options**
- What is the URL of your repository?: https://github.com/openimsdk/open-im-server
- What is your favorite style?: github
- Choose the format of your favorite commit message: <type>(<scope>): <subject> -- feat(core): Add new feature
- What is your favorite template style?: standard
- Do you include Merge Commit in CHANGELOG?: n
- Do you include Revert Commit in CHANGELOG?: y
- In which directory do you output configuration files and templates?: .chglog
```bash
git-chglog --tag-filter-pattern 'v2.0.*' -o CHANGELOG-2.0.md
```
**Other uses:**
```bash
$ git-chglog
If <tag query> is not specified, it corresponds to all tags.
This is the simplest example.
$ git-chglog 1.0.0..2.0.0
The above is a command to generate CHANGELOG including commit of 1.0.0 to 2.0.0.
$ git-chglog 1.0.0
The above is a command to generate CHANGELOG including commit of only 1.0.0.
$ git-chglog $(git describe --tags $(git rev-list --tags --max-count=1))
The above is a command to generate CHANGELOG with the commit included in the latest tag.
$ git-chglog --output CHANGELOG.md
The above is a command to output to CHANGELOG.md instead of standard output.
$ git-chglog --config custom/dir/config.yml
The above is a command that uses a configuration file placed other than ".chglog/config.yml".
```
## create next tag
```bash
$ git-chglog --next-tag 2.0.0 -o CHANGELOG.md
$ git commit -am "release 2.0.0"
$ git tag 2.0.0
```
| Query | Description | Example |
| -------------- | ---------------------------------------------- | --------------------------- |
| `<old>..<new>` | Commit contained in `<new>` tags from `<old>`. | `$ git-chglog 1.0.0..2.0.0` |
| `<name>..` | Commit from the `<name>` to the latest tag. | `$ git-chglog 1.0.0..` |
| `..<name>` | Commit from the oldest tag to `<name>`. | `$ git-chglog ..2.0.0` |
| `<name>` | Commit contained in `<name>`. | `$ git-chglog 1.0.0` |
## Release version logs
+ [OpenIM CHANGELOG-V1.0](CHANGELOG-1.0.md)
+ [OpenIM CHANGELOG-V2.0](CHANGELOG-2.0.md)
+ [OpenIM CHANGELOG-V2.1](CHANGELOG-2.1.md)
+ [OpenIM CHANGELOG-V2.2](CHANGELOG-2.2.md)
+ [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md)
+ [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md)
+ [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md)
+ [OpenIM CHANGELOG-V3.1](CHANGELOG-3.1.md)
+ [OpenIM CHANGELOG-V3.2](CHANGELOG-3.2.md)
+ [OpenIM CHANGELOG-V3.3](CHANGELOG-3.3.md)
## Introduction
In both the open-source and closed-source software development communities, it is important to follow a consistent and understandable versioning scheme for software projects. This ensures clear communication of changes, compatibility, and stability across different releases. One widely adopted naming convention is the Semantic Versioning 2.0.0.
## Naming Format
The most common format for version numbers is as follows:
```bash
major.minor[.patch[.build]]
```
Let's take a closer look at each component:
1. **Major Version**: This is the first number in the versioning scheme and indicates significant changes that may not be backward compatible (specific to each project).
2. **Minor Version**: The second number signifies the addition of new features while maintaining backward compatibility.
3. **Patch Version**: The third number represents bug fixes or code optimizations without introducing new features. It is generally backward compatible.
4. **Build Version**: Typically an automatically generated number that increments with each code commit.
## Examples
Here are a few examples to illustrate the versioning scheme:
1. `1.0`
2. `2.14.0.1478`
3. `3.2.1 build-354`
## Version Modifiers
Apart from the version numbers, there are also version modifiers used to indicate specific stages or statuses of a release. Some commonly used version modifiers include:
- **alpha**: An internal testing version with numerous known bugs. It is primarily used for communication among developers.
- **beta**: A testing version released to enthusiastic users for feedback and bug detection.
- **rc (release candidate)**: The final testing version before the official release.
- **ga (general availability)**: The initial stable release for public distribution.
- **r/release** (or no modifier at all): The final released version intended for general users.
- **lts (long-term support)**: Designates a version that will receive extended maintenance and bug fixes for a specified number of years.
## Versioning Strategy
To effectively manage version numbers, the following strategies are commonly employed:
- The initial version of a project can be either `0.1` or `1.0`.
- When fixing bugs, the patch version is incremented by 1.
- When adding new features, the minor version is incremented by 1, and the patch version is reset to 0.
- In the case of significant modifications, the major version is incremented by 1.
- The build version is usually automatically generated by the compilation process and follows a defined format. It does not require manual control.
By adhering to these strategies and guidelines, developers can maintain consistency and clarity in versioning their software projects. This enables users and collaborators to understand the nature of changes between different releases and ensure compatibility with their systems.
(Note: Markdown formatting has been used to structure this article. Markdown is a lightweight markup language used to format text on platforms like GitHub.)
------
**Note**: The above article is based on the given content and aims to provide a Markdown-formatted English article explaining the naming conventions for software project versions, specifically focusing on the Semantic Versioning 2.0.0.
+1 -1
View File
@@ -129,7 +129,7 @@ REDIS_PORT=${REDIS_PORT}
# Default: REDIS_PASSWORD=openIM123
REDIS_PASSWORD=${REDIS_PASSWORD}
# Kakfa username to authenticate with the Kafka service.
# Kafka username to authenticate with the Kafka service.
# KAFKA_USERNAME=${KAFKA_USERNAME}
# Port on which Kafka distributed streaming platform is running.
+2 -1
View File
@@ -12,7 +12,7 @@ require (
github.com/gorilla/websocket v1.5.1
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/openimsdk/protocol v0.0.69-alpha.41
github.com/openimsdk/protocol v0.0.69
github.com/openimsdk/tools v0.0.49-alpha.55
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0
@@ -74,6 +74,7 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/webp v1.1.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
+4 -2
View File
@@ -71,6 +71,8 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
@@ -319,8 +321,8 @@ github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y=
github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/openimsdk/gomake v0.0.14-alpha.5 h1:VY9c5x515lTfmdhhPjMvR3BBRrRquAUCFsz7t7vbv7Y=
github.com/openimsdk/gomake v0.0.14-alpha.5/go.mod h1:PndCozNc2IsQIciyn9mvEblYWZwJmAI+06z94EY+csI=
github.com/openimsdk/protocol v0.0.69-alpha.41 h1:9hoQ6UHMBq+g58KXir90EpnnvwJ1bvDPixPSaODo4nY=
github.com/openimsdk/protocol v0.0.69-alpha.41/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/protocol v0.0.69 h1:dVi8meSg8kmUzSH1XQab4MjihqKkkcCAmt1BYXPJuXo=
github.com/openimsdk/protocol v0.0.69/go.mod h1:OZQA9FR55lseYoN2Ql1XAHYKHJGu7OMNkUbuekrKCM8=
github.com/openimsdk/tools v0.0.49-alpha.55 h1:KPgC53oqiwZYssLKljhtXbWXifMlTj2SSQEusj4Uf4k=
github.com/openimsdk/tools v0.0.49-alpha.55/go.mod h1:h1cYmfyaVtgFbKmb1Cfsl8XwUOMTt8ubVUQrdGtsUh4=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
+9 -3
View File
@@ -107,7 +107,6 @@ func (c *Client) pingHandler(appData string) error {
}
log.ZDebug(c.ctx, "ping Handler Success.", "appData", appData)
return c.writePongMsg(appData)
}
@@ -392,7 +391,9 @@ func (c *Client) writePingMsg() error {
}
func (c *Client) writePongMsg(appData string) error {
log.ZDebug(c.ctx, "write Pong Msg in Server", "appData", appData)
if c.closed.Load() {
log.ZWarn(c.ctx, "is closed in server", nil, "appdata", appData, "closed err", c.closedErr)
return nil
}
@@ -401,8 +402,13 @@ func (c *Client) writePongMsg(appData string) error {
err := c.conn.SetWriteDeadline(writeWait)
if err != nil {
return err
log.ZWarn(c.ctx, "SetWriteDeadline in Server have error", errs.Wrap(err), "writeWait", writeWait, "appData", appData)
return errs.Wrap(err)
}
err = c.conn.WriteMessage(PongMessage, []byte(appData))
if err != nil {
log.ZWarn(c.ctx, "Write Message have error", errs.Wrap(err), "Pong msg", PongMessage)
}
return c.conn.WriteMessage(PongMessage, []byte(appData))
return errs.Wrap(err)
}
+7 -2
View File
@@ -4,13 +4,16 @@ import (
"context"
"crypto/md5"
"encoding/binary"
"fmt"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
pbuser "github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/datautil"
"math/rand"
"os"
"strconv"
"sync/atomic"
"time"
)
@@ -78,8 +81,10 @@ func (ws *WsServer) ChangeOnlineStatus(concurrent int) {
}
}
opIdCtx := mcontext.SetOperationID(context.Background(), "r"+strconv.FormatUint(rNum, 10))
var count atomic.Int64
operationIDPrefix := fmt.Sprintf("p_%d_", os.Getpid())
doRequest := func(req *pbuser.SetUserOnlineStatusReq) {
opIdCtx := mcontext.SetOperationID(context.Background(), operationIDPrefix+strconv.FormatInt(count.Add(1), 10))
ctx, cancel := context.WithTimeout(opIdCtx, time.Second*5)
defer cancel()
if _, err := ws.userClient.Client.SetUserOnlineStatus(ctx, req); err != nil {
@@ -102,7 +107,7 @@ func (ws *WsServer) ChangeOnlineStatus(concurrent int) {
case now := <-renewalTicker.C:
deadline := now.Add(-cachekey.OnlineExpire / 3)
users := ws.clients.GetAllUserStatus(deadline, now)
log.ZDebug(context.Background(), "renewal ticker", "deadline", deadline, "nowtime", now, "num", len(users))
log.ZDebug(context.Background(), "renewal ticker", "deadline", deadline, "nowtime", now, "num", len(users), "users", users)
pushUserState(users...)
case state := <-ws.clients.UserState():
log.ZDebug(context.Background(), "OnlineCache user online change", "userID", state.UserID, "online", state.Online, "offline", state.Offline)
+3 -3
View File
@@ -162,12 +162,12 @@ func (u *userMap) DeleteClients(userID string, clients []*Client) (isDeleteUser
return true
}
func (u *userMap) GetAllUserStatus(deadline time.Time, nowtime time.Time) []UserState {
func (u *userMap) GetAllUserStatus(deadline time.Time, nowtime time.Time) (result []UserState) {
u.lock.RLock()
defer u.lock.RUnlock()
result := make([]UserState, 0, len(u.data))
result = make([]UserState, 0, len(u.data))
for userID, userPlatform := range u.data {
if userPlatform.Time.Before(deadline) {
if deadline.Before(userPlatform.Time) {
continue
}
userPlatform.Time = nowtime
+2 -1
View File
@@ -198,10 +198,11 @@ func (c *ConsumerHandler) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.
offlineUserIDs = append(offlineUserIDs, userID)
}
}
log.ZDebug(ctx, "GetConnsAndOnlinePush online cache", "sendID", msg.SendID, "recvID", msg.RecvID, "groupID", msg.GroupID, "sessionType", msg.SessionType, "clientMsgID", msg.ClientMsgID, "serverMsgID", msg.ServerMsgID, "offlineUserIDs", offlineUserIDs, "onlineUserIDs", onlineUserIDs)
var result []*msggateway.SingleMsgToUserResults
if len(onlineUserIDs) > 0 {
var err error
result, err = c.onlinePusher.GetConnsAndOnlinePush(ctx, msg, pushToUserIDs)
result, err = c.onlinePusher.GetConnsAndOnlinePush(ctx, msg, onlineUserIDs)
if err != nil {
return nil, err
}
+73 -16
View File
@@ -16,13 +16,16 @@ package conversation
import (
"context"
"sort"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
dbModel "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/tools/db/redisutil"
"sort"
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
"github.com/openimsdk/open-im-server/v3/pkg/common/servererrs"
@@ -40,10 +43,11 @@ import (
)
type conversationServer struct {
msgRpcClient *rpcclient.MessageRpcClient
user *rpcclient.UserRpcClient
groupRpcClient *rpcclient.GroupRpcClient
conversationDatabase controller.ConversationDatabase
msgRpcClient *rpcclient.MessageRpcClient
user *rpcclient.UserRpcClient
groupRpcClient *rpcclient.GroupRpcClient
conversationDatabase controller.ConversationDatabase
conversationNotificationSender *ConversationNotificationSender
config *Config
}
@@ -204,11 +208,11 @@ func (c *conversationServer) getConversations(ctx context.Context, ownerUserID s
}
func (c *conversationServer) SetConversation(ctx context.Context, req *pbconversation.SetConversationReq) (*pbconversation.SetConversationResp, error) {
var conversation tablerelation.Conversation
var conversation dbModel.Conversation
if err := datautil.CopyStructFields(&conversation, req.Conversation); err != nil {
return nil, err
}
err := c.conversationDatabase.SetUserConversations(ctx, req.Conversation.OwnerUserID, []*tablerelation.Conversation{&conversation})
err := c.conversationDatabase.SetUserConversations(ctx, req.Conversation.OwnerUserID, []*dbModel.Conversation{&conversation})
if err != nil {
return nil, err
}
@@ -232,7 +236,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
}
}
var unequal int
var conv tablerelation.Conversation
var conv dbModel.Conversation
if len(req.UserIDs) == 1 {
cs, err := c.conversationDatabase.FindConversations(ctx, req.UserIDs[0], []string{req.Conversation.ConversationID})
if err != nil {
@@ -243,7 +247,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
}
conv = *cs[0]
}
var conversation tablerelation.Conversation
var conversation dbModel.Conversation
conversation.ConversationID = req.Conversation.ConversationID
conversation.ConversationType = req.Conversation.ConversationType
conversation.UserID = req.Conversation.UserID
@@ -292,7 +296,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver
}
}
if req.Conversation.IsPrivateChat != nil && req.Conversation.ConversationType != constant.ReadGroupChatType {
var conversations []*tablerelation.Conversation
var conversations []*dbModel.Conversation
for _, ownerUserID := range req.UserIDs {
conversation2 := conversation
conversation2.OwnerUserID = ownerUserID
@@ -340,12 +344,12 @@ func (c *conversationServer) CreateSingleChatConversations(ctx context.Context,
) (*pbconversation.CreateSingleChatConversationsResp, error) {
switch req.ConversationType {
case constant.SingleChatType:
var conversation tablerelation.Conversation
var conversation dbModel.Conversation
conversation.ConversationID = req.ConversationID
conversation.ConversationType = req.ConversationType
conversation.OwnerUserID = req.SendID
conversation.UserID = req.RecvID
err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation})
err := c.conversationDatabase.CreateConversation(ctx, []*dbModel.Conversation{&conversation})
if err != nil {
log.ZWarn(ctx, "create conversation failed", err, "conversation", conversation)
}
@@ -353,17 +357,17 @@ func (c *conversationServer) CreateSingleChatConversations(ctx context.Context,
conversation2 := conversation
conversation2.OwnerUserID = req.RecvID
conversation2.UserID = req.SendID
err = c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation2})
err = c.conversationDatabase.CreateConversation(ctx, []*dbModel.Conversation{&conversation2})
if err != nil {
log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation)
}
case constant.NotificationChatType:
var conversation tablerelation.Conversation
var conversation dbModel.Conversation
conversation.ConversationID = req.ConversationID
conversation.ConversationType = req.ConversationType
conversation.OwnerUserID = req.RecvID
conversation.UserID = req.SendID
err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation})
err := c.conversationDatabase.CreateConversation(ctx, []*dbModel.Conversation{&conversation})
if err != nil {
log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation)
}
@@ -584,6 +588,9 @@ func (c *conversationServer) UpdateConversation(ctx context.Context, req *pbconv
if req.MaxSeq != nil {
m["max_seq"] = req.MaxSeq.Value
}
if req.LatestMsgDestructTime != nil {
m["latest_msg_destruct_time"] = time.UnixMilli(req.LatestMsgDestructTime.Value)
}
if len(m) > 0 {
if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.UserIDs, req.ConversationID, m); err != nil {
return nil, err
@@ -602,3 +609,53 @@ func (c *conversationServer) GetOwnerConversation(ctx context.Context, req *pbco
Conversations: convert.ConversationsDB2Pb(conversations),
}, nil
}
func (c *conversationServer) GetConversationsNeedDestructMsgs(ctx context.Context, _ *pbconversation.GetConversationsNeedDestructMsgsReq) (*pbconversation.GetConversationsNeedDestructMsgsResp, error) {
num, err := c.conversationDatabase.GetAllConversationIDsNumber(ctx)
if err != nil {
log.ZError(ctx, "GetAllConversationIDsNumber failed", err)
return nil, err
}
const batchNum = 100
if num == 0 {
return nil, errs.New("Need Destruct Msg is nil").Wrap()
}
maxPage := (num + batchNum - 1) / batchNum
temp := make([]*model.Conversation, 0, maxPage*batchNum)
for pageNumber := 0; pageNumber < int(maxPage); pageNumber++ {
pagination := &sdkws.RequestPagination{
PageNumber: int32(pageNumber),
ShowNumber: batchNum,
}
conversationIDs, err := c.conversationDatabase.PageConversationIDs(ctx, pagination)
if err != nil {
log.ZError(ctx, "PageConversationIDs failed", err, "pageNumber", pageNumber)
continue
}
log.ZDebug(ctx, "PageConversationIDs success", "pageNumber", pageNumber, "conversationIDsNum", len(conversationIDs), "conversationIDs", conversationIDs)
if len(conversationIDs) == 0 {
continue
}
conversations, err := c.conversationDatabase.GetConversationsByConversationID(ctx, conversationIDs)
if err != nil {
log.ZError(ctx, "GetConversationsByConversationID failed", err, "conversationIDs", conversationIDs)
continue
}
for _, conversation := range conversations {
if conversation.IsMsgDestruct && conversation.MsgDestructTime != 0 && ((time.Now().UnixMilli() > (conversation.MsgDestructTime + conversation.LatestMsgDestructTime.UnixMilli() + 8*60*60)) || // 8*60*60 is UTC+8
conversation.LatestMsgDestructTime.IsZero()) {
temp = append(temp, conversation)
}
}
}
return &pbconversation.GetConversationsNeedDestructMsgsResp{Conversations: convert.ConversationsDB2Pb(temp)}, nil
}
+40 -18
View File
@@ -16,6 +16,8 @@ package group
import (
"context"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
"github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
@@ -27,7 +29,6 @@ import (
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/datautil"
"time"
)
// CallbackBeforeCreateGroup callback before create group.
@@ -100,27 +101,45 @@ func (s *groupServer) webhookAfterCreateGroup(ctx context.Context, after *config
s.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &callbackstruct.CallbackAfterCreateGroupResp{}, after)
}
func (s *groupServer) webhookBeforeMemberJoinGroup(ctx context.Context, before *config.BeforeConfig, groupMember *model.GroupMember, groupEx string) error {
func (s *groupServer) webhookBeforeMembersJoinGroup(ctx context.Context, before *config.BeforeConfig, groupMembers []*model.GroupMember, groupID string, groupEx string) error {
return webhook.WithCondition(ctx, before, func(ctx context.Context) error {
cbReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
CallbackCommand: callbackstruct.CallbackBeforeMemberJoinGroupCommand,
GroupID: groupMember.GroupID,
UserID: groupMember.UserID,
Ex: groupMember.Ex,
groupMembersMap := datautil.SliceToMap(groupMembers, func(e *model.GroupMember) string {
return e.UserID
})
var groupMembersCallback []*callbackstruct.CallbackGroupMember
for _, member := range groupMembers {
groupMembersCallback = append(groupMembersCallback, &callbackstruct.CallbackGroupMember{
UserID: member.UserID,
Ex: member.Ex,
})
}
cbReq := &callbackstruct.CallbackBeforeMembersJoinGroupReq{
CallbackCommand: callbackstruct.CallbackBeforeMembersJoinGroupCommand,
GroupID: groupID,
MembersList: groupMembersCallback,
GroupEx: groupEx,
}
resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{}
resp := &callbackstruct.CallbackBeforeMembersJoinGroupResp{}
if err := s.webhookClient.SyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, resp, before); err != nil {
return err
}
if resp.MuteEndTime != nil {
groupMember.MuteEndTime = time.UnixMilli(*resp.MuteEndTime)
for _, memberCallbackResp := range resp.MemberCallbackList {
if _, ok := groupMembersMap[(*memberCallbackResp.UserID)]; ok {
if memberCallbackResp.MuteEndTime != nil {
groupMembersMap[(*memberCallbackResp.UserID)].MuteEndTime = time.UnixMilli(*memberCallbackResp.MuteEndTime)
}
datautil.NotNilReplace(&groupMembersMap[(*memberCallbackResp.UserID)].FaceURL, memberCallbackResp.FaceURL)
datautil.NotNilReplace(&groupMembersMap[(*memberCallbackResp.UserID)].Ex, memberCallbackResp.Ex)
datautil.NotNilReplace(&groupMembersMap[(*memberCallbackResp.UserID)].Nickname, memberCallbackResp.Nickname)
datautil.NotNilReplace(&groupMembersMap[(*memberCallbackResp.UserID)].RoleLevel, memberCallbackResp.RoleLevel)
}
}
datautil.NotNilReplace(&groupMember.FaceURL, resp.FaceURL)
datautil.NotNilReplace(&groupMember.Ex, resp.Ex)
datautil.NotNilReplace(&groupMember.Nickname, resp.Nickname)
datautil.NotNilReplace(&groupMember.RoleLevel, resp.RoleLevel)
return nil
})
}
@@ -244,10 +263,13 @@ func (s *groupServer) webhookBeforeInviteUserToGroup(ctx context.Context, before
return err
}
if len(resp.RefusedMembersAccount) > 0 {
// Handle the scenario where certain members are refused
// You might want to update the req.Members list or handle it as per your business logic
}
// Handle the scenario where certain members are refused
// You might want to update the req.Members list or handle it as per your business logic
// if len(resp.RefusedMembersAccount) > 0 {
// implement members are refused
// }
return nil
})
}
+23 -23
View File
@@ -246,7 +246,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
return nil, err
}
joinGroup := func(userID string, roleLevel int32) error {
joinGroupFunc := func(userID string, roleLevel int32) {
groupMember := &model.GroupMember{
GroupID: group.GroupID,
UserID: userID,
@@ -258,25 +258,23 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
MuteEndTime: time.UnixMilli(0),
}
if err := s.webhookBeforeMemberJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, groupMember, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return err
}
groupMembers = append(groupMembers, groupMember)
return nil
}
if err := joinGroup(req.OwnerUserID, constant.GroupOwner); err != nil {
joinGroupFunc(req.OwnerUserID, constant.GroupOwner)
for _, userID := range req.AdminUserIDs {
joinGroupFunc(userID, constant.GroupAdmin)
}
for _, userID := range req.MemberUserIDs {
joinGroupFunc(userID, constant.GroupOrdinaryUsers)
}
if err := s.webhookBeforeMembersJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, groupMembers, group.GroupID, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return nil, err
}
for _, userID := range req.AdminUserIDs {
if err := joinGroup(userID, constant.GroupAdmin); err != nil {
return nil, err
}
}
for _, userID := range req.MemberUserIDs {
if err := joinGroup(userID, constant.GroupOrdinaryUsers); err != nil {
return nil, err
}
}
if err := s.db.CreateGroup(ctx, []*model.Group{group}, groupMembers); err != nil {
return nil, err
}
@@ -442,12 +440,13 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
MuteEndTime: time.UnixMilli(0),
}
if err := s.webhookBeforeMemberJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, groupMember, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return nil, err
}
groupMembers = append(groupMembers, member)
}
if err := s.webhookBeforeMembersJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, groupMembers, group.GroupID, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return nil, err
}
if err := s.db.CreateGroup(ctx, nil, groupMembers); err != nil {
return nil, err
}
@@ -811,9 +810,9 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
MuteEndTime: time.Unix(0, 0),
InviterUserID: groupRequest.InviterUserID,
OperatorUserID: mcontext.GetOpUserID(ctx),
Ex: groupRequest.Ex,
}
if err := s.webhookBeforeMemberJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, member, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
if err := s.webhookBeforeMembersJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, []*model.GroupMember{member}, group.GroupID, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return nil, err
}
}
@@ -882,7 +881,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
MuteEndTime: time.UnixMilli(0),
}
if err := s.webhookBeforeMemberJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, groupMember, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
if err := s.webhookBeforeMembersJoinGroup(ctx, &s.config.WebhooksConfig.BeforeMemberJoinGroup, []*model.GroupMember{groupMember}, group.GroupID, group.Ex); err != nil && err != servererrs.ErrCallbackContinue {
return nil, err
}
@@ -898,6 +897,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
return &pbgroup.JoinGroupResp{}, nil
}
groupRequest := model.GroupRequest{
UserID: req.InviterUserID,
ReqMsg: req.ReqMessage,
+3 -42
View File
@@ -17,6 +17,7 @@ package group
import (
"context"
"fmt"
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx"
@@ -126,25 +127,8 @@ func (g *GroupNotificationSender) getGroupInfo(ctx context.Context, groupID stri
if len(ownerUserIDs) > 0 {
ownerUserID = ownerUserIDs[0]
}
return &sdkws.GroupInfo{
GroupID: gm.GroupID,
GroupName: gm.GroupName,
Notification: gm.Notification,
Introduction: gm.Introduction,
FaceURL: gm.FaceURL,
OwnerUserID: ownerUserID,
CreateTime: gm.CreateTime.UnixMilli(),
MemberCount: num,
Ex: gm.Ex,
Status: gm.Status,
CreatorUserID: gm.CreatorUserID,
GroupType: gm.GroupType,
NeedVerification: gm.NeedVerification,
LookMemberInfo: gm.LookMemberInfo,
ApplyMemberFriend: gm.ApplyMemberFriend,
NotificationUpdateTime: gm.NotificationUpdateTime.UnixMilli(),
NotificationUserID: gm.NotificationUserID,
}, nil
return convert.Db2PbGroupInfo(gm, ownerUserID, num), nil
}
func (g *GroupNotificationSender) getGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*sdkws.GroupMemberFullInfo, error) {
@@ -198,29 +182,6 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex
return datautil.Slice(members, fn), nil
}
//nolint:unused
func (g *GroupNotificationSender) groupDB2PB(group *model.Group, ownerUserID string, memberCount uint32) *sdkws.GroupInfo {
return &sdkws.GroupInfo{
GroupID: group.GroupID,
GroupName: group.GroupName,
Notification: group.Notification,
Introduction: group.Introduction,
FaceURL: group.FaceURL,
OwnerUserID: ownerUserID,
CreateTime: group.CreateTime.UnixMilli(),
MemberCount: memberCount,
Ex: group.Ex,
Status: group.Status,
CreatorUserID: group.CreatorUserID,
GroupType: group.GroupType,
NeedVerification: group.NeedVerification,
LookMemberInfo: group.LookMemberInfo,
ApplyMemberFriend: group.ApplyMemberFriend,
NotificationUpdateTime: group.NotificationUpdateTime.UnixMilli(),
NotificationUserID: group.NotificationUserID,
}
}
func (g *GroupNotificationSender) groupMemberDB2PB(member *model.GroupMember, appMangerLevel int32) *sdkws.GroupMemberFullInfo {
return &sdkws.GroupMemberFullInfo{
GroupID: member.GroupID,
+66 -19
View File
@@ -2,16 +2,22 @@ package msg
import (
"context"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
"github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
pbconversation "github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/protocol/wrapperspb"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"strings"
"time"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/utils/idutil"
"github.com/openimsdk/tools/utils/stringutil"
"golang.org/x/sync/errgroup"
)
// hard delete in Database.
func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.ClearMsgResp, err error) {
if err := authverify.CheckAdmin(ctx, m.config.Share.IMAdminUserID); err != nil {
return nil, err
@@ -25,18 +31,6 @@ func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.
start = time.Now()
)
clearMsg := func(ctx context.Context) (bool, error) {
conversationSeqs := make(map[string]struct{})
defer func() {
req := &conversation.UpdateConversationReq{
MsgDestructTime: wrapperspb.Int64(time.Now().UnixMilli()),
}
for conversationID := range conversationSeqs {
req.ConversationID = conversationID
if err := m.Conversation.UpdateConversations(ctx, req); err != nil {
log.ZError(ctx, "update conversation max seq failed", err, "conversationID", conversationID, "msgDestructTime", req.MsgDestructTime)
}
}
}()
msgs, err := m.MsgDatabase.GetBeforeMsg(ctx, req.Timestamp, 100)
if err != nil {
return false, err
@@ -44,6 +38,7 @@ func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.
if len(msgs) == 0 {
return false, nil
}
for _, msg := range msgs {
index, err := m.MsgDatabase.DeleteDocMsgBefore(ctx, req.Timestamp, msg)
if err != nil {
@@ -52,15 +47,14 @@ func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.
if len(index) == 0 {
return false, errs.ErrInternalServer.WrapMsg("delete doc msg failed")
}
docNum++
msgNum += len(index)
conversationID := msg.DocID[:strings.LastIndex(msg.DocID, ":")]
if _, ok := conversationSeqs[conversationID]; !ok {
conversationSeqs[conversationID] = struct{}{}
}
}
return true, nil
}
for {
keep, err := clearMsg(ctx)
if err != nil {
@@ -71,7 +65,60 @@ func (m *msgServer) ClearMsg(ctx context.Context, req *msg.ClearMsgReq) (_ *msg.
log.ZInfo(ctx, "clear msg success", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
break
}
log.ZInfo(ctx, "clearing message", "docNum", docNum, "msgNum", msgNum, "cost", time.Since(start))
}
return &msg.ClearMsgResp{}, nil
}
// soft delete for self
func (m *msgServer) DestructMsgs(ctx context.Context, req *msg.DestructMsgsReq) (_ *msg.DestructMsgsResp, err error) {
temp := convert.ConversationsPb2DB(req.Conversations)
batchNum := 100
errg, _ := errgroup.WithContext(ctx)
errg.SetLimit(100)
for i := 0; i < len(temp); i += batchNum {
batch := temp[i:min(i+batchNum, len(temp))]
errg.Go(func() error {
for _, conversation := range batch {
handleCtx := mcontext.NewCtx(stringutil.GetSelfFuncName() + "-" + idutil.OperationIDGenerator() + "-" + conversation.ConversationID + "-" + conversation.OwnerUserID)
log.ZDebug(handleCtx, "User MsgsDestruct",
"conversationID", conversation.ConversationID,
"ownerUserID", conversation.OwnerUserID,
"msgDestructTime", conversation.MsgDestructTime,
"lastMsgDestructTime", conversation.LatestMsgDestructTime)
seqs, err := m.MsgDatabase.UserMsgsDestruct(handleCtx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
if err != nil {
log.ZError(handleCtx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
continue
}
if len(seqs) > 0 {
if err := m.Conversation.UpdateConversation(handleCtx,
&pbconversation.UpdateConversationReq{
UserIDs: []string{conversation.OwnerUserID},
ConversationID: conversation.ConversationID,
LatestMsgDestructTime: wrapperspb.Int64(time.Now().UnixMilli())}); err != nil {
log.ZError(handleCtx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)
continue
}
// if you need Notify SDK client userseq is update.
// m.msgNotificationSender.UserDeleteMsgsNotification(handleCtx, conversation.OwnerUserID, conversation.ConversationID, seqs)
}
}
return nil
})
}
if err := errg.Wait(); err != nil {
return nil, err
}
return nil, nil
}
+5
View File
@@ -16,6 +16,7 @@ package msg
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
@@ -50,6 +51,7 @@ type (
ConversationLocalCache *rpccache.ConversationLocalCache // Local cache for conversation data.
Handlers MessageInterceptorChain // Chain of handlers for processing messages.
notificationSender *rpcclient.NotificationSender // RPC client for sending notifications.
msgNotificationSender *MsgNotificationSender // RPC client for sending msg notifications.
config *Config // Global configuration settings.
webhookClient *webhook.Client
}
@@ -117,7 +119,10 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
}
s.notificationSender = rpcclient.NewNotificationSender(&config.NotificationConfig, rpcclient.WithLocalSendMsg(s.SendMsg))
s.msgNotificationSender = NewMsgNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg))
msg.RegisterMsgServer(server, s)
return nil
}
+2 -2
View File
@@ -111,7 +111,7 @@ func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sd
func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (resp *msg.SearchMessageResp, err error) {
var chatLogs []*sdkws.MsgData
var total int32
var total int64
resp = &msg.SearchMessageResp{}
if total, chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
return nil, err
@@ -194,7 +194,7 @@ func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq
}
resp.ChatLogs = append(resp.ChatLogs, pbchatLog)
}
resp.ChatLogsNum = total
resp.ChatLogsNum = int32(total)
return resp, nil
}
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package friend
package relation
import (
"context"
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package friend
package relation
import (
"context"
@@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package friend
package relation
import (
"context"
"github.com/openimsdk/tools/mq/memamq"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
@@ -49,6 +51,7 @@ type friendServer struct {
RegisterCenter discovery.SvcDiscoveryRegistry
config *Config
webhookClient *webhook.Client
queue *memamq.MemoryQueue
}
type Config struct {
@@ -118,8 +121,8 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
conversationRpcClient: rpcclient.NewConversationRpcClient(client, config.Share.RpcRegisterName.Conversation),
config: config,
webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL),
queue: memamq.NewMemoryQueue(128, 1024*8),
})
return nil
}
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package friend
package relation
import (
"context"
@@ -1,9 +1,10 @@
package friend
package relation
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/util/hashutil"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/log"
"slices"
"github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion"
@@ -17,14 +18,23 @@ func (s *friendServer) NotificationUserInfoUpdate(ctx context.Context, req *rela
if err != nil {
return nil, err
}
for _, userID := range userIDs {
if err := s.db.OwnerIncrVersion(ctx, userID, []string{req.UserID}, model.VersionStateUpdate); err != nil {
return nil, err
if len(userIDs) > 0 {
friendUserIDs := []string{req.UserID}
noCancelCtx := context.WithoutCancel(ctx)
err := s.queue.PushCtx(ctx, func() {
for _, userID := range userIDs {
if err := s.db.OwnerIncrVersion(noCancelCtx, userID, friendUserIDs, model.VersionStateUpdate); err != nil {
log.ZError(ctx, "OwnerIncrVersion", err, "userID", userID, "friendUserIDs", friendUserIDs)
}
}
for _, userID := range userIDs {
s.notificationSender.FriendInfoUpdatedNotification(noCancelCtx, req.UserID, userID)
}
})
if err != nil {
log.ZError(ctx, "NotificationUserInfoUpdate timeout", err, "userID", req.UserID)
}
}
for _, userID := range userIDs {
s.notificationSender.FriendInfoUpdatedNotification(ctx, req.UserID, userID)
}
return &relation.NotificationUserInfoUpdateResp{}, nil
}
+1 -2
View File
@@ -26,7 +26,6 @@ import (
"github.com/openimsdk/protocol/third"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/utils/datautil"
"github.com/openimsdk/tools/utils/stringutil"
)
func genLogID() string {
@@ -111,7 +110,7 @@ func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo {
return &third.LogInfo{
Filename: log.FileName,
UserID: log.UserID,
Platform: stringutil.StringToInt32(log.Platform),
Platform: log.Platform,
Url: log.Url,
CreateTime: log.CreateTime.UnixMilli(),
LogID: log.LogID,
+3 -3
View File
@@ -17,7 +17,7 @@ package user
import (
"context"
"errors"
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
"github.com/openimsdk/open-im-server/v3/internal/rpc/relation"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
@@ -54,7 +54,7 @@ import (
type userServer struct {
online cache.OnlineCache
db controller.UserDatabase
friendNotificationSender *friend.FriendNotificationSender
friendNotificationSender *relation.FriendNotificationSender
userNotificationSender *UserNotificationSender
friendRpcClient *rpcclient.FriendRpcClient
groupRpcClient *rpcclient.GroupRpcClient
@@ -105,7 +105,7 @@ func Start(ctx context.Context, config *Config, client registry.SvcDiscoveryRegi
RegisterCenter: client,
friendRpcClient: &friendRpcClient,
groupRpcClient: &groupRpcClient,
friendNotificationSender: friend.NewFriendNotificationSender(&config.NotificationConfig, &msgRpcClient, friend.WithDBFunc(database.FindWithError)),
friendNotificationSender: relation.NewFriendNotificationSender(&config.NotificationConfig, &msgRpcClient, relation.WithDBFunc(database.FindWithError)),
userNotificationSender: NewUserNotificationSender(config, &msgRpcClient, WithUserFunc(database.FindWithError)),
config: config,
webhookClient: webhook.NewWebhookClient(config.WebhooksConfig.URL),
+53 -14
View File
@@ -17,16 +17,19 @@ package tools
import (
"context"
"fmt"
"os"
"time"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
pbconversation "github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/protocol/third"
"github.com/openimsdk/tools/mcontext"
"github.com/openimsdk/tools/mw"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"os"
"time"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
@@ -50,34 +53,69 @@ func Start(ctx context.Context, config *CronTaskConfig) error {
}
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
ctx = mcontext.SetOpUserID(ctx, config.Share.IMAdminUserID[0])
conn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Msg)
msgConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Msg)
if err != nil {
return err
}
cli := msg.NewMsgClient(conn)
thirdConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Third)
if err != nil {
return err
}
conversationConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Conversation)
if err != nil {
return err
}
msgClient := msg.NewMsgClient(msgConn)
conversationClient := pbconversation.NewConversationClient(conversationConn)
thirdClient := third.NewThirdClient(thirdConn)
crontab := cron.New()
clearFunc := func() {
// scheduled hard delete outdated Msgs in specific time.
clearMsgFunc := func() {
now := time.Now()
deltime := now.Add(-time.Hour * 24 * time.Duration(config.CronTask.RetainChatRecords))
ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), deltime.UnixMilli()))
log.ZInfo(ctx, "clear chat records", "deltime", deltime, "timestamp", deltime.UnixMilli())
if _, err := cli.ClearMsg(ctx, &msg.ClearMsgReq{Timestamp: deltime.UnixMilli()}); err != nil {
if _, err := msgClient.ClearMsg(ctx, &msg.ClearMsgReq{Timestamp: deltime.UnixMilli()}); err != nil {
log.ZError(ctx, "cron clear chat records failed", err, "deltime", deltime, "cont", time.Since(now))
return
}
log.ZInfo(ctx, "cron clear chat records success", "deltime", deltime, "cont", time.Since(now))
}
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, clearFunc); err != nil {
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, clearMsgFunc); err != nil {
return errs.Wrap(err)
}
tConn, err := client.GetConn(ctx, config.Share.RpcRegisterName.Third)
if err != nil {
return err
}
thirdClient := third.NewThirdClient(tConn)
// scheduled soft delete outdated Msgs in specific time when user set `is_msg_destruct` feature.
msgDestructFunc := func() {
now := time.Now()
ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), now.UnixMilli()))
log.ZInfo(ctx, "msg destruct cron start", "now", now)
deleteFunc := func() {
conversations, err := conversationClient.GetConversationsNeedDestructMsgs(ctx, &pbconversation.GetConversationsNeedDestructMsgsReq{})
if err != nil {
log.ZError(ctx, "Get conversation need Destruct msgs failed.", err)
return
} else {
_, err := msgClient.DestructMsgs(ctx, &msg.DestructMsgsReq{Conversations: conversations.Conversations})
if err != nil {
log.ZError(ctx, "Destruct Msgs failed.", err)
return
}
}
log.ZInfo(ctx, "msg destruct cron task completed", "cont", time.Since(now))
}
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, msgDestructFunc); err != nil {
return errs.Wrap(err)
}
// scheduled delete outdated file Objects and their datas in specific time.
deleteObjectFunc := func() {
now := time.Now()
deleteTime := now.Add(-time.Hour * 24 * time.Duration(config.CronTask.FileExpireTime))
ctx := mcontext.SetOperationID(ctx, fmt.Sprintf("cron_%d_%d", os.Getpid(), deleteTime.UnixMilli()))
@@ -88,9 +126,10 @@ func Start(ctx context.Context, config *CronTaskConfig) error {
}
log.ZInfo(ctx, "cron deleteoutDatedData success", "deltime", deleteTime, "cont", time.Since(now))
}
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, deleteFunc); err != nil {
if _, err := crontab.AddFunc(config.CronTask.CronExecuteTime, deleteObjectFunc); err != nil {
return errs.Wrap(err)
}
log.ZInfo(ctx, "start cron task", "CronExecuteTime", config.CronTask.CronExecuteTime)
crontab.Start()
<-ctx.Done()
+1 -1
View File
@@ -56,7 +56,7 @@ const (
CallbackBeforeUpdateUserInfoCommand = "callbackBeforeUpdateUserInfoCommand"
CallbackBeforeCreateGroupCommand = "callbackBeforeCreateGroupCommand"
CallbackAfterCreateGroupCommand = "callbackAfterCreateGroupCommand"
CallbackBeforeMemberJoinGroupCommand = "callbackBeforeMemberJoinGroupCommand"
CallbackBeforeMembersJoinGroupCommand = "callbackBeforeMembersJoinGroupCommand"
CallbackBeforeSetGroupMemberInfoCommand = "callbackBeforeSetGroupMemberInfoCommand"
CallbackAfterSetGroupMemberInfoCommand = "callbackAfterSetGroupMemberInfoCommand"
)
+17 -8
View File
@@ -59,16 +59,20 @@ type CallbackAfterCreateGroupResp struct {
CommonCallbackResp
}
type CallbackBeforeMemberJoinGroupReq struct {
CallbackCommand `json:"callbackCommand"`
GroupID string `json:"groupID"`
UserID string `json:"userID"`
Ex string `json:"ex"`
GroupEx string `json:"groupEx"`
type CallbackGroupMember struct {
UserID string `json:"userID"`
Ex string `json:"ex"`
}
type CallbackBeforeMemberJoinGroupResp struct {
CommonCallbackResp
type CallbackBeforeMembersJoinGroupReq struct {
CallbackCommand `json:"callbackCommand"`
GroupID string `json:"groupID"`
MembersList []*CallbackGroupMember `json:"memberList"`
GroupEx string `json:"groupEx"`
}
type MemberJoinGroupCallBack struct {
UserID *string `json:"userID"`
Nickname *string `json:"nickname"`
FaceURL *string `json:"faceURL"`
RoleLevel *int32 `json:"roleLevel"`
@@ -76,6 +80,11 @@ type CallbackBeforeMemberJoinGroupResp struct {
Ex *string `json:"ex"`
}
type CallbackBeforeMembersJoinGroupResp struct {
CommonCallbackResp
MemberCallbackList []*MemberJoinGroupCallBack `json:"memberCallbackList"`
}
type CallbackBeforeSetGroupMemberInfoReq struct {
CallbackCommand `json:"callbackCommand"`
GroupID string `json:"groupID"`
+3 -2
View File
@@ -16,8 +16,9 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/api"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -38,7 +39,7 @@ func NewApiCmd() *ApiCmd {
DiscoveryConfigFilename: &apiConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -40,7 +41,7 @@ func NewAuthRpcCmd() *AuthRpcCmd {
DiscoveryConfigFilename: &authConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -43,7 +44,7 @@ func NewConversationRpcCmd() *ConversationRpcCmd {
DiscoveryConfigFilename: &conversationConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,8 +16,9 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/tools"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -38,7 +39,7 @@ func NewCronTaskCmd() *CronTaskCmd {
DiscoveryConfigFilename: &cronTaskConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+20 -19
View File
@@ -16,35 +16,36 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/internal/rpc/relation"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
type FriendRpcCmd struct {
*RootCmd
ctx context.Context
configMap map[string]any
friendConfig *friend.Config
ctx context.Context
configMap map[string]any
relationConfig *relation.Config
}
func NewFriendRpcCmd() *FriendRpcCmd {
var friendConfig friend.Config
ret := &FriendRpcCmd{friendConfig: &friendConfig}
var relationConfig relation.Config
ret := &FriendRpcCmd{relationConfig: &relationConfig}
ret.configMap = map[string]any{
OpenIMRPCFriendCfgFileName: &friendConfig.RpcConfig,
RedisConfigFileName: &friendConfig.RedisConfig,
MongodbConfigFileName: &friendConfig.MongodbConfig,
ShareFileName: &friendConfig.Share,
NotificationFileName: &friendConfig.NotificationConfig,
WebhooksConfigFileName: &friendConfig.WebhooksConfig,
LocalCacheConfigFileName: &friendConfig.LocalCacheConfig,
DiscoveryConfigFilename: &friendConfig.Discovery,
OpenIMRPCFriendCfgFileName: &relationConfig.RpcConfig,
RedisConfigFileName: &relationConfig.RedisConfig,
MongodbConfigFileName: &relationConfig.MongodbConfig,
ShareFileName: &relationConfig.Share,
NotificationFileName: &relationConfig.NotificationConfig,
WebhooksConfigFileName: &relationConfig.WebhooksConfig,
LocalCacheConfigFileName: &relationConfig.LocalCacheConfig,
DiscoveryConfigFilename: &relationConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
@@ -56,7 +57,7 @@ func (a *FriendRpcCmd) Exec() error {
}
func (a *FriendRpcCmd) runE() error {
return startrpc.Start(a.ctx, &a.friendConfig.Discovery, &a.friendConfig.RpcConfig.Prometheus, a.friendConfig.RpcConfig.RPC.ListenIP,
a.friendConfig.RpcConfig.RPC.RegisterIP, a.friendConfig.RpcConfig.RPC.Ports,
a.Index(), a.friendConfig.Share.RpcRegisterName.Friend, &a.friendConfig.Share, a.friendConfig, friend.Start)
return startrpc.Start(a.ctx, &a.relationConfig.Discovery, &a.relationConfig.RpcConfig.Prometheus, a.relationConfig.RpcConfig.RPC.ListenIP,
a.relationConfig.RpcConfig.RPC.RegisterIP, a.relationConfig.RpcConfig.RPC.Ports,
a.Index(), a.relationConfig.Share.RpcRegisterName.Friend, &a.relationConfig.Share, a.relationConfig, relation.Start)
}
+3 -2
View File
@@ -16,10 +16,11 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/versionctx"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -45,7 +46,7 @@ func NewGroupRpcCmd() *GroupRpcCmd {
DiscoveryConfigFilename: &groupConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -45,7 +46,7 @@ func NewMsgRpcCmd() *MsgRpcCmd {
DiscoveryConfigFilename: &msgConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+2 -2
View File
@@ -16,9 +16,9 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
@@ -42,7 +42,7 @@ func NewMsgGatewayCmd() *MsgGatewayCmd {
DiscoveryConfigFilename: &msgGatewayConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,8 +16,9 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/msgtransfer"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -42,7 +43,7 @@ func NewMsgTransferCmd() *MsgTransferCmd {
DiscoveryConfigFilename: &msgTransferConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/push"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -45,7 +46,7 @@ func NewPushRpcCmd() *PushRpcCmd {
DiscoveryConfigFilename: &pushConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
ret.pushConfig.FcmConfigPath = ret.ConfigPath()
return ret.runE()
+3 -2
View File
@@ -19,6 +19,7 @@ import (
"path/filepath"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/spf13/cobra"
@@ -138,13 +139,13 @@ func (r *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
r.log.StorageLocation,
r.log.RemainRotationCount,
r.log.RotationTime,
config.Version,
version.Version,
r.log.IsSimplify,
)
if err != nil {
return errs.Wrap(err)
}
return errs.Wrap(log.InitConsoleLogger(r.processName, r.log.RemainLogLevel, r.log.IsJson, config.Version))
return errs.Wrap(log.InitConsoleLogger(r.processName, r.log.RemainLogLevel, r.log.IsJson, version.Version))
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -44,7 +45,7 @@ func NewThirdRpcCmd() *ThirdRpcCmd {
DiscoveryConfigFilename: &thirdConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
+3 -2
View File
@@ -16,9 +16,10 @@ package cmd
import (
"context"
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
"github.com/openimsdk/open-im-server/v3/version"
"github.com/openimsdk/tools/system/program"
"github.com/spf13/cobra"
)
@@ -45,7 +46,7 @@ func NewUserRpcCmd() *UserRpcCmd {
DiscoveryConfigFilename: &userConfig.Discovery,
}
ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
ret.ctx = context.WithValue(context.Background(), "version", config.Version)
ret.ctx = context.WithValue(context.Background(), "version", version.Version)
ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
return ret.runE()
}
-4
View File
@@ -15,7 +15,6 @@
package config
import (
_ "embed"
"os"
"path/filepath"
@@ -26,9 +25,6 @@ import (
"gopkg.in/yaml.v3"
)
//go:embed version
var Version string
const (
FileName = "config.yaml"
NotificationFileName = "notification.yaml"
-1
View File
@@ -1 +0,0 @@
3.7.0
+2 -2
View File
@@ -22,7 +22,7 @@ import (
func ConversationDB2Pb(conversationDB *model.Conversation) *conversation.Conversation {
conversationPB := &conversation.Conversation{}
conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.Unix()
conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.UnixMilli()
if err := datautil.CopyStructFields(conversationPB, conversationDB); err != nil {
return nil
}
@@ -35,7 +35,7 @@ func ConversationsDB2Pb(conversationsDB []*model.Conversation) (conversationsPB
if err := datautil.CopyStructFields(conversationPB, conversationDB); err != nil {
continue
}
conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.Unix()
conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.UnixMilli()
conversationsPB = append(conversationsPB, conversationPB)
}
return conversationsPB
+1 -1
View File
@@ -45,7 +45,7 @@ func TestName(t *testing.T) {
}
seqUser := NewSeqUserCacheRedis(rdb, mgoSeqUser)
res, err := seqUser.GetReadSeqs(ctx, "2110910952", []string{"sg_2920732023", "sg_345762580"})
res, err := seqUser.GetUserReadSeqs(ctx, "2110910952", []string{"sg_2920732023", "sg_345762580"})
if err != nil {
panic(err)
}
+5 -1
View File
@@ -5,6 +5,7 @@ import (
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/redis/go-redis/v9"
"strconv"
"time"
@@ -82,8 +83,11 @@ func (s *userOnline) SetUserOnline(ctx context.Context, userID string, online, o
argv = append(argv, platformID)
}
keys := []string{s.getUserOnlineKey(userID), userID, s.channelName}
if err := s.rdb.Eval(ctx, script, keys, argv).Err(); err != nil {
status, err := s.rdb.Eval(ctx, script, keys, argv).Result()
if err != nil {
log.ZError(ctx, "redis SetUserOnline", err, "userID", userID, "online", online, "offline", offline)
return err
}
log.ZDebug(ctx, "redis SetUserOnline", "userID", userID, "online", online, "offline", offline, "status", status)
return nil
}
+32
View File
@@ -4,7 +4,10 @@ import (
"context"
"fmt"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
mgo2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo"
"github.com/redis/go-redis/v9"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"strconv"
"sync/atomic"
@@ -77,3 +80,32 @@ func TestRecvOnline(t *testing.T) {
fmt.Printf("Received message from channel %s: %s\n", msg.Channel, msg.Payload)
}
}
func TestName1(t *testing.T) {
opt := &redis.Options{
Addr: "172.16.8.48:16379",
Password: "openIM123",
DB: 0,
}
rdb := redis.NewClient(opt)
mgo, err := mongo.Connect(context.Background(),
options.Client().
ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").
SetConnectTimeout(5*time.Second))
if err != nil {
panic(err)
}
model, err := mgo2.NewSeqUserMongo(mgo.Database("openim_v3"))
if err != nil {
panic(err)
}
seq := NewSeqUserCacheRedis(rdb, model)
res, err := seq.GetUserReadSeqs(context.Background(), "2110910952", []string{"sg_345762580", "2000", "3000"})
if err != nil {
panic(err)
}
t.Log(res)
}
+39 -26
View File
@@ -152,42 +152,55 @@ func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string,
return f.tx.Transaction(ctx, func(ctx context.Context) error {
cache := f.cache.CloneFriendCache()
// user find friends
fs1, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs)
myFriends, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs)
if err != nil {
return err
}
addOwners, err := f.friend.FindReversalFriends(ctx, ownerUserID, friendUserIDs)
if err != nil {
return err
}
opUserID := mcontext.GetOperationID(ctx)
for _, v := range friendUserIDs {
fs1 = append(fs1, &model.Friend{OwnerUserID: ownerUserID, FriendUserID: v, AddSource: addSource, OperatorUserID: opUserID})
}
fs11 := datautil.DistinctAny(fs1, func(e *model.Friend) string {
return e.FriendUserID
friends := make([]*model.Friend, 0, len(friendUserIDs)*2)
myFriendsSet := datautil.SliceSetAny(myFriends, func(friend *model.Friend) string {
return friend.FriendUserID
})
err = f.friend.Create(ctx, fs11)
if err != nil {
return err
}
fs2, err := f.friend.FindReversalFriends(ctx, ownerUserID, friendUserIDs)
if err != nil {
return err
}
var newFriendIDs []string
for _, v := range friendUserIDs {
fs2 = append(fs2, &model.Friend{OwnerUserID: v, FriendUserID: ownerUserID, AddSource: addSource, OperatorUserID: opUserID})
newFriendIDs = append(newFriendIDs, v)
}
fs22 := datautil.DistinctAny(fs2, func(e *model.Friend) string {
return e.OwnerUserID
addOwnersSet := datautil.SliceSetAny(addOwners, func(friend *model.Friend) string {
return friend.OwnerUserID
})
err = f.friend.Create(ctx, fs22)
newMyFriendIDs := make([]string, 0, len(friendUserIDs))
newMyOwnerIDs := make([]string, 0, len(friendUserIDs))
for _, userID := range friendUserIDs {
if ownerUserID == userID {
continue
}
if _, ok := myFriendsSet[userID]; !ok {
myFriendsSet[userID] = struct{}{}
newMyFriendIDs = append(newMyFriendIDs, userID)
friends = append(friends, &model.Friend{OwnerUserID: ownerUserID, FriendUserID: userID, AddSource: addSource, OperatorUserID: opUserID})
}
if _, ok := addOwnersSet[userID]; !ok {
addOwnersSet[userID] = struct{}{}
newMyOwnerIDs = append(newMyOwnerIDs, userID)
friends = append(friends, &model.Friend{OwnerUserID: userID, FriendUserID: ownerUserID, AddSource: addSource, OperatorUserID: opUserID})
}
}
if len(friends) == 0 {
return nil
}
err = f.friend.Create(ctx, friends)
if err != nil {
return err
}
newFriendIDs = append(newFriendIDs, ownerUserID)
cache = cache.DelFriendIDs(newFriendIDs...).DelMaxFriendVersion(newFriendIDs...)
if len(newMyFriendIDs) > 0 {
cache = cache.DelFriendIDs(newMyFriendIDs...)
cache = cache.DelFriends(ownerUserID, newMyFriendIDs).DelMaxFriendVersion(newMyFriendIDs...)
}
if len(newMyOwnerIDs) > 0 {
cache = cache.DelFriendIDs(newMyOwnerIDs...)
cache = cache.DelOwner(ownerUserID, newMyOwnerIDs).DelMaxFriendVersion(newMyOwnerIDs...)
}
return cache.ChainExecDel(ctx)
})
}
+3 -3
View File
@@ -84,7 +84,7 @@ type CommonMsgDatabase interface {
//GetConversationMinMaxSeqInMongoAndCache(ctx context.Context, conversationID string) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error)
SetSendMsgStatus(ctx context.Context, id string, status int32) error
GetSendMsgStatus(ctx context.Context, id string) (int32, error)
SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error)
SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int64, msgData []*sdkws.MsgData, err error)
FindOneByDocIDs(ctx context.Context, docIDs []string, seqs map[string]int64) (map[string]*sdkws.MsgData, error)
// to mq
@@ -721,7 +721,7 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio
}
log.ZDebug(ctx, "doc info", "conversationID", conversationID, "index", index, "docID", msgDocModel.DocID, "len", len(msgDocModel.Msg))
if int64(len(msgDocModel.Msg)) > db.msgTable.GetSingleGocMsgNum() {
log.ZWarn(ctx, "msgs too large", nil, "lenth", len(msgDocModel.Msg), "docID:", msgDocModel.DocID)
log.ZWarn(ctx, "msgs too large", nil, "length", len(msgDocModel.Msg), "docID:", msgDocModel.DocID)
}
if msgDocModel.IsFull() && msgDocModel.Msg[len(msgDocModel.Msg)-1].Msg.SendTime+(remainTime*1000) < timeutil.GetCurrentTimestampByMill() {
log.ZDebug(ctx, "doc is full and all msg is expired", "docID", msgDocModel.DocID)
@@ -878,7 +878,7 @@ func (db *commonMsgDatabase) RangeGroupSendCount(
return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber)
}
func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int32, msgData []*sdkws.MsgData, err error) {
func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbmsg.SearchMessageReq) (total int64, msgData []*sdkws.MsgData, err error) {
var totalMsgs []*sdkws.MsgData
total, msgs, err := db.msgDocDatabase.SearchMessage(ctx, req)
if err != nil {
+383 -87
View File
@@ -278,124 +278,420 @@ func (m *MsgMgo) MarkSingleChatMsgsAsRead(ctx context.Context, userID string, do
return nil
}
func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*model.MsgInfoModel, error) {
where := make(bson.A, 0, 6)
//func (m *MsgMgo) searchCount(ctx context.Context, filter any) (int64, error) {
//
// return nil, nil
//}
//func (m *MsgMgo) searchMessage(ctx context.Context, filter any, nextID primitive.ObjectID, content bool, limit int) (int64, []*model.MsgInfoModel, primitive.ObjectID, error) {
// var pipeline bson.A
// if !nextID.IsZero() {
// pipeline = append(pipeline, bson.M{"$match": bson.M{"_id": bson.M{"$gt": nextID}}})
// }
// pipeline = append(pipeline,
// bson.M{"$match": filter},
// bson.M{"$limit": limit},
// bson.M{"$unwind": "$msgs"},
// bson.M{"$match": filter},
// bson.M{
// "$group": bson.M{
// "_id": "$_id",
// "doc_id": bson.M{
// "$first": "$doc_id",
// },
// "msgs": bson.M{"$push": "$msgs"},
// },
// },
// )
// if !content {
// pipeline = append(pipeline,
// bson.M{
// "$project": bson.M{
// "_id": 1,
// "count": bson.M{"$size": "$msgs"},
// },
// },
// )
// type result struct {
// ID primitive.ObjectID `bson:"_id"`
// Count int64 `bson:"count"`
// }
// res, err := mongoutil.Aggregate[result](ctx, m.coll, pipeline)
// if err != nil {
// return 0, nil, primitive.ObjectID{}, err
// }
// if len(res) == 0 {
// return 0, nil, primitive.ObjectID{}, nil
// }
// var count int64
// for _, r := range res {
// count += r.Count
// }
// return count, nil, res[len(res)-1].ID, nil
// }
// type result struct {
// ID primitive.ObjectID `bson:"_id"`
// Msg []*model.MsgInfoModel `bson:"msgs"`
// }
// res, err := mongoutil.Aggregate[result](ctx, m.coll, pipeline)
// if err != nil {
// return 0, nil, primitive.ObjectID{}, err
// }
// if len(res) == 0 {
// return 0, nil, primitive.ObjectID{}, err
// }
// var count int
// for _, r := range res {
// count += len(r.Msg)
// }
// msgs := make([]*model.MsgInfoModel, 0, count)
// for _, r := range res {
// msgs = append(msgs, r.Msg...)
// }
// return int64(count), msgs, res[len(res)-1].ID, nil
//}
/*
db.msg3.aggregate(
[
{
"$match": {
"doc_id": "si_7009965934_8710838466:0"
},
}
]
)
*/
type searchMessageIndex struct {
ID primitive.ObjectID `bson:"_id"`
Index []int64 `bson:"index"`
}
func (m *MsgMgo) searchMessageIndex(ctx context.Context, filter any, nextID primitive.ObjectID, limit int) ([]searchMessageIndex, error) {
var pipeline bson.A
if !nextID.IsZero() {
pipeline = append(pipeline, bson.M{"$match": bson.M{"_id": bson.M{"$gt": nextID}}})
}
coarseFilter := bson.M{
"$or": bson.A{
bson.M{
"doc_id": primitive.Regex{Pattern: "^sg_"},
},
bson.M{
"doc_id": primitive.Regex{Pattern: "^si_"},
},
},
}
pipeline = append(pipeline,
bson.M{"$sort": bson.M{"_id": 1}},
bson.M{"$match": coarseFilter},
bson.M{"$match": filter},
bson.M{"$limit": limit},
bson.M{
"$project": bson.M{
"_id": 1,
"msgs": bson.M{
"$map": bson.M{
"input": "$msgs",
"as": "msg",
"in": bson.M{
"$mergeObjects": bson.A{
"$$msg",
bson.M{
"_search_temp_index": bson.M{
"$indexOfArray": bson.A{
"$msgs", "$$msg",
},
},
},
},
},
},
},
},
},
bson.M{"$unwind": "$msgs"},
bson.M{"$match": filter},
bson.M{
"$project": bson.M{
"_id": 1,
"msgs._search_temp_index": 1,
},
},
bson.M{
"$group": bson.M{
"_id": "$_id",
"index": bson.M{"$push": "$msgs._search_temp_index"},
},
},
bson.M{"$sort": bson.M{"_id": 1}},
)
return mongoutil.Aggregate[searchMessageIndex](ctx, m.coll, pipeline)
}
func (m *MsgMgo) searchMessage(ctx context.Context, req *msg.SearchMessageReq) (int64, []searchMessageIndex, error) {
filter := bson.M{}
if req.RecvID != "" {
where = append(where, bson.M{"msgs.msg.recv_id": req.RecvID})
filter["$or"] = bson.A{
bson.M{"msgs.msg.recv_id": req.RecvID},
bson.M{"msgs.msg.group_id": req.RecvID},
}
}
if req.SendID != "" {
where = append(where, bson.M{"msgs.msg.send_id": req.SendID})
filter["msgs.msg.send_id"] = req.SendID
}
if req.ContentType != 0 {
where = append(where, bson.M{"msgs.msg.content_type": req.ContentType})
filter["msgs.msg.content_type"] = req.ContentType
}
if req.SessionType != 0 {
where = append(where, bson.M{"msgs.msg.session_type": req.SessionType})
filter["msgs.msg.session_type"] = req.SessionType
}
if req.SendTime != "" {
sendTime, err := time.Parse(time.DateOnly, req.SendTime)
if err != nil {
return 0, nil, errs.ErrArgs.WrapMsg("invalid sendTime", "req", req.SendTime, "format", time.DateOnly, "cause", err.Error())
}
where = append(where,
bson.M{
"msgs.msg.send_time": bson.M{
"$gte": sendTime.UnixMilli(),
},
},
filter["$and"] = bson.A{
bson.M{"msgs.msg.send_time": bson.M{
"$gte": sendTime.UnixMilli(),
}},
bson.M{
"msgs.msg.send_time": bson.M{
"$lt": sendTime.Add(time.Hour * 24).UnixMilli(),
},
},
)
}
}
var (
nextID primitive.ObjectID
count int
dataRange []searchMessageIndex
skip = int((req.Pagination.GetPageNumber() - 1) * req.Pagination.GetShowNumber())
)
_, _ = dataRange, skip
const maxDoc = 50
data := make([]searchMessageIndex, 0, req.Pagination.GetShowNumber())
push := cap(data)
for i := 0; ; i++ {
res, err := m.searchMessageIndex(ctx, filter, nextID, maxDoc)
if err != nil {
return 0, nil, err
}
if len(res) > 0 {
nextID = res[len(res)-1].ID
}
for _, r := range res {
var dataIndex []int64
for _, index := range r.Index {
if push > 0 && count >= skip {
dataIndex = append(dataIndex, index)
push--
}
count++
}
if len(dataIndex) > 0 {
data = append(data, searchMessageIndex{
ID: r.ID,
Index: dataIndex,
})
}
}
if push <= 0 {
push--
}
if len(res) < maxDoc || push < -10 {
return int64(count), data, nil
}
}
}
func (m *MsgMgo) getDocRange(ctx context.Context, id primitive.ObjectID, index []int64) ([]*model.MsgInfoModel, error) {
if len(index) == 0 {
return nil, nil
}
pipeline := bson.A{
bson.M{
"$unwind": "$msgs",
},
bson.M{"$match": bson.M{"_id": id}},
bson.M{"$project": "$msgs"},
}
if len(where) > 0 {
pipeline = append(pipeline, bson.M{
"$match": bson.M{"$and": where},
})
}
pipeline = append(pipeline,
bson.M{
"$project": bson.M{
"_id": 0,
"msg": "$msgs.msg",
},
},
bson.M{
"$count": "count",
},
)
count, err := mongoutil.Aggregate[int32](ctx, m.coll, pipeline)
if err != nil {
return 0, nil, err
}
if len(count) == 0 || count[0] == 0 {
return 0, nil, nil
}
pipeline = pipeline[:len(pipeline)-1]
pipeline = append(pipeline,
bson.M{
"$skip": (req.Pagination.GetPageNumber() - 1) * req.Pagination.GetShowNumber(),
},
bson.M{
"$limit": req.Pagination.GetShowNumber(),
},
)
msgs, err := mongoutil.Aggregate[*model.MsgInfoModel](ctx, m.coll, pipeline)
if err != nil {
return nil, err
}
return msgs, nil
}
func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int64, []*model.MsgInfoModel, error) {
count, data, err := m.searchMessage(ctx, req)
if err != nil {
return 0, nil, err
}
for i := range msgs {
msgInfo := msgs[i]
if msgInfo == nil || msgInfo.Msg == nil {
continue
var msgs []*model.MsgInfoModel
if len(data) > 0 {
var n int
for _, d := range data {
n += len(d.Index)
}
if msgInfo.Revoke != nil {
revokeContent := sdkws.MessageRevokedContent{
RevokerID: msgInfo.Revoke.UserID,
RevokerRole: msgInfo.Revoke.Role,
ClientMsgID: msgInfo.Msg.ClientMsgID,
RevokerNickname: msgInfo.Revoke.Nickname,
RevokeTime: msgInfo.Revoke.Time,
SourceMessageSendTime: msgInfo.Msg.SendTime,
SourceMessageSendID: msgInfo.Msg.SendID,
SourceMessageSenderNickname: msgInfo.Msg.SenderNickname,
SessionType: msgInfo.Msg.SessionType,
Seq: msgInfo.Msg.Seq,
Ex: msgInfo.Msg.Ex,
msgs = make([]*model.MsgInfoModel, 0, n)
}
for _, val := range data {
res, err := mongoutil.FindOne[*model.MsgDocModel](ctx, m.coll, bson.M{"_id": val.ID})
if err != nil {
return 0, nil, err
}
for _, i := range val.Index {
if i >= int64(len(res.Msg)) {
continue
}
data, err := jsonutil.JsonMarshal(&revokeContent)
if err != nil {
return 0, nil, errs.WrapMsg(err, "json.Marshal revokeContent")
}
elem := sdkws.NotificationElem{Detail: string(data)}
content, err := jsonutil.JsonMarshal(&elem)
if err != nil {
return 0, nil, errs.WrapMsg(err, "json.Marshal elem")
}
msgInfo.Msg.ContentType = constant.MsgRevokeNotification
msgInfo.Msg.Content = string(content)
msgs = append(msgs, res.Msg[i])
}
}
//start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
//n := int32(len(msgs))
//if start >= n {
// return n, []*relation.MsgInfoModel{}, nil
//}
//if start+req.Pagination.ShowNumber < n {
// msgs = msgs[start : start+req.Pagination.ShowNumber]
//} else {
// msgs = msgs[start:]
//}
return count[0], msgs, nil
return count, msgs, nil
}
//func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*model.MsgInfoModel, error) {
// where := make(bson.A, 0, 6)
// if req.RecvID != "" {
// if req.SessionType == constant.ReadGroupChatType {
// where = append(where, bson.M{
// "$or": bson.A{
// bson.M{"doc_id": "^n_" + req.RecvID + ":"},
// bson.M{"doc_id": "^sg_" + req.RecvID + ":"},
// },
// })
// } else {
// where = append(where, bson.M{"msgs.msg.recv_id": req.RecvID})
// }
// }
// if req.SendID != "" {
// where = append(where, bson.M{"msgs.msg.send_id": req.SendID})
// }
// if req.ContentType != 0 {
// where = append(where, bson.M{"msgs.msg.content_type": req.ContentType})
// }
// if req.SessionType != 0 {
// where = append(where, bson.M{"msgs.msg.session_type": req.SessionType})
// }
// if req.SendTime != "" {
// sendTime, err := time.Parse(time.DateOnly, req.SendTime)
// if err != nil {
// return 0, nil, errs.ErrArgs.WrapMsg("invalid sendTime", "req", req.SendTime, "format", time.DateOnly, "cause", err.Error())
// }
// where = append(where,
// bson.M{
// "msgs.msg.send_time": bson.M{
// "$gte": sendTime.UnixMilli(),
// },
// },
// bson.M{
// "msgs.msg.send_time": bson.M{
// "$lt": sendTime.Add(time.Hour * 24).UnixMilli(),
// },
// },
// )
// }
// opt := options.Find().SetLimit(100)
// res, err := mongoutil.Find[model.MsgDocModel](ctx, m.coll, bson.M{"$and": where}, opt)
// if err != nil {
// return 0, nil, err
// }
// _ = res
// fmt.Println()
//
// return 0, nil, nil
// pipeline := bson.A{
// bson.M{
// "$unwind": "$msgs",
// },
// }
// if len(where) > 0 {
// pipeline = append(pipeline, bson.M{
// "$match": bson.M{"$and": where},
// })
// }
// pipeline = append(pipeline,
// bson.M{
// "$project": bson.M{
// "_id": 0,
// "msg": "$msgs.msg",
// },
// },
// bson.M{
// "$count": "count",
// },
// )
// //count, err := mongoutil.Aggregate[int32](ctx, m.coll, pipeline)
// //if err != nil {
// // return 0, nil, err
// //}
// //if len(count) == 0 || count[0] == 0 {
// // return 0, nil, nil
// //}
// count := []int32{0}
// pipeline = pipeline[:len(pipeline)-1]
// pipeline = append(pipeline,
// bson.M{
// "$skip": (req.Pagination.GetPageNumber() - 1) * req.Pagination.GetShowNumber(),
// },
// bson.M{
// "$limit": req.Pagination.GetShowNumber(),
// },
// )
// msgs, err := mongoutil.Aggregate[*model.MsgInfoModel](ctx, m.coll, pipeline)
// if err != nil {
// return 0, nil, err
// }
// for i := range msgs {
// msgInfo := msgs[i]
// if msgInfo == nil || msgInfo.Msg == nil {
// continue
// }
// if msgInfo.Revoke != nil {
// revokeContent := sdkws.MessageRevokedContent{
// RevokerID: msgInfo.Revoke.UserID,
// RevokerRole: msgInfo.Revoke.Role,
// ClientMsgID: msgInfo.Msg.ClientMsgID,
// RevokerNickname: msgInfo.Revoke.Nickname,
// RevokeTime: msgInfo.Revoke.Time,
// SourceMessageSendTime: msgInfo.Msg.SendTime,
// SourceMessageSendID: msgInfo.Msg.SendID,
// SourceMessageSenderNickname: msgInfo.Msg.SenderNickname,
// SessionType: msgInfo.Msg.SessionType,
// Seq: msgInfo.Msg.Seq,
// Ex: msgInfo.Msg.Ex,
// }
// data, err := jsonutil.JsonMarshal(&revokeContent)
// if err != nil {
// return 0, nil, errs.WrapMsg(err, "json.Marshal revokeContent")
// }
// elem := sdkws.NotificationElem{Detail: string(data)}
// content, err := jsonutil.JsonMarshal(&elem)
// if err != nil {
// return 0, nil, errs.WrapMsg(err, "json.Marshal elem")
// }
// msgInfo.Msg.ContentType = constant.MsgRevokeNotification
// msgInfo.Msg.Content = string(content)
// }
// }
// //start := (req.Pagination.PageNumber - 1) * req.Pagination.ShowNumber
// //n := int32(len(msgs))
// //if start >= n {
// // return n, []*relation.MsgInfoModel{}, nil
// //}
// //if start+req.Pagination.ShowNumber < n {
// // msgs = msgs[start : start+req.Pagination.ShowNumber]
// //} else {
// // msgs = msgs[start:]
// //}
// return count[0], msgs, nil
//}
func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error) {
var sort int
if ase {
@@ -0,0 +1,75 @@
package mgo
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
"github.com/openimsdk/protocol/msg"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/db/mongoutil"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"math/rand"
"strconv"
"testing"
"time"
)
func TestName1(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*300)
defer cancel()
cli := Result(mongo.Connect(ctx, options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second)))
v := &MsgMgo{
coll: cli.Database("openim_v3").Collection("msg3"),
}
req := &msg.SearchMessageReq{
//RecvID: "3187706596",
//SendID: "7009965934",
ContentType: 101,
//SendTime: "2024-05-06",
//SessionType: 3,
Pagination: &sdkws.RequestPagination{
PageNumber: 1,
ShowNumber: 10,
},
}
total, res, err := v.SearchMessage(ctx, req)
if err != nil {
panic(err)
}
for i, re := range res {
t.Logf("%d => %d | %+v", i+1, re.Msg.Seq, re.Msg.Content)
}
t.Log(total)
}
func TestName10(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
cli := Result(mongo.Connect(ctx, options.Client().ApplyURI("mongodb://openIM:openIM123@172.16.8.48:37017/openim_v3?maxPoolSize=100").SetConnectTimeout(5*time.Second)))
v := &MsgMgo{
coll: cli.Database("openim_v3").Collection("msg3"),
}
opt := options.Find().SetLimit(1000)
res, err := mongoutil.Find[model.MsgDocModel](ctx, v.coll, bson.M{}, opt)
if err != nil {
panic(err)
}
ctx = context.Background()
for i := 0; i < 100000; i++ {
for j := range res {
res[j].DocID = strconv.FormatUint(rand.Uint64(), 10) + ":0"
}
if err := mongoutil.InsertMany(ctx, v.coll, res); err != nil {
panic(err)
}
t.Log("====>", time.Now(), i)
}
}
@@ -26,7 +26,7 @@ func Mongodb() *mongo.Database {
func TestUserSeq(t *testing.T) {
uSeq := Result(NewSeqUserMongo(Mongodb())).(*seqUserMongo)
t.Log(uSeq.SetMinSeq(context.Background(), "1000", "2000", 4))
t.Log(uSeq.SetUserMinSeq(context.Background(), "1000", "2000", 4))
}
func TestConversationSeq(t *testing.T) {
@@ -35,3 +35,8 @@ func TestConversationSeq(t *testing.T) {
t.Log(cSeq.Malloc(context.Background(), "2000", 10))
t.Log(cSeq.GetMaxSeq(context.Background(), "2000"))
}
func TestUserGetUserReadSeqs(t *testing.T) {
uSeq := Result(NewSeqUserMongo(Mongodb())).(*seqUserMongo)
t.Log(uSeq.GetUserReadSeqs(context.Background(), "2110910952", []string{"sg_345762580", "2000", "3000"}))
}
@@ -88,6 +88,14 @@ func (s *seqUserMongo) GetUserReadSeq(ctx context.Context, conversationID string
return s.getSeq(ctx, conversationID, userID, "read_seq")
}
func (s *seqUserMongo) notFoundSet0(seq map[string]int64, conversationIDs []string) {
for _, conversationID := range conversationIDs {
if _, ok := seq[conversationID]; !ok {
seq[conversationID] = 0
}
}
}
func (s *seqUserMongo) GetUserReadSeqs(ctx context.Context, userID string, conversationID []string) (map[string]int64, error) {
if len(conversationID) == 0 {
return map[string]int64{}, nil
@@ -102,6 +110,7 @@ func (s *seqUserMongo) GetUserReadSeqs(ctx context.Context, userID string, conve
for _, seq := range seqs {
res[seq.ConversationID] = seq.ReadSeq
}
s.notFoundSet0(res, conversationID)
return res, nil
}
+1 -1
View File
@@ -37,7 +37,7 @@ type Msg interface {
GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*model.MsgDocModel, error)
DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error
MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error
SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*model.MsgInfoModel, error)
SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int64, []*model.MsgInfoModel, error)
RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error)
RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*model.GroupCount, dateCount map[string]int64, err error)
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
+43
View File
@@ -14,6 +14,11 @@
package rpccache
import (
"github.com/openimsdk/tools/errs"
"google.golang.org/protobuf/proto"
)
func newListMap[V comparable](values []V, err error) (*listMap[V], error) {
if err != nil {
return nil, err
@@ -32,3 +37,41 @@ type listMap[V comparable] struct {
List []V
Map map[V]struct{}
}
func respProtoMarshal(resp proto.Message, err error) ([]byte, error) {
if err != nil {
return nil, err
}
return proto.Marshal(resp)
}
func cacheUnmarshal[V any](resp []byte, err error) (*V, error) {
if err != nil {
return nil, err
}
var val V
if err := proto.Unmarshal(resp, any(&val).(proto.Message)); err != nil {
return nil, errs.WrapMsg(err, "local cache proto.Unmarshal error")
}
return &val, nil
}
type cacheProto[V any] struct{}
func (cacheProto[V]) Marshal(resp *V, err error) ([]byte, error) {
if err != nil {
return nil, err
}
return proto.Marshal(any(resp).(proto.Message))
}
func (cacheProto[V]) Unmarshal(resp []byte, err error) (*V, error) {
if err != nil {
return nil, err
}
var val V
if err := proto.Unmarshal(resp, any(&val).(proto.Message)); err != nil {
return nil, errs.WrapMsg(err, "local cache proto.Unmarshal error")
}
return &val, nil
}
+38 -17
View File
@@ -23,6 +23,7 @@ import (
pbconversation "github.com/openimsdk/protocol/conversation"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/utils/datautil"
"github.com/redis/go-redis/v9"
"golang.org/x/sync/errgroup"
)
@@ -36,7 +37,7 @@ func NewConversationLocalCache(client rpcclient.ConversationRpcClient, localCach
log.ZDebug(context.Background(), "ConversationLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable())
x := &ConversationLocalCache{
client: client,
local: localcache.New[any](
local: localcache.New[[]byte](
localcache.WithLocalSlotNum(lc.SlotNum),
localcache.WithLocalSlotSize(lc.SlotSize),
localcache.WithLinkSlotNum(lc.SlotNum),
@@ -52,21 +53,30 @@ func NewConversationLocalCache(client rpcclient.ConversationRpcClient, localCach
type ConversationLocalCache struct {
client rpcclient.ConversationRpcClient
local localcache.Cache[any]
local localcache.Cache[[]byte]
}
func (c *ConversationLocalCache) GetConversationIDs(ctx context.Context, ownerUserID string) (val []string, err error) {
log.ZDebug(ctx, "ConversationLocalCache GetConversationIDs req", "ownerUserID", ownerUserID)
resp, err := c.getConversationIDs(ctx, ownerUserID)
if err != nil {
return nil, err
}
return resp.ConversationIDs, nil
}
func (c *ConversationLocalCache) getConversationIDs(ctx context.Context, ownerUserID string) (val *pbconversation.GetConversationIDsResp, err error) {
log.ZDebug(ctx, "ConversationLocalCache getConversationIDs req", "ownerUserID", ownerUserID)
defer func() {
if err == nil {
log.ZDebug(ctx, "ConversationLocalCache GetConversationIDs return", "value", val)
log.ZDebug(ctx, "ConversationLocalCache getConversationIDs return", "ownerUserID", ownerUserID, "value", val)
} else {
log.ZError(ctx, "ConversationLocalCache GetConversationIDs return", err)
log.ZError(ctx, "ConversationLocalCache getConversationIDs return", err, "ownerUserID", ownerUserID)
}
}()
return localcache.AnyValue[[]string](c.local.Get(ctx, cachekey.GetConversationIDsKey(ownerUserID), func(ctx context.Context) (any, error) {
log.ZDebug(ctx, "ConversationLocalCache GetConversationIDs rpc", "ownerUserID", ownerUserID)
return c.client.GetConversationIDs(ctx, ownerUserID)
var cache cacheProto[pbconversation.GetConversationIDsResp]
return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationIDsKey(ownerUserID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "ConversationLocalCache getConversationIDs rpc", "ownerUserID", ownerUserID)
return cache.Marshal(c.client.Client.GetConversationIDs(ctx, &pbconversation.GetConversationIDsReq{UserID: ownerUserID}))
}))
}
@@ -74,14 +84,15 @@ func (c *ConversationLocalCache) GetConversation(ctx context.Context, userID, co
log.ZDebug(ctx, "ConversationLocalCache GetConversation req", "userID", userID, "conversationID", conversationID)
defer func() {
if err == nil {
log.ZDebug(ctx, "ConversationLocalCache GetConversation return", "value", val)
log.ZDebug(ctx, "ConversationLocalCache GetConversation return", "userID", userID, "conversationID", conversationID, "value", val)
} else {
log.ZError(ctx, "ConversationLocalCache GetConversation return", err)
log.ZError(ctx, "ConversationLocalCache GetConversation return", err, "userID", userID, "conversationID", conversationID)
}
}()
return localcache.AnyValue[*pbconversation.Conversation](c.local.Get(ctx, cachekey.GetConversationKey(userID, conversationID), func(ctx context.Context) (any, error) {
var cache cacheProto[pbconversation.Conversation]
return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationKey(userID, conversationID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "ConversationLocalCache GetConversation rpc", "userID", userID, "conversationID", conversationID)
return c.client.GetConversation(ctx, userID, conversationID)
return cache.Marshal(c.client.GetConversation(ctx, userID, conversationID))
}))
}
@@ -126,9 +137,19 @@ func (c *ConversationLocalCache) GetConversations(ctx context.Context, ownerUser
return conversations, nil
}
func (c *ConversationLocalCache) getConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) (*listMap[string], error) {
return localcache.AnyValue[*listMap[string]](c.local.Get(ctx, cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID), func(ctx context.Context) (any, error) {
return newListMap(c.client.GetConversationNotReceiveMessageUserIDs(ctx, conversationID))
func (c *ConversationLocalCache) getConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) (val *pbconversation.GetConversationNotReceiveMessageUserIDsResp, err error) {
log.ZDebug(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs req", "conversationID", conversationID)
defer func() {
if err == nil {
log.ZDebug(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs return", "conversationID", conversationID, "value", val)
} else {
log.ZError(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs return", err, "conversationID", conversationID)
}
}()
var cache cacheProto[pbconversation.GetConversationNotReceiveMessageUserIDsResp]
return cache.Unmarshal(c.local.Get(ctx, cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "ConversationLocalCache getConversationNotReceiveMessageUserIDs rpc", "conversationID", conversationID)
return cache.Marshal(c.client.Client.GetConversationNotReceiveMessageUserIDs(ctx, &pbconversation.GetConversationNotReceiveMessageUserIDsReq{ConversationID: conversationID}))
}))
}
@@ -137,7 +158,7 @@ func (c *ConversationLocalCache) GetConversationNotReceiveMessageUserIDs(ctx con
if err != nil {
return nil, err
}
return res.List, nil
return res.UserIDs, nil
}
func (c *ConversationLocalCache) GetConversationNotReceiveMessageUserIDMap(ctx context.Context, conversationID string) (map[string]struct{}, error) {
@@ -145,5 +166,5 @@ func (c *ConversationLocalCache) GetConversationNotReceiveMessageUserIDMap(ctx c
if err != nil {
return nil, err
}
return res.Map, nil
return datautil.SliceSet(res.UserIDs), nil
}
+36 -16
View File
@@ -16,7 +16,8 @@ package rpccache
import (
"context"
cachekey2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/protocol/relation"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
@@ -30,7 +31,7 @@ func NewFriendLocalCache(client rpcclient.FriendRpcClient, localCache *config.Lo
log.ZDebug(context.Background(), "FriendLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable())
x := &FriendLocalCache{
client: client,
local: localcache.New[any](
local: localcache.New[[]byte](
localcache.WithLocalSlotNum(lc.SlotNum),
localcache.WithLocalSlotSize(lc.SlotSize),
localcache.WithLinkSlotNum(lc.SlotNum),
@@ -46,36 +47,55 @@ func NewFriendLocalCache(client rpcclient.FriendRpcClient, localCache *config.Lo
type FriendLocalCache struct {
client rpcclient.FriendRpcClient
local localcache.Cache[any]
local localcache.Cache[[]byte]
}
func (f *FriendLocalCache) IsFriend(ctx context.Context, possibleFriendUserID, userID string) (val bool, err error) {
log.ZDebug(ctx, "FriendLocalCache IsFriend req", "possibleFriendUserID", possibleFriendUserID, "userID", userID)
res, err := f.isFriend(ctx, possibleFriendUserID, userID)
if err != nil {
return false, err
}
return res.InUser1Friends, nil
}
func (f *FriendLocalCache) isFriend(ctx context.Context, possibleFriendUserID, userID string) (val *relation.IsFriendResp, err error) {
log.ZDebug(ctx, "FriendLocalCache isFriend req", "possibleFriendUserID", possibleFriendUserID, "userID", userID)
defer func() {
if err == nil {
log.ZDebug(ctx, "FriendLocalCache IsFriend return", "value", val)
log.ZDebug(ctx, "FriendLocalCache isFriend return", "possibleFriendUserID", possibleFriendUserID, "userID", userID, "value", val)
} else {
log.ZError(ctx, "FriendLocalCache IsFriend return", err)
log.ZError(ctx, "FriendLocalCache isFriend return", err, "possibleFriendUserID", possibleFriendUserID, "userID", userID)
}
}()
return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey2.GetIsFriendKey(possibleFriendUserID, userID), func(ctx context.Context) (any, error) {
log.ZDebug(ctx, "FriendLocalCache IsFriend rpc", "possibleFriendUserID", possibleFriendUserID, "userID", userID)
return f.client.IsFriend(ctx, possibleFriendUserID, userID)
}, cachekey2.GetFriendIDsKey(possibleFriendUserID)))
var cache cacheProto[relation.IsFriendResp]
return cache.Unmarshal(f.local.GetLink(ctx, cachekey.GetIsFriendKey(possibleFriendUserID, userID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "FriendLocalCache isFriend rpc", "possibleFriendUserID", possibleFriendUserID, "userID", userID)
return cache.Marshal(f.client.Client.IsFriend(ctx, &relation.IsFriendReq{UserID1: userID, UserID2: possibleFriendUserID}))
}, cachekey.GetFriendIDsKey(possibleFriendUserID)))
}
// IsBlack possibleBlackUserID selfUserID.
func (f *FriendLocalCache) IsBlack(ctx context.Context, possibleBlackUserID, userID string) (val bool, err error) {
log.ZDebug(ctx, "FriendLocalCache IsBlack req", "possibleBlackUserID", possibleBlackUserID, "userID", userID)
res, err := f.isBlack(ctx, possibleBlackUserID, userID)
if err != nil {
return false, err
}
return res.InUser2Blacks, nil
}
// IsBlack possibleBlackUserID selfUserID.
func (f *FriendLocalCache) isBlack(ctx context.Context, possibleBlackUserID, userID string) (val *relation.IsBlackResp, err error) {
log.ZDebug(ctx, "FriendLocalCache isBlack req", "possibleBlackUserID", possibleBlackUserID, "userID", userID)
defer func() {
if err == nil {
log.ZDebug(ctx, "FriendLocalCache IsBlack return", "value", val)
log.ZDebug(ctx, "FriendLocalCache isBlack return", "possibleBlackUserID", possibleBlackUserID, "userID", userID, "value", val)
} else {
log.ZError(ctx, "FriendLocalCache IsBlack return", err)
log.ZError(ctx, "FriendLocalCache isBlack return", err, "possibleBlackUserID", possibleBlackUserID, "userID", userID)
}
}()
return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey2.GetIsBlackIDsKey(possibleBlackUserID, userID), func(ctx context.Context) (any, error) {
var cache cacheProto[relation.IsBlackResp]
return cache.Unmarshal(f.local.GetLink(ctx, cachekey.GetIsBlackIDsKey(possibleBlackUserID, userID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "FriendLocalCache IsBlack rpc", "possibleBlackUserID", possibleBlackUserID, "userID", userID)
return f.client.IsBlack(ctx, possibleBlackUserID, userID)
}, cachekey2.GetBlackIDsKey(userID)))
return cache.Marshal(f.client.Client.IsBlack(ctx, &relation.IsBlackReq{UserID1: possibleBlackUserID, UserID2: userID}))
}, cachekey.GetBlackIDsKey(userID)))
}
+22 -17
View File
@@ -17,6 +17,8 @@ package rpccache
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/protocol/group"
"github.com/openimsdk/tools/utils/datautil"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
@@ -32,7 +34,7 @@ func NewGroupLocalCache(client rpcclient.GroupRpcClient, localCache *config.Loca
log.ZDebug(context.Background(), "GroupLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable())
x := &GroupLocalCache{
client: client,
local: localcache.New[any](
local: localcache.New[[]byte](
localcache.WithLocalSlotNum(lc.SlotNum),
localcache.WithLocalSlotSize(lc.SlotSize),
localcache.WithLinkSlotNum(lc.SlotNum),
@@ -48,21 +50,22 @@ func NewGroupLocalCache(client rpcclient.GroupRpcClient, localCache *config.Loca
type GroupLocalCache struct {
client rpcclient.GroupRpcClient
local localcache.Cache[any]
local localcache.Cache[[]byte]
}
func (g *GroupLocalCache) getGroupMemberIDs(ctx context.Context, groupID string) (val *listMap[string], err error) {
func (g *GroupLocalCache) getGroupMemberIDs(ctx context.Context, groupID string) (val *group.GetGroupMemberUserIDsResp, err error) {
log.ZDebug(ctx, "GroupLocalCache getGroupMemberIDs req", "groupID", groupID)
defer func() {
if err == nil {
log.ZDebug(ctx, "GroupLocalCache getGroupMemberIDs return", "value", val)
log.ZDebug(ctx, "GroupLocalCache getGroupMemberIDs return", "groupID", groupID, "value", val)
} else {
log.ZError(ctx, "GroupLocalCache getGroupMemberIDs return", err)
log.ZError(ctx, "GroupLocalCache getGroupMemberIDs return", err, "groupID", groupID)
}
}()
return localcache.AnyValue[*listMap[string]](g.local.Get(ctx, cachekey.GetGroupMemberIDsKey(groupID), func(ctx context.Context) (any, error) {
var cache cacheProto[group.GetGroupMemberUserIDsResp]
return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupMemberIDsKey(groupID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "GroupLocalCache getGroupMemberIDs rpc", "groupID", groupID)
return newListMap(g.client.GetGroupMemberIDs(ctx, groupID))
return cache.Marshal(g.client.Client.GetGroupMemberUserIDs(ctx, &group.GetGroupMemberUserIDsReq{GroupID: groupID}))
}))
}
@@ -70,14 +73,15 @@ func (g *GroupLocalCache) GetGroupMember(ctx context.Context, groupID, userID st
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo req", "groupID", groupID, "userID", userID)
defer func() {
if err == nil {
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo return", "value", val)
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo return", "groupID", groupID, "userID", userID, "value", val)
} else {
log.ZError(ctx, "GroupLocalCache GetGroupInfo return", err)
log.ZError(ctx, "GroupLocalCache GetGroupInfo return", err, "groupID", groupID, "userID", userID)
}
}()
return localcache.AnyValue[*sdkws.GroupMemberFullInfo](g.local.Get(ctx, cachekey.GetGroupMemberInfoKey(groupID, userID), func(ctx context.Context) (any, error) {
var cache cacheProto[sdkws.GroupMemberFullInfo]
return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupMemberInfoKey(groupID, userID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo rpc", "groupID", groupID, "userID", userID)
return g.client.GetGroupMemberCache(ctx, groupID, userID)
return cache.Marshal(g.client.GetGroupMemberCache(ctx, groupID, userID))
}))
}
@@ -85,14 +89,15 @@ func (g *GroupLocalCache) GetGroupInfo(ctx context.Context, groupID string) (val
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo req", "groupID", groupID)
defer func() {
if err == nil {
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo return", "value", val)
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo return", "groupID", groupID, "value", val)
} else {
log.ZError(ctx, "GroupLocalCache GetGroupInfo return", err)
log.ZError(ctx, "GroupLocalCache GetGroupInfo return", err, "groupID", groupID)
}
}()
return localcache.AnyValue[*sdkws.GroupInfo](g.local.Get(ctx, cachekey.GetGroupInfoKey(groupID), func(ctx context.Context) (any, error) {
var cache cacheProto[sdkws.GroupInfo]
return cache.Unmarshal(g.local.Get(ctx, cachekey.GetGroupInfoKey(groupID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "GroupLocalCache GetGroupInfo rpc", "groupID", groupID)
return g.client.GetGroupInfoCache(ctx, groupID)
return cache.Marshal(g.client.GetGroupInfoCache(ctx, groupID))
}))
}
@@ -101,7 +106,7 @@ func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string)
if err != nil {
return nil, err
}
return res.List, nil
return res.UserIDs, nil
}
func (g *GroupLocalCache) GetGroupMemberIDMap(ctx context.Context, groupID string) (map[string]struct{}, error) {
@@ -109,7 +114,7 @@ func (g *GroupLocalCache) GetGroupMemberIDMap(ctx context.Context, groupID strin
if err != nil {
return nil, err
}
return res.Map, nil
return datautil.SliceSet(res.UserIDs), nil
}
func (g *GroupLocalCache) GetGroupInfos(ctx context.Context, groupIDs []string) ([]*sdkws.GroupInfo, error) {
+53 -37
View File
@@ -28,7 +28,7 @@ func NewOnlineCache(user rpcclient.UserRpcClient, group *GroupLocalCache, rdb re
for message := range rdb.Subscribe(ctx, cachekey.OnlineChannel).Channel() {
userID, platformIDs, err := useronline.ParseUserOnlineStatus(message.Payload)
if err != nil {
log.ZError(ctx, "OnlineCache redis subscribe parseUserOnlineStatus", err, "payload", message.Payload, "channel", message.Channel)
log.ZError(ctx, "OnlineCache setUserOnline redis subscribe parseUserOnlineStatus", err, "payload", message.Payload, "channel", message.Channel)
continue
}
storageCache := x.setUserOnline(userID, platformIDs)
@@ -47,53 +47,69 @@ type OnlineCache struct {
local lru.LRU[string, []int32]
}
func (o *OnlineCache) GetUserOnlinePlatform(ctx context.Context, userID string) ([]int32, error) {
return o.local.Get(userID, func() ([]int32, error) {
func (o *OnlineCache) getUserOnlinePlatform(ctx context.Context, userID string) ([]int32, error) {
platformIDs, err := o.local.Get(userID, func() ([]int32, error) {
return o.user.GetUserOnlinePlatform(ctx, userID)
})
if err != nil {
log.ZError(ctx, "OnlineCache GetUserOnlinePlatform", err, "userID", userID)
return nil, err
}
log.ZDebug(ctx, "OnlineCache GetUserOnlinePlatform", "userID", userID, "platformIDs", platformIDs)
return platformIDs, nil
}
func (o *OnlineCache) GetUserOnlinePlatform(ctx context.Context, userID string) ([]int32, error) {
platformIDs, err := o.getUserOnlinePlatform(ctx, userID)
if err != nil {
return nil, err
}
tmp := make([]int32, len(platformIDs))
copy(tmp, platformIDs)
return platformIDs, nil
}
func (o *OnlineCache) GetUserOnline(ctx context.Context, userID string) (bool, error) {
platformIDs, err := o.GetUserOnlinePlatform(ctx, userID)
platformIDs, err := o.getUserOnlinePlatform(ctx, userID)
if err != nil {
return false, err
}
return len(platformIDs) > 0, nil
}
func (o *OnlineCache) GetUsersOnline(ctx context.Context, userIDs []string) ([]string, error) {
onlineUserIDs := make([]string, 0, len(userIDs))
for _, userID := range userIDs {
online, err := o.GetUserOnline(ctx, userID)
if err != nil {
return nil, err
}
if online {
onlineUserIDs = append(onlineUserIDs, userID)
}
}
log.ZDebug(ctx, "OnlineCache GetUsersOnline", "userIDs", userIDs, "onlineUserIDs", onlineUserIDs)
return onlineUserIDs, nil
}
func (o *OnlineCache) GetGroupOnline(ctx context.Context, groupID string) ([]string, error) {
userIDs, err := o.group.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return nil, err
}
var onlineUserIDs []string
for _, userID := range userIDs {
online, err := o.GetUserOnline(ctx, userID)
if err != nil {
return nil, err
}
if online {
onlineUserIDs = append(onlineUserIDs, userID)
}
}
log.ZDebug(ctx, "OnlineCache GetGroupOnline", "groupID", groupID, "onlineUserIDs", onlineUserIDs, "allUserID", userIDs)
return onlineUserIDs, nil
}
//func (o *OnlineCache) GetUsersOnline(ctx context.Context, userIDs []string) ([]string, error) {
// onlineUserIDs := make([]string, 0, len(userIDs))
// for _, userID := range userIDs {
// online, err := o.GetUserOnline(ctx, userID)
// if err != nil {
// return nil, err
// }
// if online {
// onlineUserIDs = append(onlineUserIDs, userID)
// }
// }
// log.ZDebug(ctx, "OnlineCache GetUsersOnline", "userIDs", userIDs, "onlineUserIDs", onlineUserIDs)
// return onlineUserIDs, nil
//}
//
//func (o *OnlineCache) GetGroupOnline(ctx context.Context, groupID string) ([]string, error) {
// userIDs, err := o.group.GetGroupMemberIDs(ctx, groupID)
// if err != nil {
// return nil, err
// }
// var onlineUserIDs []string
// for _, userID := range userIDs {
// online, err := o.GetUserOnline(ctx, userID)
// if err != nil {
// return nil, err
// }
// if online {
// onlineUserIDs = append(onlineUserIDs, userID)
// }
// }
// log.ZDebug(ctx, "OnlineCache GetGroupOnline", "groupID", groupID, "onlineUserIDs", onlineUserIDs, "allUserID", userIDs)
// return onlineUserIDs, nil
//}
func (o *OnlineCache) setUserOnline(userID string, platformIDs []int32) bool {
return o.local.SetHas(userID, platformIDs)
+21 -26
View File
@@ -16,12 +16,12 @@ package rpccache
import (
"context"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
"github.com/openimsdk/open-im-server/v3/pkg/localcache"
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/protocol/user"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"github.com/redis/go-redis/v9"
@@ -32,7 +32,7 @@ func NewUserLocalCache(client rpcclient.UserRpcClient, localCache *config.LocalC
log.ZDebug(context.Background(), "UserLocalCache", "topic", lc.Topic, "slotNum", lc.SlotNum, "slotSize", lc.SlotSize, "enable", lc.Enable())
x := &UserLocalCache{
client: client,
local: localcache.New[any](
local: localcache.New[[]byte](
localcache.WithLocalSlotNum(lc.SlotNum),
localcache.WithLocalSlotSize(lc.SlotSize),
localcache.WithLinkSlotNum(lc.SlotNum),
@@ -48,7 +48,7 @@ func NewUserLocalCache(client rpcclient.UserRpcClient, localCache *config.LocalC
type UserLocalCache struct {
client rpcclient.UserRpcClient
local localcache.Cache[any]
local localcache.Cache[[]byte]
}
func (u *UserLocalCache) GetUserInfo(ctx context.Context, userID string) (val *sdkws.UserInfo, err error) {
@@ -60,24 +60,34 @@ func (u *UserLocalCache) GetUserInfo(ctx context.Context, userID string) (val *s
log.ZError(ctx, "UserLocalCache GetUserInfo return", err)
}
}()
return localcache.AnyValue[*sdkws.UserInfo](u.local.Get(ctx, cachekey.GetUserInfoKey(userID), func(ctx context.Context) (any, error) {
var cache cacheProto[sdkws.UserInfo]
return cache.Unmarshal(u.local.Get(ctx, cachekey.GetUserInfoKey(userID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "UserLocalCache GetUserInfo rpc", "userID", userID)
return u.client.GetUserInfo(ctx, userID)
return cache.Marshal(u.client.GetUserInfo(ctx, userID))
}))
}
func (u *UserLocalCache) GetUserGlobalMsgRecvOpt(ctx context.Context, userID string) (val int32, err error) {
log.ZDebug(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt req", "userID", userID)
resp, err := u.getUserGlobalMsgRecvOpt(ctx, userID)
if err != nil {
return 0, err
}
return resp.GlobalRecvMsgOpt, nil
}
func (u *UserLocalCache) getUserGlobalMsgRecvOpt(ctx context.Context, userID string) (val *user.GetGlobalRecvMessageOptResp, err error) {
log.ZDebug(ctx, "UserLocalCache getUserGlobalMsgRecvOpt req", "userID", userID)
defer func() {
if err == nil {
log.ZDebug(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt return", "value", val)
log.ZDebug(ctx, "UserLocalCache getUserGlobalMsgRecvOpt return", "value", val)
} else {
log.ZError(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt return", err)
log.ZError(ctx, "UserLocalCache getUserGlobalMsgRecvOpt return", err)
}
}()
return localcache.AnyValue[int32](u.local.Get(ctx, cachekey.GetUserGlobalRecvMsgOptKey(userID), func(ctx context.Context) (any, error) {
var cache cacheProto[user.GetGlobalRecvMessageOptResp]
return cache.Unmarshal(u.local.Get(ctx, cachekey.GetUserGlobalRecvMsgOptKey(userID), func(ctx context.Context) ([]byte, error) {
log.ZDebug(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt rpc", "userID", userID)
return u.client.GetUserGlobalMsgRecvOpt(ctx, userID)
return cache.Marshal(u.client.Client.GetGlobalRecvMessageOpt(ctx, &user.GetGlobalRecvMessageOptReq{UserID: userID}))
}))
}
@@ -110,18 +120,3 @@ func (u *UserLocalCache) GetUsersInfoMap(ctx context.Context, userIDs []string)
}
return users, nil
}
//func (u *UserLocalCache) GetUserOnlinePlatform(ctx context.Context, userID string) (val []int32, err error) {
// log.ZDebug(ctx, "UserLocalCache GetUserOnlinePlatform req", "userID", userID)
// defer func() {
// if err == nil {
// log.ZDebug(ctx, "UserLocalCache GetUserOnlinePlatform return", "value", val)
// } else {
// log.ZError(ctx, "UserLocalCache GetUserOnlinePlatform return", err)
// }
// }()
// return localcache.AnyValue[[]int32](u.local.Get(ctx, cachekey.GetOnlineKey(userID), func(ctx context.Context) (any, error) {
// log.ZDebug(ctx, "UserLocalCache GetUserGlobalMsgRecvOpt rpc", "userID", userID)
// return u.client.GetUserGlobalMsgRecvOpt(ctx, userID)
// }))
//}
+9 -1
View File
@@ -82,7 +82,7 @@ func (c *ConversationRpcClient) SetConversations(ctx context.Context, userIDs []
return err
}
func (c *ConversationRpcClient) UpdateConversations(ctx context.Context, conversation *pbconversation.UpdateConversationReq) error {
func (c *ConversationRpcClient) UpdateConversation(ctx context.Context, conversation *pbconversation.UpdateConversationReq) error {
_, err := c.Client.UpdateConversation(ctx, conversation)
return err
}
@@ -146,3 +146,11 @@ func (c *ConversationRpcClient) GetConversationNotReceiveMessageUserIDs(ctx cont
}
return resp.UserIDs, nil
}
func (c *ConversationRpcClient) GetConversationsNeedDestructMsgs(ctx context.Context) ([]*pbconversation.Conversation, error) {
resp, err := c.Client.GetConversationsNeedDestructMsgs(ctx, &pbconversation.GetConversationsNeedDestructMsgsReq{})
if err != nil {
return nil, err
}
return resp.Conversations, nil
}
+4
View File
@@ -324,6 +324,10 @@ func (s *NotificationSender) send(ctx context.Context, sendID, recvID string, co
options := config.GetOptionsByNotification(optionsConfig)
s.SetOptionsByContentType(ctx, options, contentType)
msg.Options = options
// fill Notification OfflinePush by config
offlineInfo.Title = optionsConfig.OfflinePush.Title
offlineInfo.Desc = optionsConfig.OfflinePush.Desc
offlineInfo.Ex = optionsConfig.OfflinePush.Ext
msg.OfflinePushInfo = &offlineInfo
req.MsgData = &msg
_, err = s.sendMsg(ctx, &req)
+1
View File
@@ -0,0 +1 @@
3.8.0
+6
View File
@@ -0,0 +1,6 @@
package version
import _ "embed"
//go:embed version
var Version string