суббота, 11 декабря 2010 г.

вторник, 7 декабря 2010 г.

эхо-сервер и 15000 запросов в секунду

В своём прошлом посте я жаловался на быстродействие казалось бы тривиального эхо-сервера. При разборе archimag'овского сервера с 10000 запросами в секунду обратил внимание, что он использует пул буферов чтения-записи. Собственно, идея то не нова, но скопипащенный ex8-server.lisp из IOLIB тогда почему-то не привлёк моё внимание отсутствием пула. Добавление его убыстрило эхо-сервер более, чем в 10 раз. На моём стареньком ноуте он теперь обрабатывает порядка 15000 запросов в секунду против 1200. На другой машинке (Core i5 с пониженной частотой при множителе 13, где-то около 1200 ГГц) порядка 35000-40000 запросов в секунду. Также стоит отметить, что эхо-сервер не сбрасывает сам соединение, а держит сеанс. В противном случае могло бы быть ещё быстрее.

суббота, 4 декабря 2010 г.

iolib и эхо-сервер

Недавно тут озаботился написанием tcp-сервера. Эксперименты решил начать с простого эхо-сервера. Да и в примерах iolib'ов он был. Ну, значит, запустил я его и решил испытать на стрессовые нагрузки. Для этого я использовал тулзу jmeter. Так вот, что выяснилось. При даже 100 параллельных запросах не все доходит правильно до клиента. И где-то 2% теряется (на моей машине). Вариант эхо-сервера, написанного на C, который я взял в том же iolib - на 100 обходится без ошибок. Правда на 1000 уже где-то 1% появляется. Вариант с использованием IOLIB - 10%. И вот меня тут смутило немного - а правильно ли я вообще понимаю всё? И неужели простому эхо-серверу так сильно становится плохо? Быстро накиданный вариант на java, который выделяет отдельные потоки на клиента - вообще 97% ошибок показал. С java.nio (асинхронная модель) не пробовал, потому как к этому времени уже изрядно расстроился.

среда, 1 декабря 2010 г.

Обновление REPO 20101201

Очередное пополение в lisp-репизотрии для Ubuntu и Debian.

  • iolib - версия 0.7.3.

понедельник, 29 ноября 2010 г.

Обновление REPO 20101129

Очередное пополение в lisp-репизотрии для Ubuntu и Debian. Какие-то библиотеки обновились, какие-то появились:

  • alexandria;
  • cffi;
  • trivial-features;
  • bordeaux-threads;
  • fiveam;
  • arnesi;
  • trivial-garbage.

Большинство из них собиралось для удовлетворения зависимостей к iolib. Обновление было произведено на последние релизные версии. В связи с этим вопрос - у этих библиотечек что-нибудь требуется ну очень свежее?

среда, 17 ноября 2010 г.

SBCL 1.0.44

Пока я спал, вышла новая версия SBCL. Я даже как-то умудрился пропустить одну. Но это не помешало собрать последнюю. :)

Обновление SBCL 1.0.44 в lisp-репизотрии для Ubuntu и Debian.

четверг, 28 октября 2010 г.

CLISP 2.49

Холодным осенним вечером делать было нечего, поэтому собрал свежую версию CLISP'а и выложил его в lisp-репизотрии для Ubuntu и Debian. В силу некоторых особенностей модуль clisp-module-berkley-db для 32-битной системы собран с зависимостью на libdb4.6, а для 64-битной системы - на libdb4.8. В остальном отличий нет. В отличие от оригинального пакета Debian, собран без зависимости и без использования CLC (Common Lisp Controller), согласно идеологии репозитория, поэтому для кого это критично - нужно будет задуматься. А в целом, свежачок. :)

пятница, 22 октября 2010 г.

Пингующий скрипт

Стандартная задача "маршрутизации" для бедных. Дано: два провайдера и выход в интернет. Один из каналов считается основным, второй резервным. И необходимо переключать маршрут с одного провайдера на другого, перестраивая таблицу маршрутизации. При этом не имеется ни автономной системы, ни, тем более, анонсирования маршрутов со стороны провайдера. Выходом является создание пингующего скрипта, который проверяет доступность внешнего ресурса, и на основании этих данных принимает какое-либо решение. Прямо напрашивается программирование. Ну я то знаю, что нет ничего удобнее для программирования, чем lisp. Итог - дебиан-пакет reserve-channel, который находится в lisp-репизотрии для Ubuntu и Debian. Сами исходные тексты можно посмотреть тут. Задача обобщена для n каналов, где n больше 1, поэтому есть возможность развёртывания системы для каналов больше двух. Ну и, напоследок, пример конфигурационного файла:

(:config
(:channel
(:interface "eth2")
(:gateway "192.168.2.1")
(:routed t)
(:purpose :main))
(:channel
(:interface "eth1")
(:gateway "192.168.0.200")
(:routed t)
(:purpose :reserve))
(:test-host (:hostname "google.ru"))
(:test-host (:hostname "ya.ru")))

среда, 15 сентября 2010 г.

lisp-getent - получение пользователей и групп в системе

Может, кому ещё понадобится. Данная библиотечка позволяет получить список пользователей и групп в системе, список пользователей группы, а также вести поиск по имени или идентификатору в каталогах пользователя или группы. Работает через external-program, что не все, наверное, поймут, но работает. Имеет ограничение на работу в unix-системах, в которых существует команда getent. Традиционно лежит в lisp-репизотрии для Ubuntu и Debian.

вторник, 7 сентября 2010 г.

Обновление REPO 20100907

Обновления в lisp-репизотрии для Ubuntu и Debian. Оказалось, что у пакета ironclad прописана зависимость на CommonLispController, а у пакета slime используются сценарии post-inst и pre-rm с его участием. Непорядок. Что и было, собственно, исправлено. Заодно обновлён slime на снапшот от 20100907.

воскресенье, 5 сентября 2010 г.

четверг, 29 июля 2010 г.

do-backup, программа создания резервных копий

С недавнего времени озаботился созданием резервных копий того, что есть на диске. Точнее, на диске сервера. Конфигурации, некоторое состояние и тому подобное. Не помню почему, но то, что было - не устроило. Ну и решил написать своё решение, но уже на лиспе. Для запуска внешних программ используется библиотека external-program. Программа do-backup обрабатывает конфигурацию вида:

((:contact

(:to "root")

(:subject "DO-BACKUP robot"))

(:action :7z

(:suffix ".7z")

(:program "7z")

(:argument "a")

(:argument :file)

(:argument :files))

(:action :slapcat

(:program "slapcat"))

(:action :pg_dumpall

(:program "su")

(:argument "-")

(:argument "postgres")

(:argument "-c")

(:argument "pg_dumpall"))

(:backup

(:action :7z)

(:file "/etc/")

(:file "/var/lib/bind/")

(:file "/var/lib/egroupware/")

(:file "/var/lib/ejabberd/")

(:file "/var/lib/ldap/")

(:dynamic-file "/var/backups/ldap-data.ldif" :action :slapcat :saveoutput t)

(:dynamic-file "/var/backups/postgresql/postgre.sql" :action :pg_dumpall :saveoutput t)

(:output-directory "/backups/configuration/" "configuration-~a.7z" 60))

(:backup

(:action :7z)

(:file "/var/lib/projects/")

(:output-directory "/backups/projects/" "projects-~a.7z" 30)))

Секция :backup описывает то, что необходимо будет резервнокопировать (в секциях :file и :dynamic-file), а :action - какие дейтвия необходимо выполнять. В целом, как мне кажется, по конфигурации понятно что должно происходить.

Далее, необходимо запускать задания по расписанию. В целом, мог бы подойти и обычный cron, но в данном случае для обобщения решений на лиспе был использован clon как аналог cron'а. Ну и, конечно же, необходимо демонизировать. Это достигается путём использования пакета sbcl-daemon, являющегося производным от restas-daemon.lisp. Важное отличие - это неиспользование (sb-posix:umask 0), поскольку это порождает файлы с записью для всего мира, что несколько небезопасно по умолчанию. Ну и ещё динамический запуск процедур в зависимости от конфигурации. Конфигурация демона do-backup производится в /etc/do-backup.daemon, где и задаётся периодичность запуска.

В заключении - исходный код проекта. Собранные пакеты, готовые для установки - в lisp-репизотрии для Ubuntu и Debian.

вторник, 20 июля 2010 г.

Обновление REPO 20100720

Очередное пополение в lisp-репизотрии для Ubuntu и Debian.
  • sbcl-daemon - инфраструктура для запуска лисп-приложений под sbcl в качестве демона (начальный коммит, производный от restas-daemon.lisp);
  • trivial-timers - библиотечка таймеров, используемая в clon;
  • clon - некий аналог cron'а.

пятница, 16 июля 2010 г.

Более удобный запуск внешних програм external-program-extender

Для лиспа существует возможность наиболее кроссплатформенно запускать внешние программы - external-program. В целом с задачей своей она справляется, и даже позволяет перенаправлять вывод в поток. Но вот сразу получить вывод в виде строки или же в виде списка строк, как это делает scsh - нет этого встроенного. Собственно, с целью получить подобную функциональность и написал небольшой extender. Теперь можно использовать следующую конструкцию:

* (run/string "ls" '("-a"))

".

..

bin

boot

cdrom

.config

dev

etc

home

initrd.img

initrd.img.old

.kde

lib

lib32

lib64

lost+found

media

mnt

proc

root

sbin

selinux

srv

sys

tmp

usr

var

vmlinuz

vmlinuz.old

"

Или, если хочется получить результат в виде списка строк, то:

* (run/strings "ls" '("-a"))

("." ".." "bin" "boot" "cdrom" ".config" "dev" "etc" "home" "initrd.img"

"initrd.img.old" ".kde" "lib" "lib32" "lib64" "lost+found" "media" "mnt"

"proc" "root" "sbin" "selinux" "srv" "sys" "tmp" "usr" "var" "vmlinuz"

"vmlinuz.old" "")

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

воскресенье, 4 июля 2010 г.

Обновление REPO 20100604

external-program 0.0.6 в lisp-репизотрии для Ubuntu и Debian. Данная библиотека позволяет кроссплатформенно запускать внешние программы.

[SOLVED] egroupware в lucid и проблемы со входом

Недавно столкнулся с проблемой, что в Ubuntu Lucid Lynx 10.04 egroupware не позволяет произвести вход, объясняя это тем, что "Ваш сеанс не может быть удостоверен." ("your session couldn't be verified"). Изрыл интернет направо и налево и где-то в закоулке нашёл решение. Собственно, необходимо в файле /etc/php5/apache2/php.ini строчку:

request_order = "GP"

Заменить на:

request_order = "GPCS"

И тогда будет производиться вход.

SBCL 1.0.40

Обновление SBCL 1.0.40 в lisp-репизотрии для Ubuntu и Debian. Из приятного - тесты у него проходят теперь и на 32-битной платформе. Внутри у него ASDF2 и теперь нет необходимости в пакете asdf-binary-locations.

пятница, 25 июня 2010 г.

Обновление REPO

Обновление REPO

Обновился пакеты в lisp-репизотрии для Ubuntu и Debian.


  • SLIME (Superior Lisp Interaction Mode for Emacs) - 20100624;
  • bordeaux-threads - 0.7.0

среда, 23 июня 2010 г.

ICFPC-2010

В этом году я второй раз участвовал в ICFP Contest (отчёт об участии в ICFPC-2009 ). Ожидалось заранее, что будет какое-нибудь устройство, которым можно будет управлять. Но ожидания слегка не оправдались. :) В этот раз задача походила на сказку - пойди туда не знаю куда, сделай то не знаю что. Участвовал в команде Skobochka и набрали где-то 3 с чем-то балла. Но обо всём по порядку:

День1
Прямо к четырём оказаться для контеста у меня не получилось, поэтому я опоздал где-то на полчаса. Начал читать задание. Кто-то в это время уже набросал в CLOS модель машин и разгадывал фабрику. Фабрика представляла собой гейты с двумя входами (левый и правый) и двумя выходами (также левый и правый) и соединениями между ними. При этом соединение к одной точке (вход или выход) могло производиться только одной линией. Также фабрика содержит специальный гейт, называемый внешним, от которого поступает информация и на который эта информация уходит. В чате все предположили, что слева - входы гейта, справа - выходы. Ну и описание соответственно. Приведу прмер фабрики, которая была в задании:

19L:
12R13R0#1R12R,
14R0L0#4R9L,
9R10R0#3L8L,
2L17R0#5L9R,
15R1L0#10R13R,
3L18R0#6L15L,
5L11R0#13L12L,
19R16R0#11R8R,
2R7R0#11L10L,
1R3R0#18L2L,
8R4L0#16L2R,
8L7L0#15R6R,
6R0R0#14L0L,
6L4R0#14R0R,
12L13L0#17L1L,
5R11L0#16R4L,
10L15L0#17R7R,
14L16L0#18R3R,
9L17L0#19R5R,
X18L0#X7L:
19L
К этой фабрике необходимо было подать на вход последовательность [0,2,2,2,2,2,2,0,2,1,0,1,1,0,0,1,1] и на выходе бы получился ключ, который должна выдавать каждая из фабрик.
Посмотрев, как входы и выходы специфицируются на каждом гейте и как вход на цепь специфицируется входами гейтов я сразу же подумал подать пустую фабрику "X: :X" и получил последовательность. И тут, как говорится, "Остапа понесло". Я предположил, что незвестна не только функция гейта, но ещё и функция внешнего гейта, на котором также происходит преобразование. Весь оставшийся день прошёл в попытках решить аналитически две неизвестные функции гейтов.

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

День3
Состязание завершилось. 3 балла.

Итог
В следующем году обязательно буду участвовать. Всей команде Skobochka (allchemist, vseloved, rigidus, treep, dmitry_vk, ...) спасибо.