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

com.netflix.dyno.queues.redis.v2.MultiRedisQueue Maven / Gradle / Ivy

/**
 * Copyright 2017 Netflix, Inc.
 * 

* 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.netflix.dyno.queues.redis.v2; import com.netflix.dyno.queues.DynoQueue; import com.netflix.dyno.queues.Message; import java.io.IOException; import java.lang.UnsupportedOperationException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** * @author Viren * MultiRedisQueue exposes a single queue using multiple redis queues. Each RedisQueue is a shard. * When pushing elements to the queue, does a round robin to push the message to one of the shards. * When polling, the message is polled from the current shard (shardName) the instance is associated with. */ public class MultiRedisQueue implements DynoQueue { private List shards; private String name; private Map queues = new HashMap<>(); private RedisPipelineQueue me; public MultiRedisQueue(String queueName, String shardName, Map queues) { this.name = queueName; this.queues = queues; this.me = queues.get(shardName); if (me == null) { throw new IllegalArgumentException("List of shards supplied (" + queues.keySet() + ") does not contain current shard name: " + shardName); } this.shards = queues.keySet().stream().collect(Collectors.toList()); } @Override public String getName() { return name; } @Override public int getUnackTime() { return me.getUnackTime(); } @Override public List push(List messages) { int size = queues.size(); int partitionSize = messages.size() / size; List ids = new LinkedList<>(); for (int i = 0; i < size - 1; i++) { RedisPipelineQueue queue = queues.get(getNextShard()); int start = i * partitionSize; int end = start + partitionSize; ids.addAll(queue.push(messages.subList(start, end))); } RedisPipelineQueue queue = queues.get(getNextShard()); int start = (size - 1) * partitionSize; ids.addAll(queue.push(messages.subList(start, messages.size()))); return ids; } @Override public List pop(int messageCount, int wait, TimeUnit unit) { return me.pop(messageCount, wait, unit); } @Override public Message popWithMsgId(String messageId) { throw new UnsupportedOperationException(); } @Override public Message unsafePopWithMsgIdAllShards(String messageId) { throw new UnsupportedOperationException(); } @Override public List peek(int messageCount) { return me.peek(messageCount); } @Override public boolean ack(String messageId) { for (DynoQueue q : queues.values()) { if (q.ack(messageId)) { return true; } } return false; } @Override public void ack(List messages) { Map> byShard = messages.stream().collect(Collectors.groupingBy(Message::getShard)); for (Entry> e : byShard.entrySet()) { queues.get(e.getKey()).ack(e.getValue()); } } @Override public boolean setUnackTimeout(String messageId, long timeout) { for (DynoQueue q : queues.values()) { if (q.setUnackTimeout(messageId, timeout)) { return true; } } return false; } @Override public boolean setTimeout(String messageId, long timeout) { for (DynoQueue q : queues.values()) { if (q.setTimeout(messageId, timeout)) { return true; } } return false; } @Override public boolean remove(String messageId) { for (DynoQueue q : queues.values()) { if (q.remove(messageId)) { return true; } } return false; } @Override public boolean ensure(Message message) { throw new UnsupportedOperationException(); } @Override public boolean containsPredicate(String predicate) { return containsPredicate(predicate, false); } @Override public String getMsgWithPredicate(String predicate) { return getMsgWithPredicate(predicate, false); } @Override public boolean containsPredicate(String predicate, boolean localShardOnly) { throw new UnsupportedOperationException(); } @Override public String getMsgWithPredicate(String predicate, boolean localShardOnly) { throw new UnsupportedOperationException(); } @Override public Message popMsgWithPredicate(String predicate, boolean localShardOnly) { throw new UnsupportedOperationException(); } @Override public List bulkPop(int messageCount, int wait, TimeUnit unit) { throw new UnsupportedOperationException(); } @Override public List unsafeBulkPop(int messageCount, int wait, TimeUnit unit) { throw new UnsupportedOperationException(); } @Override public Message get(String messageId) { for (DynoQueue q : queues.values()) { Message msg = q.get(messageId); if (msg != null) { return msg; } } return null; } @Override public Message localGet(String messageId) { throw new UnsupportedOperationException(); } @Override public long size() { long size = 0; for (DynoQueue q : queues.values()) { size += q.size(); } return size; } @Override public Map> shardSizes() { Map> sizes = new HashMap<>(); for (Entry e : queues.entrySet()) { sizes.put(e.getKey(), e.getValue().shardSizes().get(e.getKey())); } return sizes; } @Override public void clear() { for (DynoQueue q : queues.values()) { q.clear(); } } @Override public void close() throws IOException { for (RedisPipelineQueue queue : queues.values()) { queue.close(); } } @Override public List getAllMessages() { throw new UnsupportedOperationException(); } @Override public void processUnacks() { for (RedisPipelineQueue queue : queues.values()) { queue.processUnacks(); } } @Override public void atomicProcessUnacks() { throw new UnsupportedOperationException(); } private AtomicInteger nextShardIndex = new AtomicInteger(0); private String getNextShard() { int indx = nextShardIndex.incrementAndGet(); if (indx >= shards.size()) { nextShardIndex.set(0); indx = 0; } String s = shards.get(indx); return s; } @Override public List unsafePeekAllShards(final int messageCount) { throw new UnsupportedOperationException(); } @Override public List unsafePopAllShards(int messageCount, int wait, TimeUnit unit) { throw new UnsupportedOperationException(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy