Обработка приоритетов SMS-очереди - PullRequest
0 голосов
/ 27 июня 2018

У меня есть более логичная проблема, чем программирование, и я решил спросить здесь. Я должен создать систему массовых смс, которые имеют ограниченную пропускную способность. Оператор может отправить только 2 SMS / сек. У меня есть смс-сайт, где клиенты могут планировать объемы. Каждый пакет содержит различное количество SMS-сообщений (1000, 2000, 10 000 и т. Д.) И может быть запланировано в любое время. Проблема возникает, когда на одно и то же время запланировано 2 или более сыпучих материала, например, в 15:00. Я хочу выполнить все объемы в зависимости от того, какой приоритет имеет каждый из них. Это означает, что ни один из них не будет выполнен первым, а затем вторым, третьим и т. Д., Но, например, чтобы отправить 3 SMS-сообщения с наибольшим приоритетом, а затем 2 SMS-сообщения с ниже и затем 1 от наименьшего приоритета, а затем продолжайте в том же духе, пока не будут отправлены все SMS. Возможно, я ищу какую-то очередь, но не могли бы вы предложить какое-нибудь хорошее решение и структуру данных, подходящую для моего случая?

Мое решение будет на Java!

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Если бы вы выбирали сообщения с наивысшим приоритетом, то очередь с простым приоритетом работала бы, в памяти или из базы данных. Но вы намереваетесь получить некоторые сообщения из всей очереди. Вот грубая реализация, чтобы дать вам идею. Вы можете экстраполировать его на массовый сценарий.

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

public final class NQueue
{
    private final List<Deque<String>> queues = new ArrayList<>();
    private final int[] poll;
    private int currentIndex;
    private int queueIndex;
    private final int pollWidth;

    public NQueue(int[] poll)
    {
        this.poll = new int[poll.length];
        int sum = 0;
        for (int i = 0; i < poll.length; i++)
        {
            int val = poll[i];
            sum += val;
            this.poll[i] = sum;
            queues.add(new LinkedList<>());
        }
        this.pollWidth = sum;
    }

    public synchronized void addMessage(String msg, int priority)
    {
        queues.get(priority).add(msg);
    }

    public synchronized Optional<String> removeMessage()
    {
        for (int i = 0; i < this.pollWidth; i++)
        {
            updateQueueIndex();
            String msg = queues.get(queueIndex).poll();
            currentIndex++;
            if (msg != null)
            {
                return Optional.of(msg);
            }
        }
        return Optional.empty();
    }

    private void updateQueueIndex()
    {
        if (currentIndex == pollWidth)
        {
            currentIndex = 0;
            queueIndex = 0;
        }
        else if (currentIndex == this.poll[this.queueIndex])
        {
            queueIndex++;
        }
    }
}

Пример клиента.

//in every run, poll 3 from priority 0, 2 from priority 1 and 1 from priority 2
NQueue nQueue = new NQueue(new int[]{3,2,1});

nQueue.addMessage("a",0);
nQueue.addMessage("b",1);
nQueue.addMessage("c",2);
nQueue.addMessage("d",1);
nQueue.addMessage("e",0);
nQueue.addMessage("f",1);
nQueue.addMessage("g",1);

for (int i = 0; i < 10; i++)
{
    Optional<String> s = nQueue.removeMessage();
    System.out.println("s = " + s);
}

печатает

s = Optional[a]
s = Optional[e]
s = Optional[b]
s = Optional[d]
s = Optional[c]
s = Optional[f]
s = Optional[g]
s = Optional.empty
s = Optional.empty
s = Optional.empty
0 голосов
/ 27 июня 2018

Я думаю, вы можете иметь 2 таблицы в БД:

  1. СМС (id, текст, статус, bulk_id)
  2. Bulk (id, priority)

Вы можете организовать приоритет, собрав все объемы, затем отсортировав их в том порядке, в котором вы хотите их обработать (или запросите их уже отсортированными). Для каждой группы получите столько SMS-сообщений, сколько вы хотите (по приоритету), и отправьте их, затем отметьте их как «отправлено». Вы будете знать, что основная масса обрабатывается, когда для этой массы нет SMS со статусом «готово к отправке».

Недостаток этого подхода в том, что у вас больше нагрузки на БД, но у вас ОЧЕНЬ узкое место (2SMS / сек), так что это не будет проблемой для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...