Вы отлично описали мою ситуацию в данный момент. Последние 9 лет работал на java 7 и OSGI, один стек в двух разных компаниях, который не меняется, т.к. бизнесу это не нужно. Долго не решался сменить работу, а теперь вышел на собеседования и везде теперь стандарт спринг, микросервисы, кафка, ощущаю себя джуном с 9 летним опытом . Пытаюсь наверстать упущенное книгами, пет проектами, ищу подходящую вакансию. Считаю, что сам виноват, что не следил за рынком и не развивался. Нужно было уделять этому время, делая пет проекты.
Да, при старте запускается 10 worker`ов. Сообщение пользователя помещается в общую очередь. Тут уточню, что в моем случае, используемая библиотека, реализует паттерн "производитель потребитель", т.е. один поток наполняет общую очередь, другой берет из очереди задачи и решает их. Так вот, я получал от второго потока, "потребителя", задачу и передавал на выполнение в один из worker`ов.
Вы как раз говорите, о способе выбора worker`а для передачи ему задачи. У меня каждый worker (BotMessageQueueExecutor в моем примере) - это очередь с одним обработчиком и переменная для хранения TelegramID.
Есть класс, который получает от потока "потребителя" задачу и выбирает worker, это BotMessageExecutor. Вот в нем есть метод getAvailableExecutor() который и делает выбор worker`а. Только вот пока готовил ответ, понял, что в моем коде ошибка - спасибо вам, так бы и не заметил. Для выбора, нужно сначала найти среди worker`ов того, кто в данный момент обрабатывает задачи текущего TelegramID, если такого нет, то нужно уже искать первый свободный или простаивающий worker, даже если TelegramID не совпадают. В моем примере ошибка в этом методе, т.к. нужно сначала проверять именно все worker`ы на соответствие TelegramID, а я этого не сделал.
Таким образом, worker закрепляется за каким то TelegramID при получении задачи, но когда он будет простаивать и нам нужен будет worker для задачи с другим TelegramID, то мы можем его использовать.
Круто увидеть у кого то похожее решение какой то проблемы) Такую же параллельную обработку очереди делал на java. В моем случае использовалась библиотека https://github.com/rubenlagus/TelegramBots и она тоже все сообщения от всех пользователей обрабатывает последовательно.
Есть один тонкий момент в обработке одной очереди: вы можете обработать два запроса от одного пользователя одновременно или не в порядке их получения, что приводит к нарушению бизнес логики. Например пользователь нажимает по очереди разные inline button, пока бот "подвис".
Как я понял, ваш пример этому подвержен. В моем проекте, на каждый "worker" создавалась дополнительная очередь. При появлении задачи в общей очереди, задача на основании TelegramID, закрепляется за свободной очередью "worker`a" и с этого времени этот "worker" обрабатывает только задачи этого TelegramID в порядке их появления. "worker" освобождается, когда его очередь кончается. Так мне удалось решить эту проблему в моем случае.
Вы отлично описали мою ситуацию в данный момент. Последние 9 лет работал на java 7 и OSGI, один стек в двух разных компаниях, который не меняется, т.к. бизнесу это не нужно. Долго не решался сменить работу, а теперь вышел на собеседования и везде теперь стандарт спринг, микросервисы, кафка, ощущаю себя джуном с 9 летним опытом . Пытаюсь наверстать упущенное книгами, пет проектами, ищу подходящую вакансию.
Считаю, что сам виноват, что не следил за рынком и не развивался. Нужно было уделять этому время, делая пет проекты.
Да, при старте запускается 10 worker`ов. Сообщение пользователя помещается в общую очередь. Тут уточню, что в моем случае, используемая библиотека, реализует паттерн "производитель потребитель", т.е. один поток наполняет общую очередь, другой берет из очереди задачи и решает их. Так вот, я получал от второго потока, "потребителя", задачу и передавал на выполнение в один из worker`ов.
Для наглядности даю ссылку на свой код github
Вы как раз говорите, о способе выбора worker`а для передачи ему задачи. У меня каждый worker (BotMessageQueueExecutor в моем примере) - это очередь с одним обработчиком и переменная для хранения TelegramID.
Есть класс, который получает от потока "потребителя" задачу и выбирает worker, это BotMessageExecutor. Вот в нем есть метод getAvailableExecutor() который и делает выбор worker`а. Только вот пока готовил ответ, понял, что в моем коде ошибка - спасибо вам, так бы и не заметил. Для выбора, нужно сначала найти среди worker`ов того, кто в данный момент обрабатывает задачи текущего TelegramID, если такого нет, то нужно уже искать первый свободный или простаивающий worker, даже если TelegramID не совпадают. В моем примере ошибка в этом методе, т.к. нужно сначала проверять именно все worker`ы на соответствие TelegramID, а я этого не сделал.
Таким образом, worker закрепляется за каким то TelegramID при получении задачи, но когда он будет простаивать и нам нужен будет worker для задачи с другим TelegramID, то мы можем его использовать.
Надеюсь удалось донести до вас свою мысль)
Круто увидеть у кого то похожее решение какой то проблемы) Такую же параллельную обработку очереди делал на java. В моем случае использовалась библиотека https://github.com/rubenlagus/TelegramBots и она тоже все сообщения от всех пользователей обрабатывает последовательно.
Есть один тонкий момент в обработке одной очереди: вы можете обработать два запроса от одного пользователя одновременно или не в порядке их получения, что приводит к нарушению бизнес логики. Например пользователь нажимает по очереди разные inline button, пока бот "подвис".
Как я понял, ваш пример этому подвержен. В моем проекте, на каждый "worker" создавалась дополнительная очередь. При появлении задачи в общей очереди, задача на основании TelegramID, закрепляется за свободной очередью "worker`a" и с этого времени этот "worker" обрабатывает только задачи этого TelegramID в порядке их появления. "worker" освобождается, когда его очередь кончается.
Так мне удалось решить эту проблему в моем случае.