Как стать автором
Обновить
20
0

Пользователь

Отправить сообщение

Читал я однажды книжку, в которой (видимо, после массовой замены еще -> ещё) встречалось чудесное слово "пещёра".


Как теперь статью плюсовать, чтобы не картинку не испортить?

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

В самом начале, как раз, указан пример требований (очередь с приоритетом и отложенным перезапуском не обработанных из-за исключений задач) и отмечены ограничения применимости.

Вот давайте попробуем выполнить эти требования при помощи MQ. Давайте даже ослабим требования, исключив приоритет задач.

Возьмём MQ, которая умеет отложенную доставку сообщений. Например, ActiveMQ.

Шлём упавшие задачи в ту же очередь с заданной задержкой доставки. Всё ok, но однажды возникает вопрос: сколько в этой очереди новых задач и сколько повторных?

Тогда давайте разделим очередь на две: в одну пишем новые, в другую — упавшие с задержкой. Отлично. Как теперь балансировать нагрузку на воркеры? 50% на новые, 50% на упавшие? А если упавших мало, то 50% мощностей будут простаивать? Брать задачи из каждой очереди по очереди?

Допустим, как-то решили этот вопрос. Далее. Как узнать, какие основные причины, по которым задачи попадают в очередь упавших? Ну, наверное, надо логи погрепать…

Ладно. А как быть уверенным, что в очереди находятся действительно все упавшие задачи, и какая-то не потерялась? Ну, например, воркер может писать в какую-нибудь БД, когда он взял в работу задачу. И поискать в этой БД невыполненные задачи, которые давно не обновлялись (не брались в работу).

А зачем нам тогда очередь, если у нас уже есть таблица с задачами, их статусом и временем последней попытки выполнения?

По поводу update-ов в БД. Для одной задачи в лучшем случае выполняется 1 insert и 2 update (взять задачу, завершить задачу). Во время выполнения задачи в БД могут совершаться десятки и сотни запросов на вставку и изменение строк.

Эти программисты так любят что-то менять в БД, они что, не понимают, что при этом каждый раз создаётся новая запись?! Давайте им запретим.

Изюминка ситуации в том, что в одном из моих текущих проектов очень активно используется ActiveMQ. И её использование в некоторых случаях не соответствует эксплуатационным требованиям. И я с самого начала знал, что она не будет им соответствовать. И вот сейчас, когда самописная очередь прошла проверку на менее критичных задачах в менее критичных проектах, придёт, наконец, время заменить один не очень хороший инструмент на другой, тоже не очень хороший, но получше.
3. Супервизор.
Супервизор запускает и поддерживает заданное количество работающих исполнителей.
Супервизор следит за исполнителями. При аварийном завершении исполнителя перезапускает задачу. При превышении заданного времени работы исполнитель убивается, задача перезапускается.
Очень дельное замечание (как и другие ваши комментарии в ветке), спасибо.

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

При подготовке статьи код берётся из работающей системы, обобщается и упрощается. Здесь легко потерять некоторые нюансы или не донести контекст.

Например, отмеченные вами проблемы завершения задач в контексте процессов моей системы проблемами не являются, поскольку

1) перезапуск уже завершённой задачи допустим и к катастрофе не приведёт;

2) за исполнителями наблюдает супервизор и принудительно завершает их по таймауту, перезапуская взятые исполнителями задачи. Пример перезапуска задач в статье нужен для ситуации, когда аварийно завершился супервизор (и при этом были убиты все подчинённые ему исполнители).

Наверное, выступление на конференции можно приравнять к публикации в журнале.

Несколько лет назад я посетил одну IT-конференцию. В «обычных» секциях (back, front, etc) всё было как обычно: мы сделали вот так-то и получили вот это, мы молодцы, вы тоже можете попробовать и у вас, скорее всего, получится.

Но была на той конференции ещё одна секция — «околонаучная». Там рассказывали про придуманные или модифицированные алгоритмы, внутреннее устройство БД, было что-то про data-science. В основном, выступали программисты, но на темы, которые не укладывались в тематику секции backend, например.

И был один доклад человека из университета о вычислениях в гетерогенных средах. Тема действительно была очень интересная, докладчик рассказывал, как космические корабли бороздят просторы Большого театра код компилируется под целевой компьютер, передаётся вместе с необходимыми данными на целевой узел и всё это работает вот чуть ли не прямо сейчас. Я уже успел вообразить, как соединю всю свою домашнюю вычислительную технику (от роутера до принтера) в сеть и буду на ней нейросети гонять (тоже ставшая очень «горячей» в то время тема) или ещё какую математику. И после выступления задаю два вопроса: «Спасибо за доклад, очень интересно и круто. 1) Где бы увидеть код и 2) как бы в этой теме поучаствовать?» Докладчик как-то замялся и ответил в духе: «Ну-у, это так-то академические исследования, приходите к нам в лабораторию аспирантом. И кода тоже как бы нет, на гитхабе какой-то старый-старый proof-of-concept на Ruby, который даже и не работает...» Ведущий секции пришёл на помощь, вопрос быстро замяли и обсуждение увели в теоретическую плоскость «а вот бы в этой штуке infiniband от Intel ещё бы использовать, тогда вобще сингулярность наступит».

Может, в академической среде действительно так принято, как выше отметил stilic?
Немного покритикую.

1. Насколько я понял, этот процессор не умеет работать с памятью (RAM).
2. Не понятно, зачем нужен стек на 16 слов, если есть 19 неиспользуемых регистров.
3. За регистрами PLUS, AND, OR, XOR спрятано неплохое такое АЛУ (Арифметико-логическое устройство). И ещё аппаратный генератор случайных чисел. Получается как-то не очень: давайте сделаем АЛУ с четырьмя операциями, но номального доступа к ним не дадим. Тут должна была быть шутка про сложные хирургические операции через не подходящие для этого отверстия.

Критикуя — предлагай!

Давным-давно в далёкой-далёкой галактике на форуме WASM.RU пользователь Black_mirror опубликовал такую тему:

Однокомандный dzen-процессор ;)

Исходное сообщение
Число регистров - 2^k (k должно быть не менее 3, наверное :)
    (к ним также относится счётчик команд ip)
Архитектура - трехадресная
Число команд - одна единственная (условное вычитание)
Число флагов - один (f - флаг переполнения)
Разрядность машинного слова - 2+3*k
Максимально адресуемое число ячеек памяти - 2^(2+3*k)
 
Все обрабатываемые числа считаются положительными,
-1=11...1111 - максимальное число
 
Формат команды:
 
тип
00 R1 R2 R3 - csub R1,R2,R3 if f=0 then R1:=R2-R3,f:=R3>R2 else f=0
01 R1 R2 R3 - csub R1,R2,[R3]   if f=0 then R1:=R2-[R3],f:=[R3]>R2 else f=0
10 R1 R2 R3 - csub R1,[R2],R3   if f=0 then R1:=[R2]-R3,f:=R3>[R2] else f=0
11 R1 R2 R3 - csub [R1],R2,R3   if f=0 then [R1]:=R2-R3,f:=R3>R2 else f=0
 
R1,R2,R3 - поля размером k бит, вся команда занимает одну ячейку памяти
 
Основной цикл:
Проверить флаг
    если f=0
        1) считать команду из памяти
        2) если тип команды 01 или 10 - считать операнд из памяти
        3) вычислить разность и установить флаг при переполнении
        4) записать результат в приёмник и увеличить счетчик команд
        если он(ip) не является приёмником данной команды       
    иначе
        сбросить флаг
    перейти к началу
 
При включении питания или поступлении сигнала сброса все регистры и флаг
переполнения обнуляются, и начинает выполняться команда расположеная по
нулевому адресу.
 
Примеры(предполагается что в начале флаг переполнения сброшен)
 
1) обнуление регистра
 
csub r,r,r; ;r=0
 
2) загрузка в регистр единицы
 
csub r,r,r  ;r=0
csub r,ip,r ;r=$(адрес этой команды)
csub r,ip,r     ;r=1
 
3) сложение регистров a и b
 
csub r,r,r      ;r=0
csub b,r,b  ;b=-b
csub r,r,r  ;при b>0 эта команда не выполяется
csub a,a,b  ;a=a-(-b)
csub r,r,r  ;при -b>a эта команда не выполяется
 
4) проверка числа на 0
 
csub z,z,z
csub z,z,r
csub <- эта команда будет выполнена если r=0
 
5) загрузка из памяти
 
csub z,z,z
csub r,[m],z
 
6) сохранение в памяти
 
csub z,z,z
csub [m],r,z
 
7) деление числа в регистре a на число в регистре b, с записью частного в
регистр d и остатка в регистр a
 
#1 csub z,z,z   ;z=0
#2 csub m,ip,z  ;m=$
#3 csub m,m,ip  ;m=-1
#4 csub z,z,z   ;никогда не исполняется
#5 csub d,d,d   ;d=0
#6 csub l,ip,m  ;l=адрес следующей команды
;начало цикла
#7 csub d,d,m   ;d=d-(-1) не исполняется при первом проходе цикла
#8 сsub z,z,z  ;исполняется только при первом прохорде
#9 csub a,a,b   ;a=a-b
#10 csub ip,l,z ;ip=l-z, то есть переход в начало цикла если в предыдущей
        ;команде не произошло переполнение
;далее довычисление остатка
#11 csub z,z,b  ;z=z-b
#12 csub z,z,z  ;на результат предыдущей команды не влияет
#13 csub a,a,b  ;формирование остатка
 
 
Работа алгоритма:
 
пусть a=7 и b=3
#1 z=0 f=0
#2 m=2 f=0
#3 m=-1 f=1 -1=11...1111
#5 d=0 f=0
#6 l=7 f=1
 
#8 z=0 f=0
#9 a=4 f=0
#10 ip=7 f=0
 
#7 d=1 f=1
#9 a=1 f=0
#10 ip=7 f=0
 
#7 d=2 f=1  частное уже вычислено
#9 a=-2 f=1     -2=11...1110
 
#11 z=-3 f=1    -3=11...1101
#13 a=1 f=0 остаток тоже вычислен




Брюзжание-mode on
Да, были люди в наше время,
Не то, что нынешнее племя:
Богатыри — не вы!
М. Ю. Лермонтов, Бородино
В условном «кровавом энтрепрайзе»™ мне довольно часто встречалась задача «пропатчить» буквально один узел в XML-документе (в том числе, не существующий в исходном документе). Писать для этого полноценное XSL-преобразование (или делать десериализацию в объект) совершенно не хочется. И «конструирующий XPath» здесь — то, что доктор прописал.
Следующий шаг — написать макрос, создающий тип и функцию-конструктор:
(defmacro def-grid-node [name props grid] ...)

(def-grid-node FireHands {:magic :fire, :limbs :hands} #'grid)

(defmethod canFireball FireHands [p] (> (:mana p) 0))

(def simpleMage (->FireHands {:mana 100}))

Насколько я понял, идея заключается в диспетчеризации методов по набору мета-свойств объекта. Каждый объект помимо своих свойств получает мета-свойства «класса»: феникс из примера не просто некое существо с заданной силой и маной, это магическое существо с крыльями, владеющее магией огня.

         раса     магия   конечности  материал  есть ручка для переноски?
маг      маг      огонь   руки        -         -
варвар   человек  -       руки        -         -
феникс   маг      огонь   крылья      -         -
эльф     эльф     воздух  руки        -         -
чайник   -        -       -           железо    да
тарелка  -        -       -           фарфор    нет
голем    голем    -       руки        железо    -


Поиск метода происходит по набору мета-свойств объекта, сам метод выполняется над свойствами объекта. Невозможно выполнить метод над объектом, который не предназначен для этого.
Эльф не расплавится при температуре 1540 °C как чайник (и голем). Железный голем не может летать, но может развести огонь. У кенгуру нет рук, он не сможет стрелять из ПЗРК.

Преимущество представленного метода по сравнению с миксинами или какой-либо формой множественного наследования заключается в декларативном описании мета-свойств объектов и в безопасном выполнении любой функции над любым объектом (при условии адекватного ничего-не-делающего поведения по-умолчанию).
Среди тысяч ложных, конечно, встретятся и десятки истинных.
Есть такая возможность в списке всех показателей. Из этого списка графики открываются в новых вкладках с адресом вида odpr.bakhmatov.ru/factors/14233/14336

Информация

В рейтинге
Не участвует
Откуда
Пермь, Пермский край, Россия
Зарегистрирован
Активность