LINUX.ORG.RU

Сообщения DRVTiny

 

Система управления конфигурациями, которой не обязателен ssh?

Ситуация такая: есть доступы к портам, которые зарезервированы за совершенно другим софтом, хотелось бы их полулегально использовать для системы управления конфигурациями.

Для этого от СУК требуется:

1) Управление клиентами/нодами/агентами со стороны мастера/сервера коннектом на порт X

Собственно, всё... :)

Но проблема в том, что порт - совсем не 22-й, а сам протокол очень желательно, чтобы не был слишком уж похож на ssh.

Можно замутить openvpn во все концы, тогда вообще любая конфигурация взлетит, но как-то это геморно, да и openvpn тоже засечь не так уж сложно (всякие грёбаные фаерволлы его легко распознают).

В идеале хотелось бы, чтобы мастер коннектился к своим нодам на порту X и общался с ними по своему протоколу, который фаерволлам неведом/неинтересен.

С оговорками puppet (ruby) вроде устраивал, но во-первых что-то к 5-й версии он уже стал ппц мудрёным и тяжёлым, а во-вторых - по-моему там всё-таки есть коннекты от нод к мастеру? Мне такое точно не нужно.

Смотрел ещё rexify (perl'овый) - тотально ssh-ный и как всегда через Ж описано самое главное - взаимодействие нод и сервера, ansible (python) хочет подключаться к нодам по ssh и на 22-м порту (поправьте меня, если я не прав).

Может, ещё что-то есть? Я уж думаю хотя бы для самых простых зада ч синхронизации файлов вообще rsync-демон использовать, а то достало уже: что так всем этот ssh сдался-то.

 , , , rexify

DRVTiny
()

The best target для внедрения майнилок

Я тут подумал, что лучше всего внедрять майнилки в игры, раздаваемые на торрентах. Желательно какие-нибудь массовые и средние по требованиям к GPU.

Я в танке, и уже были многочисленные прецеденты? Или я в танке, но пока это не массовое явление?

Почитал тут статью на хабре - там предлагают что-то хитро внедрять через бесплатный WiFI, JavaScript'ом майнить. Но смысла в этом не много по-моему: мощные устройства переносными редко бывают, и ещё реже на них стоит хороший мощный GPU.

А тут - выкладываешь игру с креком для обхода защиты - и все считают тебя героем, и никто даже не замечает, что их GPU греется чуть больше обычного...

Есть такое дело?

 , foolstory, hacking

DRVTiny
()

Кольцевой двухсвязный список ограниченного размера

Собственно, пишу соотв. класс (пока для Perl). Мне он нужен для того, чтобы задания, поставленные в очередь отправки, в случае успешной отправки выдёргивать из списка-кольца. То, что одно задание отправится - не гарантирует успеха с остальными, поэтому нельзя очищать просто N элементов подряд из очереди: есть вероятность того, что какое-то задание удастся грохнуть из списка, а какие-то придётся оставить до следующей попытки.

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

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

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

Условно - если размер кольца 5 элементов, то на стеке изначально будут лежать : [4,3,2,1,0] - и первый pop возьмёт индекс 0, создаст в nodes_list[0] узел с NULL-ссылками на next и prev ноды.

Может, на Ruby что-то такое есть, например? Ну или ещё на каком языке с не-Rust и не-C++ подобным синтаксисом?

 dllist,

DRVTiny
()

Нечаянная загадка цикла while

while read -r d; do
        [[ -d $d ]] || {
                echo "$d is not a directory, skipping it" >&2
                continue
        }
        d=${d%%+(/)}
        info_ "Processing <<$d>>"
        { ssh ${remoteHost} "mkdir -p '$d'" && echo 'mkdir OK' >&2; } || echo 'mkdir FAIL' >&2
        rsync -a${flBeVerbose:+v} "${d}/" "${remoteHost}:${d}"

done < <(cat "$confDirList" | sed -r -e '/^\s*(#.*)?$/d' -e 's%\s*(#.*)$%%')

Есть вот такой цикл. В confDirList - путь до файлика с каталогами для синхронизации через перевод строки, либо "-", если нужно читать с STDIN. Целиком код этого скриптика здесь: https://pastebin.com/HbhWLWad

Внимание, вопрос: (какого) почему такое может быть, что если делать ssh в цикле, то цикл выполнится только один раз (и будет напечатано: «mkdir OK»), а если не делать ssh - то всё ОК, выполнится по количеству каталогов в confDirList'е. Каким образом использование ssh может привести к генерации признака EOF при чтении из потока в цикле while??

 , ,

DRVTiny
()

Быстрый «хеш» со статичным набором ключей?

Может, встречал кто-нибудь максимально быструю реализацию на Perl такой логики:

1) В конструктор объекта или tied-переменной передаётся статичный набор ключей и начальных значений

2) Конструктор создаёт ссылку на анонимный массив, для каждого ключа генерирует функцию по типу use constant: KEY_{NAME}() => $count++, для каждого из индексов $count++ - кладёт по ссылке на анонимный массив соотв. индексу значение

3) Класс предоставляет методы «взять,записать значение по ключу»: внутри этот метод проверяет, есть ли соотв функция KEY_{NAME} - и если есть, вызывает её, получает индексы - и дальше по этому индексу кладёт или берёт значение.

Смысл в том, чтобы с одной стороны избавиться от оверхеда времени хеширования, а с другой стороны - избежать нанисания явного тупого прописывания индексов для работы со списком «ну почти как» с хешем.

Понятно, что кодится такое довольно просто (и можно даже список ключей не делать статическим). Но интересует именно максимально быстрая реализация, иначе овчинка в сравнении с реализованными на Си функциями хеширования - выделки в общем-то не будет стоить :)

 , tuples

DRVTiny
()

Реализация open, вписывающаяся в функциональную парадигму?

Товарищи, есть ли для perl какая-либо штатная, либо XS-ная реализация open, которая возвращает значением собственно файловый дескриптор?

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

Понятно, что перловой функцией делается в три буквы:

my %modeName2modeCryptoSymbols=(
 'read' => '<',
 'write' => '>',
 'append' => '>>',
 'edit' => '+<'
...
);
sub fopen ($$) { open my $fh, $modeName2modeCryptoSymbols{$_[1]}, $_[0]; $fh }

Но нет ли сишной готовой реализации? Просто встроенный оператор open в традиционном перловом виде - это какое-то «привет BASIC'у образца 80-х», потому что современный BASIC уже давно так не делает...

 , ,

DRVTiny
()

Чего мне не хватает в Perl?

Пишу на языке давно и успешно, отношусь к нему сугубо положительно, но есть конечно моменты, которые, мягко говоря не устраивают.

Итак, претензии к Perl от человека, который его осилил и знает особенности языка не по наслышке:

1) Не хватает собственно скорости. Скорость исполнения кода, т.е. его непосредственной интерпретации - Ахиллесова пята не только Perl, но и Ruby, и Python, и PHP. Но если интерпретаторы PHP и Python становятся быстрее с каждым годом, то интерпретатор Perl застрял в своём развитии - и при этом язык не имеет LLVM-компиляторов, как тот же Crystal, реализующий очень быстрый диалект Ruby. Для Perl есть RPerl, который непонятно как работает и работает ли у кого-то, кроме самого Вина Бразвелла. Ну и да, RPerl - это всё-таки не вполне Perl, по сути это какой-то «perl'оподобный диалект языка Си»

2) Не хватает адекватной проверки входных параметров. Есть куча сторонних модулей для этого: MooseX::Method::Signatures, Params::Validate и ещё тысячи их, но все они добавляют дикий оверхед к и без того не быстрой работе интерпретатора

3) Отсутствует как класс нормальный параллелизм: без пула потоков работать с потоками невозможно (создание потока - крайне медленная операция), с пулом потоков в принципе удобно, но всё одно памяти они жрут как не в себя. На Perl в 100 раз всё лучше с процессами, в том числе есть неплохие модули для работы с shared memory (правда, Redis для того же самого намного удобнее).

4) CPAN конечно замечательный репозиторий пакетов, но выкладывать что-то туда - это лишняя трата времени, да и все эти инструкции по правильному выкладыванию немного бесят: мне что, заняться больше нечем? ИМХО подход того же Crystal'а с его shards'ами намного удобнее.

5) Отсутствие макрогенерации кода. Есть конечно eval, но это, мягко говоря, всё равно что бульдозером шпалы укладывать: неудобно, анахронично, работает в рантайме (что просто ппц на самом деле), чревато ошибками. Учитывая стоимость вызова процедур в Perl5 отсутствие макрогенерации негативно влияет на потенциальную производительность

Относительно удобства ООП претензий не имею - те, у кого они есть, просто пришли из других языков и пытаются применять к совершенно иначе устроенному Perl'у свои «обобщённые» знания.

 ,

DRVTiny
()

docker-иризированные приложения и вопросы по ним

В связи с тем, что docker широко шагает по планете, и разработчики под Linux особенно сильно его любят, у меня, как у админа-разработчика возник ряд вопросов:

1) Как обновлять библиотеки внутри docker-контейнера? Предположим, у нас на сервере 9000 контейнеров. На самом сервере библиотеки, предположим также, обновляются apt-get upgrade'ом. А внутри контейнеров?

2) Что произойдёт с тем ПО, которое слинковано с библиотеками, если их там в контейнере обновить?

3) А если в библиотеке критическая уязвимость, которую нужно было устранить день назад, то что делать с 2137-ю контейнерами, в которых библиотека (положим, openssl) используется?

4) А что делать, если обновилось ядро системы (бывает такое), а библиотека использует какие-то особенности ядра - старого ядра особенности, которых нет в новом ядре? Ситуация гипотетическая конечно, но бьюсь об заклад, что современная GLibC даже с ядром 2.4 работать не будет, не то что с 2.2, например. А часики тикают, а в контейнерах - безоблачное небо

5) А что мешает разработчикам всё-таки собирать бинарные пакеты? Что принципиально мешает?

Спасибо!

 , ,

DRVTiny
()

Реализуем ли на практике двухсвязный индексированный список?

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

Проблема в том, что из ассоциативных массивов элементы удаляются легко и просто, но при этом ассоциативные массивы нормально не итерируются по значению ключа, и в этом есть некая проблема на фоне того, что сам по себе доступ к элементам АМ осуществляется вычислением дорогостоящей хеш-функции.

Как себе представляю попытку решения проблемы созданием двухсвязного списка и к чему в итоге прихожу:

=== Есть служебная структура данных - перечислитель ===

Перечислитель представляет собой динамический массив смещений до элементов списка для быстрого поиска элемента за номером N.

Перечислитель скорее всего реализуется «на стеке», хотя мне ближе подход с malloc'ами статичных чанков и связыванием этих чанков через ещё одну надстроечную структуру. Проще говоря, такой вектор сам по себе должен быть динамически расширяемым. А как? Ну вот либо malloc'ом выделять чанк, а потом когда закончится - выделять новый и связывать со старым, либо... на этом мысль останавливается, потому что таки да, стек - это не абстракция, а тот же чанк в памяти и у стека тоже есть границы.

=== Есть собственно элементы двухсвязного списка ===

Каждый элемент списка содержит в себе: смещение предыдущего элемента, смещение до полезных данных элемента (payload), размер полезных данных, смещение последующего элемента, индекс текущего элемента.

=== Поиск элемента списка за номером N=3937 ===

Идём в служебную структуру данных - перечислитель, смотрим её заголовок:

ага, элементы с 0 по 2048-й - ищи по смещению такому-то. Не подходит, у нас 3937

следующая запись: элементы с 2048 до 4096 - ищи по смещению AUX_OFFSET

OK, нам подходит, у нас как раз N>2048 && N<4096

Вычисляем смещение до элемента перечислителя, содержащего указатель на элемент списка.

DLL_EL_OFFSET=QWORD(AUX_OFFSET+(3937-2048)*8)

Получили смещение до элемента списка - взяли данные, считав смещение до payload.

=== Удаление элемента из списка ===

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

После непродолжительных раздумий напрашивается вывод о том, что дуализм двухсвязного списка, позволяющий представлять его и как просто вектор, и как список - невозможен без тупого перебора всех элементов списка вплоть до того. как будет найден нужный нам в рамках «парадигмы вектора» элемент N.

Т.е. списки хорошо итерируются влево-вправо, но вот как сделать так, чтобы можно было всё-таки находить просто элемент за номером N со скоростью O(1) (говоря не на птичьем языке - за время, «почти независящее» от этого самого N) ?

В общем, интересно есть ли библиотечные реализации двухсвязных списков, элементы которых можно быстро адресовать по индексу, делая минмальное количество телодвижений и уж точно не делая интенсивных переборов? Безусловно, поиск элемента N может быть более трудоёмким, нежели поиск 0-го, но хотелось, чтобы разница была минимальной, а не «равно максимизированной для всех», как это имеет место быть в случае ассоциативного массива.

P.S. И где-то там за горизонтом сам собой встаёт вопрос о том, а можно ли кешировать результат выполнения хеш-функции? Префиксным деревом, быть может?

 ,

DRVTiny
()

Как увидеть отправляемое curl'ом?

Безуспешно пытаюсь жрать кактус Net::Curl::Easy :(

Есть какая-то странная проблема с POST'ом, которую уже давно не могу решить.

Мне бы сильно помогла отладка на тему того, что libcurl собственно пуляет на сервер.

Но сервер - разумеется, https, и tcpdump'ом фиг что увидишь.

У CURL есть замечательная опция CURLOPT_VERBOSE - она позволяет увидеть, что приложение получает от сервера. И есть CURLOPT_WRITEFUNCTION, которой можно конечно передать некий хендлер, но явно не perl'овый (пробовал, не котируются здесь perl'овые sub'ы).

Соответственно, внимание, вопрос: как увидеть, до какой степени некорректную фигню шлёт на сервер сам Net::Curl::Easy? :)

Превентивное гигантское всем Спасибо!

 ,

DRVTiny
()

HTTP-клиент, возвращающий детальные тайминги?

Нужен HTTP-клиент для движка веб-тестирования.

Сейчас пользуюсь Mojo::UserAgent - для базовых вещей адекватный и настраиваемый вполне (плюс груда пока не слишком нужного функционала).

Но вот захотелось снимать метрику «время DNS-ответа». Можно конечно и отдельно резолвить DNS, потом ещё раз то же самое, но уже из Mojo::UserAgent... Но зачем, это же время теста всё-таки, лишняя нагрузка, потенциальные дополнительные источники багов в самом движке тестирования.

Сам HTTP-клиент, очевидно, может узнать, сколько у него времени отнял DNS-резолвинг. Я порылся в безумной иерархии Mojo-классов - не нашёл ничего вообще связанного с таймингами (в response).

Может быть, плохо смотрел? Может быть, есть какой-то более подходящий для веб-тестов перловый HTTP-клиент?

Возможный вариант ответа: https://metacpan.org/pod/WWW::Mechanize::Timed

НО: про DNS ни слова. Время client_connect и время резолвинга всё-таки хоть и коррелируют, но это сильно не одно и то же.

 , ,

DRVTiny
()

grep с остановкой при первом совпадении?

Есть ли для perl'а какая-либо реализация логики grep, при которой если grep проверяется в булевом контексте, то первое же совпадение приведёт к завершению перебора входного списка?

Просто косячить эту логику циклом for - как-то некошерно, да и короткая форма работает уродливо:

my $f;
my %hsh=('a'..'z');
my $arr=[qw/b c d/]
exists $hsh{$_} and $f=$_, last for @{$arr};

Делать из $arr сначала временный хеш, а потом по нему искать пересечения с %hsh - тоже как-то криво (мягко скажем).

Идеальным был бы вариант:

perl -E 'print "hello\n" if grep { say; $_&1 } 1..31'

Но он печатает всё от 1 до 31, хотя уже первого элемента списка достаточно для true в if'е. Как известно, в grep не работают никакие last'ы, break'и, next'ы. Возможно, есть уже некий кусок XS'ки, исправляющий эту досадную недоработку? Если уж в этом случае grep зачем-то перебирает всё подряд, то чего бы тогда в and и or не вычислять всегда левую и правую части выражения, просто «шоб було»?

Запостил этот вопрос на SO: https://stackoverflow.com/questions/47416807/avoid-grepping-all-in-boolean-co...

 , , ,

DRVTiny
()

Язык, в котором есть constraints'ы

Это то же самое, что типы данных, но для логики приложения, а не логики исполнителя (CPU).

Пример constraint'а: «constrX is integer, [0..55],[117..200],999»

Другой пример: «constrY is string, regexp(^fo+\s+bar$)»

По-моему по сравнению с ограничениями на внешние данные в духе «вот в этом поле число не должно быть больше 2^32-1» потому что у нас битовая разрядность такая - contraint'ы были бы гиганстким шагом вперёд, позволили бы существенно сократить «проверяющий» код и оптмизировать выполнение за счёт того, что нам не пришлось бы создавать объект только ради того, чтобы убедиться в консистентности значения.

Оптимальным видится такой вариант использования: переменная, заполняемая из внешнего источника -> наложение constraint'ов -> внутренняя переменная с мета-тегом «пройдён constraint такой-то».

Т.е. ограничения - это механизм преимущественно для рантайма, во многом упрощающий тестирование и сопровождение софта. Для проверок соответствия ограничениям нужно писать декларативные определения, а не заниматься индусскими изысками с написанием соотв. кода вручную - желательно, ещё и в 30 разных местах.

Например, во всеми нелюбимом perl'е есть уже львиная доля такой логики: а именно taint mode, когда переменные делятся на «грязные» (из внешних источников) и «чистые». Недостаток - как раз в отсутствии простого механизма наложения ограничений, который бы и «очищал» переменную.

Речь о том, что сами по себе типы данных в компилируемых языках - это сказка о повышении производительности, но никак не о повышении стабильности кода. Потому что если в вашу переменную типа UInt8, которая не может быть за диапазоном [101..143] приехало вдруг 235, а вы это не проверили в рантайме - ну как бы тип данных вас точно не спасёт.

В общем, я же правильно понимаю, что везде подобные вещи реализованы сбоку, а не как встроенное средство самого ЯП?

 constraints, ,

DRVTiny
()

Как создать GUI-подобное приложение для десктопного веб и не сойти с ума?

Заголовок очень длинный, но зато суть отражает почти полностью:

суть в том, что мне и далеко не только мне нравится GUI-программирование. Нормальное такое классическое, в результате которого получались такие без гениальные вещи как интерфейс OS/2 WorkPlace Shell, интерфейс Mac OS X Aqua и все последующие...

Отсюда вопрос: а есть ли хоть какой-то вариант писать веб-приложения именно в GUI-стиле? Да, пусть с ограниченным набором виджетов и без каких-то феерических возможностей, но зато с такими классическими вещами, как обработчики событий на виджете, абсолютно адекватным поведением виджетов-контейнеров, правильным взаимодействием между виджетами, унификацией их внешнего вида и широкими возможностями их «тематического» декорирования (гм, вспомните лучше темы KDE). При этом если никому не нужно, чтобы приложение было одним и тем же для мобильных устройств и для десктопа -почему бы не разнести сугубо V составляющую на 2 части, а не пытаться сделать один интерфейс настолько супер-адаптабельным и универсальным, что его код станет по сути SSHA-суммой Книги перемен?

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

В общем, вопрос прост как три копейки: есть ли в 2017-м году хоть один JS-фреймворк, который был бы комфортен для GUI-разработчиков и позволял бы получать работающие в браузере веб-приложения, по сути являющиеся, например, «веб-репликами» их уже написанных GUI-собратьев? Ведь многие же компании, и очень крупные, самые крупные, переводили свои десктопные приложения на веб-платформу. Неужели им всем было в радость просто писать всё заново в чистой веб-парадигме со всеми этими «прекрасными» вещами типа DOM и VirtualDOM?

P.S. Вопрос возник по итогам попытки прочесть https://habrahabr.ru/post/341688 : из прочитанного я не понял практически вообще ничего, хотя у меня есть опыт JS-разработки. Я просто не врубаюсь, что такого полезного с функциональной, осязаемой точки зрения мне даёт всё это...

Внимание, правильный ответ:

https://github.com/qooxdoo/qooxdoo

Огромное спасибо dmxrand и всем-всем-всем, кто помог определиться!

 , ,

DRVTiny
()

Decision tree, но не совсем... как это может называться?

Представьте такую абстракцию:

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

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

На самом деле и простейшие факты тоже могут быть такими «конечными выводами», почему же нет.

Собственно, вопрос не в том, как должен бы работать алгоритм, а в том, как проектировать дерево описанного типа. Для этого нужно понимать, а что это такое :) Как в IT или логике или ещё чём называется дерево, которое следует обходить не начиная с одного-единственного факта сверху вниз, а наоборот - по которому следует подниматься от листьев к «вершинам», т.е. от более простых логических агрегатов (включая элементарные) к более сложным логическим агрегатам, при этом имея на каждом этапе подъёма всё более глобальную и при этом менее точную картину?

По сути это дерево позволяет смотреть на проблему на разных уровнях: начиная от элементарного уровня (у вас загрузка CPU превышает 89%) и заканчивая глобальным уровнем: «Следует провести радикальное обновление парка серверов в ЦОДе таком-то».

Возможно, кроме меня такие штуки никому не нужны и все подстраиваются под логику Decision trees - тогда звиняйте. Но мало ли...

 выводы, ,

DRVTiny
()

Лавина бесполезных изменений в кеше - хорошо ли это?

Предположим, over 128 запущенных на машине процессов, обслуживающих REST-запросы, практически одновременно, независимо друг от друга, получили запросы на сборку дорогостоящего JSON'а. Они все поняли, что та версия, которая ныне лежит в кеше, устарела, и начали вытаскивать данные. Считаем, что процессы никак не взаимодействуют, поскольку это именно процессы, а не потоки - им затруднительно узнать что-то вроде «данные находятся на пересчёте, обождите и приходите в кеш снова, когда данные посчитаются».

Теперь все эти процессы через некоторое время получаю огромный такой текстовый блоб -и хотят его засунуть в кеш обратно. И вот все 128 процессов идут в кеш и засовывают туда этот свой JSON. Вот только... wait, oh shi... да они ведь одно и то же засовывают в один и тот же кеш! Т.е. буквально: все 128 процессов бомбардируют кеш тем, что надо было бы записать всего один раз.

Мне кажется, что второй ситуации можно было бы избежать, если бы каждый процесс поговорил с кешем по душам вот о чём:

а) Дорогой Кеш, вот у меня есть данные для ключа «ААА», которые я собрал в (метка времени). Можно ли мне их тебе засунуть или твои данные новее?

б) Конец, если Кеш говорит: нельзя. Если Кеш ответил «можно», то спросить: а вот у меня есть данные для ключа «ААА», и md5-сумма этих данных такая-то - могу ли я их тебе, дорогой Кеш, передать или у тебя там точно такие же данные уже есть?

в) Конец, если то, что мы пытаемся передать, точно совпадает с тем, что уже есть. Если данные всё же нужно записать, говорим: «Дорогой Кеш, вот тебе данные, актуальные на момент времени X, прими эти данные, если у тебя там запись для ключа ААА древнее моей».

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

Теперь внимание вопрос: а есть ли кеш-движки, которые умеют всё-таки не только хранить гигабайты в спуле, но умеют быть достаточно «ленивыми» для того, чтобы не принимать лишнее? Я вот написал подобную обвязку с протоколом обмена для Redis на Perl'е, но хотелось бы конечно, чтобы подобные вещи были встроенными.

Объясняется это очень просто: производительность кеша, который сам по себе является критичной компонентой системы, не должна бы «проваливаться» в случае подобного рода «лавинных» записей. Каждый процесс моет внутри себя творить всё, что угодно: в конце-концов у него всё равно отберут его квант времени и передадут управление другим процессам, а вот напрягать без веских на то оснований разделяемые ресурсы типа кешей - это нездорово, потому что мы никогда не знаем, насколько сейчас тому же Redis'у и без нас хреново.

В общем, бывают ли умные кеш-движки, умеющие что-то проверять прежде, чем писать?

 , шторм

DRVTiny
()

Как англоязычные называют Ресурсно-сервисную модель?

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

Например, «IT Services» есть в Zabbix (Рига, Латвия. ex-USSR), но нет во всех остальных системах мониторинга.

Как же они это называют?

 ,

DRVTiny
()

Языки, которые по сути-то LISP, но успешно прикидываются императивными?

Знаю 2 таких - это Julia и R. А ещё есть что-то подобное? Julia, кстати, наверное вообще идеальный «переходник» от императивщины к функциональщине.

 , , , whatelse

DRVTiny
()

Хочу несуществующего: веб-приложение для проектирования графовой структуры

Есть объекты некоей сложной системы, они взаимосвязаны - вообще иерархически, но это не дерево, а именно древовидный граф.

Хотелось бы: иметь возможность рисовать граф, редактировать свойства объектов в графическом интерфейсе и через API (свойства - на базе пользовательских схем, описывающих классы), в том числе менять внешний вид этих объектов.

Возможно, это UML.

Но хотелось бы как можно менее замороченное решение. Это не какой-то сложный бизнес-процесс, в котором непременно есть сканирования бумажек и утверждения бюрократическими потрохами, этот граф представляет собой Ресурсно-Сервисную Модель IT-инфраструктуры, поэтому всякая галиматья для бизнеса, у которого слишком много денег и желания покидать пальцы - не нужна.

Нужен буквально удобно редактируемый граф объектов с внешним API-доступом.

Видел кто-нибудь нечто подобное? :)

 , , , web-app

DRVTiny
()

Как понять, какое расширение используется для языка X?

Погуглил - не нашёл.

У меня установлено несколько расширений, «поддерживающих» язык Crystal. Всего их вроде 3 живых (и это для редкого языка!), соотв.-но могу хоть все три поставить и активировать.

Но как понять, какое из них используется для редактирования «*.cr»-файлов в действительности?

 , ,

DRVTiny
()

RSS подписка на новые темы