public Mono<UserInfosWithVersion> queryGroupBlockedUserInfosWithVersion(
            @NotNull Long groupId,
            @Nullable Date lastUpdatedDate) {
        try {
            Validator.notNull(groupId, "groupId");
        } catch (ResponseException e) {
            return Mono.error(e);
        }
        return groupVersionService.queryBlocklistVersion(groupId)
                .flatMap(version -> {
                    if (DateTimeUtil.isAfterOrSame(lastUpdatedDate, version)) {
                        return ResponseExceptionPublisherPool.alreadyUpToUpdate();
                    }
                    Recyclable<List<Long>> recyclableList = ListRecycler.obtain();
                    Recyclable<Set<User>> recyclableSet = SetRecycler.obtain();
                    return queryGroupBlockedUserIds(groupId)
                            .collect(Collectors.toCollection(recyclableList::getValue))
                            .flatMapMany(ids -> {
                                if (ids.isEmpty()) {
                                    throw ResponseException.get(ResponseStatusCode.NO_CONTENT);
                                }
                                return userService.queryUsersProfile(ids, false);
                            })
                            .collect(Collectors.toCollection(recyclableSet::getValue))
                            .map(users -> {
                                if (users.isEmpty()) {
                                    throw ResponseException.get(ResponseStatusCode.NO_CONTENT);
                                }
                                UserInfosWithVersion.Builder builder =
                                        ClientMessagePool.getUserInfosWithVersionBuilder()
                                                .setLastUpdatedDate(version.getTime());
                                for (User user : users) {
                                    builder.addUserInfos(
                                            ProtoModelConvertor.userProfile2proto(user));
                                }
                                return builder.build();
                            })
                            .doFinally(signalType -> {
                                recyclableList.recycle();
                                recyclableSet.recycle();
                            });
                })
                .switchIfEmpty(ResponseExceptionPublisherPool.alreadyUpToUpdate());
    }
@return whether the user to unblock was blocked
turms-service/src/main/java/im/turms/service/domain/group/service/GroupBlocklistService.java