All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.redis.runtime.datasource.BlockingRedisDataSourceImpl Maven / Gradle / Ivy

There is a newer version: 3.17.5
Show newest version
package io.quarkus.redis.runtime.datasource;

import static io.quarkus.redis.runtime.datasource.ReactiveRedisDataSourceImpl.toTransactionResult;

import java.time.Duration;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

import com.fasterxml.jackson.core.type.TypeReference;

import io.quarkus.redis.datasource.ReactiveRedisDataSource;
import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.autosuggest.AutoSuggestCommands;
import io.quarkus.redis.datasource.bitmap.BitMapCommands;
import io.quarkus.redis.datasource.bloom.BloomCommands;
import io.quarkus.redis.datasource.countmin.CountMinCommands;
import io.quarkus.redis.datasource.cuckoo.CuckooCommands;
import io.quarkus.redis.datasource.geo.GeoCommands;
import io.quarkus.redis.datasource.graph.GraphCommands;
import io.quarkus.redis.datasource.hash.HashCommands;
import io.quarkus.redis.datasource.hyperloglog.HyperLogLogCommands;
import io.quarkus.redis.datasource.json.JsonCommands;
import io.quarkus.redis.datasource.keys.KeyCommands;
import io.quarkus.redis.datasource.list.ListCommands;
import io.quarkus.redis.datasource.pubsub.PubSubCommands;
import io.quarkus.redis.datasource.search.SearchCommands;
import io.quarkus.redis.datasource.set.SetCommands;
import io.quarkus.redis.datasource.sortedset.SortedSetCommands;
import io.quarkus.redis.datasource.stream.StreamCommands;
import io.quarkus.redis.datasource.string.StringCommands;
import io.quarkus.redis.datasource.timeseries.TimeSeriesCommands;
import io.quarkus.redis.datasource.topk.TopKCommands;
import io.quarkus.redis.datasource.transactions.OptimisticLockingTransactionResult;
import io.quarkus.redis.datasource.transactions.TransactionResult;
import io.quarkus.redis.datasource.transactions.TransactionalRedisDataSource;
import io.quarkus.redis.datasource.value.ValueCommands;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.redis.client.Command;
import io.vertx.mutiny.redis.client.Redis;
import io.vertx.mutiny.redis.client.RedisAPI;
import io.vertx.mutiny.redis.client.RedisConnection;
import io.vertx.mutiny.redis.client.Request;
import io.vertx.mutiny.redis.client.Response;

public class BlockingRedisDataSourceImpl implements RedisDataSource {

    private final Duration timeout;
    final ReactiveRedisDataSourceImpl reactive;
    final RedisConnection connection;

    public BlockingRedisDataSourceImpl(Vertx vertx, Redis redis, RedisAPI api, Duration timeout) {
        this(new ReactiveRedisDataSourceImpl(vertx, redis, api), timeout);
    }

    public BlockingRedisDataSourceImpl(ReactiveRedisDataSourceImpl reactive, Duration timeout) {
        this.reactive = reactive;
        this.timeout = timeout;
        this.connection = reactive.connection;
    }

    public BlockingRedisDataSourceImpl(Vertx vertx, Redis redis, RedisConnection connection, Duration timeout) {
        this(new ReactiveRedisDataSourceImpl(vertx, redis, connection), timeout);
    }

    public TransactionResult withTransaction(Consumer ds) {
        RedisConnection connection = reactive.redis.connect().await().atMost(timeout);
        ReactiveRedisDataSourceImpl dataSource = new ReactiveRedisDataSourceImpl(reactive.getVertx(), reactive.redis,
                connection);
        TransactionHolder th = new TransactionHolder();
        BlockingTransactionalRedisDataSourceImpl source = new BlockingTransactionalRedisDataSourceImpl(
                new ReactiveTransactionalRedisDataSourceImpl(dataSource, th), timeout);

        try {
            connection.send(Request.cmd(Command.MULTI)).await().atMost(timeout);
            ds.accept(source);
            if (!source.discarded()) {
                Response response = connection.send((Request.cmd(Command.EXEC))).await().atMost(timeout);
                return toTransactionResult(response, th);
            } else {
                return toTransactionResult(null, th);
            }
        } finally {
            connection.closeAndAwait();
        }
    }

    @Override
    public TransactionResult withTransaction(Consumer ds, String... watchedKeys) {
        RedisConnection connection = reactive.redis.connect().await().atMost(timeout);
        ReactiveRedisDataSourceImpl dataSource = new ReactiveRedisDataSourceImpl(reactive.getVertx(), reactive.redis,
                connection);
        TransactionHolder th = new TransactionHolder();
        BlockingTransactionalRedisDataSourceImpl source = new BlockingTransactionalRedisDataSourceImpl(
                new ReactiveTransactionalRedisDataSourceImpl(dataSource, th), timeout);

        try {
            Request cmd = Request.cmd(Command.WATCH);
            for (String watchedKey : watchedKeys) {
                cmd.arg(watchedKey);
            }
            connection.send(cmd).await().atMost(timeout);
            connection.send(Request.cmd(Command.MULTI)).await().atMost(timeout);

            ds.accept(source);
            if (!source.discarded()) {
                Response response = connection.send(Request.cmd(Command.EXEC)).await().atMost(timeout);
                // exec produce null is the transaction has been discarded
                return toTransactionResult(response, th);
            } else {
                return toTransactionResult(null, th);
            }

        } finally {
            connection.closeAndAwait();
        }
    }

    @Override
    public  OptimisticLockingTransactionResult withTransaction(Function preTxBlock,
            BiConsumer tx, String... watchedKeys) {
        RedisConnection connection = reactive.redis.connect().await().atMost(timeout);
        ReactiveRedisDataSourceImpl dataSource = new ReactiveRedisDataSourceImpl(reactive.getVertx(), reactive.redis,
                connection);
        TransactionHolder th = new TransactionHolder();
        BlockingTransactionalRedisDataSourceImpl source = new BlockingTransactionalRedisDataSourceImpl(
                new ReactiveTransactionalRedisDataSourceImpl(dataSource, th), timeout);

        try {
            Request cmd = Request.cmd(Command.WATCH);
            for (String watchedKey : watchedKeys) {
                cmd.arg(watchedKey);
            }
            connection.send(cmd).await().atMost(timeout);

            I input = preTxBlock
                    .apply(new BlockingRedisDataSourceImpl(reactive.getVertx(), reactive.redis, connection, timeout));

            connection.send(Request.cmd(Command.MULTI)).await().atMost(timeout);

            tx.accept(input, source);
            if (!source.discarded()) {
                Response response = connection.send(Request.cmd(Command.EXEC)).await().atMost(timeout);
                // exec produce null is the transaction has been discarded
                return toTransactionResult(response, input, th);
            } else {
                return toTransactionResult(null, input, th);
            }

        } finally {
            connection.closeAndAwait();
        }
    }

    @Override
    public void withConnection(Consumer consumer) {
        if (connection != null) {
            // Already on a specific connection, we keep using it
            consumer.accept(this);
            return;
        }

        BlockingRedisDataSourceImpl source = reactive.redis.connect()
                .map(rc -> new BlockingRedisDataSourceImpl(reactive.getVertx(), reactive.redis, rc, timeout))
                .await().atMost(timeout);

        try {
            consumer.accept(source);
        } finally {
            source.connection.closeAndAwait();
        }
    }

    @Override
    public void select(long index) {
        reactive.select(index)
                .await().atMost(timeout);
    }

    @Override
    public void flushall() {
        reactive.flushall()
                .await().atMost(timeout);
    }

    @Override
    public  HashCommands hash(Class redisKeyType, Class typeOfField, Class typeOfValue) {
        return new BlockingHashCommandsImpl<>(this, reactive.hash(redisKeyType, typeOfField, typeOfValue), timeout);
    }

    @Override
    public  HashCommands hash(TypeReference redisKeyType, TypeReference typeOfField,
            TypeReference typeOfValue) {
        return new BlockingHashCommandsImpl<>(this, reactive.hash(redisKeyType, typeOfField, typeOfValue), timeout);
    }

    @Override
    public  GeoCommands geo(Class redisKeyType, Class memberType) {
        return new BlockingGeoCommandsImpl<>(this, reactive.geo(redisKeyType, memberType), timeout);
    }

    @Override
    public  GeoCommands geo(TypeReference redisKeyType, TypeReference memberType) {
        return new BlockingGeoCommandsImpl<>(this, reactive.geo(redisKeyType, memberType), timeout);
    }

    @Override
    public  KeyCommands key(Class redisKeyType) {
        return new BlockingKeyCommandsImpl<>(this, reactive.key(redisKeyType), timeout);
    }

    @Override
    public  KeyCommands key(TypeReference redisKeyType) {
        return new BlockingKeyCommandsImpl<>(this, reactive.key(redisKeyType), timeout);
    }

    @Override
    public  SortedSetCommands sortedSet(Class redisKeyType, Class valueType) {
        return new BlockingSortedSetCommandsImpl<>(this, reactive.sortedSet(redisKeyType, valueType), timeout);
    }

    @Override
    public  SortedSetCommands sortedSet(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingSortedSetCommandsImpl<>(this, reactive.sortedSet(redisKeyType, valueType), timeout);
    }

    @Override
    public  StringCommands string(Class redisKeyType, Class valueType) {
        return new BlockingStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout);
    }

    @Override
    public  ValueCommands value(Class redisKeyType, Class valueType) {
        return new BlockingStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout);
    }

    @Override
    public  ValueCommands value(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingStringCommandsImpl<>(this, reactive.value(redisKeyType, valueType), timeout);
    }

    @Override
    public  SetCommands set(Class redisKeyType, Class memberType) {
        return new BlockingSetCommandsImpl<>(this, reactive.set(redisKeyType, memberType), timeout);
    }

    @Override
    public  SetCommands set(TypeReference redisKeyType, TypeReference memberType) {
        return new BlockingSetCommandsImpl<>(this, reactive.set(redisKeyType, memberType), timeout);
    }

    @Override
    public  ListCommands list(Class redisKeyType, Class memberType) {
        return new BlockingListCommandsImpl<>(this, reactive.list(redisKeyType, memberType), timeout);
    }

    @Override
    public  ListCommands list(TypeReference redisKeyType, TypeReference memberType) {
        return new BlockingListCommandsImpl<>(this, reactive.list(redisKeyType, memberType), timeout);
    }

    @Override
    public  HyperLogLogCommands hyperloglog(Class redisKeyType, Class memberType) {
        return new BlockingHyperLogLogCommandsImpl<>(this, reactive.hyperloglog(redisKeyType, memberType), timeout);
    }

    @Override
    public  HyperLogLogCommands hyperloglog(TypeReference redisKeyType, TypeReference memberType) {
        return new BlockingHyperLogLogCommandsImpl<>(this, reactive.hyperloglog(redisKeyType, memberType), timeout);
    }

    @Override
    public  BitMapCommands bitmap(Class redisKeyType) {
        return new BlockingBitmapCommandsImpl<>(this, reactive.bitmap(redisKeyType), timeout);
    }

    @Override
    public  BitMapCommands bitmap(TypeReference redisKeyType) {
        return new BlockingBitmapCommandsImpl<>(this, reactive.bitmap(redisKeyType), timeout);
    }

    @Override
    public  StreamCommands stream(Class redisKeyType, Class fieldType, Class valueType) {
        return new BlockingStreamCommandsImpl<>(this, reactive.stream(redisKeyType, fieldType, valueType), timeout);
    }

    @Override
    public  StreamCommands stream(TypeReference redisKeyType, TypeReference fieldType,
            TypeReference valueType) {
        return new BlockingStreamCommandsImpl<>(this, reactive.stream(redisKeyType, fieldType, valueType), timeout);
    }

    @Override
    public  JsonCommands json(Class redisKeyType) {
        return new BlockingJsonCommandsImpl<>(this, reactive.json(redisKeyType), timeout);
    }

    @Override
    public  JsonCommands json(TypeReference redisKeyType) {
        return new BlockingJsonCommandsImpl<>(this, reactive.json(redisKeyType), timeout);
    }

    @Override
    public  BloomCommands bloom(Class redisKeyType, Class valueType) {
        return new BlockingBloomCommandsImpl<>(this, reactive.bloom(redisKeyType, valueType), timeout);
    }

    @Override
    public  BloomCommands bloom(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingBloomCommandsImpl<>(this, reactive.bloom(redisKeyType, valueType), timeout);
    }

    @Override
    public  CuckooCommands cuckoo(Class redisKeyType, Class valueType) {
        return new BlockingCuckooCommandsImpl<>(this, reactive.cuckoo(redisKeyType, valueType), timeout);
    }

    @Override
    public  CuckooCommands cuckoo(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingCuckooCommandsImpl<>(this, reactive.cuckoo(redisKeyType, valueType), timeout);
    }

    @Override
    public  CountMinCommands countmin(Class redisKeyType, Class valueType) {
        return new BlockingCountMinCommandsImpl<>(this, reactive.countmin(redisKeyType, valueType), timeout);
    }

    @Override
    public  CountMinCommands countmin(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingCountMinCommandsImpl<>(this, reactive.countmin(redisKeyType, valueType), timeout);
    }

    @Override
    public  TopKCommands topk(Class redisKeyType, Class valueType) {
        return new BlockingTopKCommandsImpl<>(this, reactive.topk(redisKeyType, valueType), timeout);
    }

    @Override
    public  TopKCommands topk(TypeReference redisKeyType, TypeReference valueType) {
        return new BlockingTopKCommandsImpl<>(this, reactive.topk(redisKeyType, valueType), timeout);
    }

    @Override
    public  GraphCommands graph(Class redisKeyType) {
        return new BlockingGraphCommandsImpl<>(this, reactive.graph(redisKeyType), timeout);
    }

    @Override
    public  SearchCommands search(Class redisKeyType) {
        return new BlockingSearchCommandsImpl<>(this, reactive.search(redisKeyType), timeout);
    }

    @Override
    public  AutoSuggestCommands autosuggest(Class redisKeyType) {
        return new BlockingAutoSuggestCommandsImpl<>(this, reactive.autosuggest(redisKeyType), timeout);
    }

    @Override
    public  AutoSuggestCommands autosuggest(TypeReference redisKeyType) {
        return new BlockingAutoSuggestCommandsImpl<>(this, reactive.autosuggest(redisKeyType), timeout);
    }

    @Override
    public  TimeSeriesCommands timeseries(Class redisKeyType) {
        return new BlockingTimeSeriesCommandsImpl<>(this, reactive.timeseries(redisKeyType), timeout);
    }

    @Override
    public  TimeSeriesCommands timeseries(TypeReference redisKeyType) {
        return new BlockingTimeSeriesCommandsImpl<>(this, reactive.timeseries(redisKeyType), timeout);
    }

    @Override
    public  PubSubCommands pubsub(Class messageType) {
        return new BlockingPubSubCommandsImpl<>(this, reactive.pubsub(messageType), timeout);
    }

    @Override
    public  PubSubCommands pubsub(TypeReference messageType) {
        return new BlockingPubSubCommandsImpl<>(this, reactive.pubsub(messageType), timeout);
    }

    @Override
    public Response execute(String command, String... args) {
        return reactive.execute(command, args)
                .await().atMost(timeout);
    }

    @Override
    public Response execute(Command command, String... args) {
        return reactive.execute(command, args)
                .await().atMost(timeout);
    }

    @Override
    public Response execute(io.vertx.redis.client.Command command, String... args) {
        return reactive.execute(command, args)
                .await().atMost(timeout);
    }

    @Override
    public ReactiveRedisDataSource getReactive() {
        return reactive;
    }
}