public Mono<Void> upsertGroupConversationsReadDate(
            @NotNull Set<GroupConversation.GroupConversionMemberKey> keys,
            @Nullable @PastOrPresent Date readDate) {
        try {
            Validator.notNull(keys, "keys");
            Validator.pastOrPresent(readDate, "readDate");
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        if (keys.isEmpty()) {
            return Mono.empty();
        }
        if (readDate == null) {
            readDate = new Date();
        }
        Map<Long, List<Long>> groupIdToMemberIds = CollectionUtil.newMapWithExpectedSize(1);
        int keyCount = keys.size();
        for (GroupConversation.GroupConversionMemberKey key : keys) {
            groupIdToMemberIds.computeIfAbsent(key.getGroupId(), k -> new ArrayList<>(keyCount))
                    .add(key.getMemberId());
        }
        Set<Map.Entry<Long, List<Long>>> entries = groupIdToMemberIds.entrySet();
        List<Mono<Void>> upsertMonos = new ArrayList<>(entries.size());
        for (Map.Entry<Long, List<Long>> entry : entries) {
            Long groupId = entry.getKey();
            List<Long> memberIds = entry.getValue();
            upsertMonos.add(groupConversationRepository.upsert(groupId, memberIds, readDate)
                    .then());
        }
        return Mono.whenDelayError(upsertMonos);
    }
@param groupService is lazy because conversationService -> groupService ->
                    conversationService
turms-service/src/main/java/im/turms/service/domain/conversation/service/ConversationService.java