dyno-queues icon indicating copy to clipboard operation
dyno-queues copied to clipboard

Misleading exception thrown when dynamo can't connect to any node in cluster

Open maryoush opened this issue 8 years ago • 2 comments

This happens when nodes denoted as dynamo cluster hosts are not available (see attached project)

We receive somewhere in logs

[WARN] [com.netflix.dyno.connectionpool.impl.HostConnectionPoolImpl] Unable to make any successful connections to host Host [hostname=localhost, ipAddress=127.0.0.1, port=8102, rack: rack1, status: Up]

but the exception which is being received while calling

 DynoJedisClient dynoClient = new DynoJedisClient.Builder()  //
                .withApplicationName("appname")   //
                .withHostSupplier(customHostSupplier)  //
                .withCPConfig(connectionPoolConfiguration)//
                .build();

is ugly ArrayIndexOutOfBoundsException

Caused by: java.lang.RuntimeException: java.lang.ArrayIndexOutOfBoundsException: 0
	at com.netflix.dyno.jedis.DynoJedisClient$Builder.startConnectionPool(DynoJedisClient.java:3414)
	at com.netflix.dyno.jedis.DynoJedisClient$Builder.buildDynoJedisClient(DynoJedisClient.java:3383)
	at com.netflix.dyno.jedis.DynoJedisClient$Builder.build(DynoJedisClient.java:3302)
	at com.hybris.decay.client.DynoQueueClient.<init>(DynoQueueClient.java:62)
	at com.hybris.decay.client.DynoQueueClient.<init>(DynoQueueClient.java:38)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
	... 77 more
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
	at com.netflix.dyno.connectionpool.impl.lb.HostSelectionWithFallback.calculateReplicationFactor(HostSelectionWithFallback.java:389)
	at com.netflix.dyno.connectionpool.impl.lb.HostSelectionWithFallback.initWithHosts(HostSelectionWithFallback.java:346)
	at com.netflix.dyno.connectionpool.impl.ConnectionPoolImpl.initSelectionStrategy(ConnectionPoolImpl.java:605)
	at com.netflix.dyno.connectionpool.impl.ConnectionPoolImpl.start(ConnectionPoolImpl.java:505)
	at com.netflix.dyno.jedis.DynoJedisClient$Builder.startConnectionPool(DynoJedisClient.java:3397)
	... 86 more

maryoush avatar Dec 16 '16 12:12 maryoush

import com.netflix.dyno.connectionpool.Host;
import com.netflix.dyno.connectionpool.HostSupplier;
import com.netflix.dyno.connectionpool.TokenMapSupplier;
import com.netflix.dyno.connectionpool.impl.ConnectionPoolConfigurationImpl;
import com.netflix.dyno.connectionpool.impl.lb.AbstractTokenMapSupplier;
import com.netflix.dyno.jedis.DynoJedisClient;
import com.netflix.dyno.queues.DynoQueue;
import com.netflix.dyno.queues.Message;
import com.netflix.dyno.queues.ShardSupplier;
import com.netflix.dyno.queues.redis.RedisQueues;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class Main {

    private final static Logger LOG = LoggerFactory.getLogger(Main.class);
    
    private static final String queueName = "test_queue";

    private static final String redisKeyPrefix = "testdynoqueues";

    private static final String RACK = "rack1";


    final static String json = "[" + //
            "{\"zone\":\"rack1\",\"hostname\":\"host1\",\"host\":\"127.0.0.1\",\"port\":\"8102\",\"token\":\"1383429731\"}," +//
            "{\"zone\":\"rack2\",\"hostname\":\"host2\",\"host\":\"127.0.0.2\",\"port\":\"8102\",\"token\":\"1383429731\"}," +//
            "{\"zone\":\"rack3\",\"hostname\":\"host3\",\"host\":\"127.0.0.3\",\"port\":\"8102\",\"token\":\"1383429731\"}" +//
            "]";

    final static HostSupplier customHostSupplier = new HostSupplier() {

        final List<Host> hosts = new ArrayList<Host>();

        @Override
        public Collection<Host> getHosts() {
            hosts.add(new Host("host1", "127.0.0.1", 8102, Host.Status.Up).setRack("rack1"));
            hosts.add(new Host("host2", "127.0.0.2", 8102, Host.Status.Up).setRack("rack2"));
            hosts.add(new Host("host3", "127.0.0.3", 8102, Host.Status.Up).setRack("rack3"));

            return hosts;
        }
    };


    private static TokenMapSupplier testTokenMapSupplier = new AbstractTokenMapSupplier() {


        @Override
        public String getTopologyJsonPayload(final Set<Host> activeHosts) {
            return json;
        }

        @Override
        public String getTopologyJsonPayload(String hostname) {
            return json;
        }
    };


    final static Set<String> allShards = customHostSupplier.getHosts().stream().map(host -> host.getRack().substring(
            host.getRack().length() - 2)).collect(Collectors.toSet());


    public static void main(String... args) throws Exception {
        ConnectionPoolConfigurationImpl connectionPoolConfiguration = new ConnectionPoolConfigurationImpl(RACK);
        connectionPoolConfiguration.withTokenSupplier(testTokenMapSupplier);
        connectionPoolConfiguration.setLocalRack(RACK);

        String shardName = allShards.iterator().next();

        ShardSupplier ss = new ShardSupplier() {

            @Override
            public Set<String> getQueueShards() {
                return allShards;
            }

            @Override
            public String getCurrentShard() {
                return shardName;
            }
        };

        DynoJedisClient dynoClient = new DynoJedisClient.Builder()  //
                .withApplicationName("appname")   //
                .withHostSupplier(customHostSupplier)  //
                .withCPConfig(connectionPoolConfiguration)//
                .build();

        RedisQueues rq = new RedisQueues(dynoClient, dynoClient, redisKeyPrefix, ss, 1_000, 1_000_000, 100);

.....

maryoush avatar Dec 16 '16 12:12 maryoush

Hi everyone, I also want to be a contributor to this project. Can anybody please tell me what i need to do for that ?

princejha95 avatar Oct 19 '19 19:10 princejha95