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

com.lambdaworks.redis.pubsub.StatefulRedisPubSubConnectionImpl Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
/*
 * Copyright 2011-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambdaworks.redis.pubsub;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

import com.lambdaworks.redis.RedisChannelWriter;
import com.lambdaworks.redis.RedisFuture;
import com.lambdaworks.redis.StatefulRedisConnectionImpl;
import com.lambdaworks.redis.codec.RedisCodec;
import com.lambdaworks.redis.protocol.ConnectionWatchdog;
import com.lambdaworks.redis.pubsub.api.async.RedisPubSubAsyncCommands;
import com.lambdaworks.redis.pubsub.api.reactive.RedisPubSubReactiveCommands;
import com.lambdaworks.redis.pubsub.api.sync.RedisPubSubCommands;

import io.netty.channel.ChannelHandler;
import io.netty.util.internal.ConcurrentSet;

/**
 * An thread-safe pub/sub connection to a Redis server. Multiple threads may share one {@link StatefulRedisPubSubConnectionImpl}
 *
 * A {@link ConnectionWatchdog} monitors each connection and reconnects automatically until {@link #close} is called. All
 * pending commands will be (re)sent after successful reconnection.
 * 
 * @param  Key type.
 * @param  Value type.
 * @author Mark Paluch
 */
public class StatefulRedisPubSubConnectionImpl extends StatefulRedisConnectionImpl implements
        StatefulRedisPubSubConnection {

    private final PubSubEndpoint endpoint;

    /**
     * Initialize a new connection.
     *
     * @param endpoint the {@link PubSubEndpoint}
     * @param writer the writer used to write commands
     * @param codec Codec used to encode/decode keys and values.
     * @param timeout Maximum time to wait for a response.
     * @param unit Unit of time for the timeout.
     */
    public StatefulRedisPubSubConnectionImpl(PubSubEndpoint endpoint, RedisChannelWriter writer, RedisCodec codec, long timeout,
            TimeUnit unit) {
        super(writer, codec, timeout, unit);

        this.endpoint = endpoint;
    }

    /**
     * Add a new listener.
     *
     * @param listener Listener.
     */
    @Override
    public void addListener(RedisPubSubListener listener) {
        endpoint.addListener(listener);
    }

    /**
     * Remove an existing listener.
     *
     * @param listener Listener.
     */
    @Override
    public void removeListener(RedisPubSubListener listener) {
        endpoint.removeListener(listener);
    }

    @Override
    public RedisPubSubAsyncCommands async() {
        return (RedisPubSubAsyncCommands) async;
    }

    @Override
    protected RedisPubSubAsyncCommandsImpl newRedisAsyncCommandsImpl() {
        return new RedisPubSubAsyncCommandsImpl<>(this, codec);
    }

    @Override
    public RedisPubSubCommands sync() {
        return (RedisPubSubCommands) sync;
    }

    @Override
    protected RedisPubSubCommands newRedisSyncCommandsImpl() {
        return syncHandler(async(), RedisPubSubCommands.class);
    }

    @Override
    public RedisPubSubReactiveCommands reactive() {
        return (RedisPubSubReactiveCommands) reactive;
    }

    @Override
    protected RedisPubSubReactiveCommandsImpl newRedisReactiveCommandsImpl() {
        return new RedisPubSubReactiveCommandsImpl<>(this, codec);
    }

    /**
     * Re-subscribe to all previously subscribed channels and patterns.
     * 
     * @return list of the futures of the {@literal subscribe} and {@literal psubscribe} commands.
     */
    protected List> resubscribe() {

        List> result = new ArrayList<>();

        if (!endpoint.getChannels().isEmpty()) {
            result.add(async().subscribe(toArray(endpoint.getChannels())));
        }

        if (!endpoint.getPatterns().isEmpty()) {
            result.add(async().psubscribe(toArray(endpoint.getPatterns())));
        }

        return result;
    }

    @SuppressWarnings("unchecked")
    private  T[] toArray(Collection c) {
        Class cls = (Class) c.iterator().next().getClass();
        T[] array = (T[]) Array.newInstance(cls, c.size());
        return c.toArray(array);
    }



    @Override
    public void activated() {
        super.activated();
        resubscribe();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy