JavaScript на Диване – мой lightning talk на JSConf

Рубрика: Development, JavaScript/Ajax | 21 February 2012, 12:02 | Vadim Voituk

Про просьбе организаторов последней JSConf выкладываю свою презентацию и черновик доклада своего lightning talk под названием “JavaScript на Диване”. [Далее...]

Remove inactive MacPorts

Рубрика: Mac OS X | 2 March 2011, 12:38 | Vadim Voituk

Небольшой quick tip для тех кто использует MacPorts у себя на Mac OS X – очистка неактивных портов:

port echo inactive | sed 's/ //g' | xargs port uninstall

Обратите внимаение что именно “port echo”, а не “port list” (почему именно так – не знаю)

Исполнение такой комманды почти вдвое (с 8.3Gb до 4.6Gb) уменьшило место занятое под MacPorts (что в эпоху дороготоящих SSD винчестеров весьма не бесполезно)

JSON Lint tool using Node.js

Рубрика: Development, JavaScript/Ajax | 8 February 2011, 22:19 | Vadim Voituk

История одной занозы в … или небольшая заметка о том, как быстро написать что-то полезное на node.js

В последнее время много и часто приходится работать с HTTP-REST-JSON  API, в результате чего назрела необходимость в нормальном client tool для этого API. И если на роль полноценного HTTP-REST-клиента претендовать не приходится (первенство тут отдаем старому доброму консольному curl), то вот с “красивым” форматированием результата вызова API – приходилось повозиться.
Порою доходило до того, что ввиду сложности структуры результата, приходилось запускать developers console WebKit-a, копировать в буфер обмена строку-результат запроса, и выполнять  что-то вроде:

console.log(/*...long...long...long...string...goes...here..*/)

Во процессе борьбы с таким неудобством, в какой-то момент в недрах сети была найдена утилита jsonlint, которая умела структурировано выводить на экран JSON-обьект (такой себе аналог xmllint), но и с ней не сложилось – какие-то ее зависимости категорично отказывались устанавливаться посредством  MacPorts.

Вконце концов было принято решение набросать аналогичный tool самостоятельно.
Среди кандидатов на язык разработки подобной мелочи были Groovy, Groovy++, php и Node.JS).
Ввиду JavaScript-nature поставленной задачи грех было не воспользоваться Node.JS – и выбор оправдал мои ожидания.
Всего 30 минут “курения” node.js Manual & Documentation”, 10 строк кода, и нужнейшая утилита “в кармане”.

Исходный код приводить тут не буду – его можно поглядеть на github, покажу лишь несколько примеров использования полученной мини-утилиты на примере Twitter API (команды вводить unix-консоли):

1. Информации о Twitter-аккаунте конкретного пользователя:
curl -s "http://api.twitter.com/1/users/show/voituk.json" | jsonlint | less

2. Поиск в Twitter:
curl -s "http://search.twitter.com/search.json?q=@voituk" | jsonlint | less

Установить или обновить такую полезную “тулзу” можно простой консольной командой:
curl https://github.com/voituk/Misc/raw/master/nodejs/jsonlint > ~/bin/jsonlint && chmod a+x !#:3
(как это сделать на Windows – не спрашивайте ибо я даже не представляю как установить на Windows сам Node.JS)

Вот так вот неожиданно все получилось легко и просто посредством Node.JS.
Критика и пожелания приветствуются в коментариях.

Задачка про 8 шаров

Рубрика: Google, Задачки | 24 January 2011, 22:31 | Vadim Voituk

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

Вот еще одна классическая задачка, которую опять же согласно слухам спрашивают в Google, и совершенно точно когда-то спрашивали в давно сгинувшей (или правильно говорить “переродившейся в Cogniance?”) Sonopia.

Итак у вас есть 8 шаров одинакового размера, при этом 7 из них весят одинаково, а один – существенно больше.

Задача: используя не более 2х взвешиваний типа “больше-меньше”, определить тяжелый шар.


MemcacheDB Quick Benchmarks

Рубрика: Development | 3 March 2010, 18:43 | Vadim Voituk

Эта заметка увидела свет в результате небольшого исследования, проведенного мною в процессе работы на оптимизацией проекта www.savevid.com и призвана поделиться моим скромным опытом миграции на key-value базы дынных (БД) . [Далее...]

Mac OS X: Usefull tips & hints 2

Рубрика: Mac OS X | 18 November 2009, 17:53 | Vadim Voituk

Следующая порция советов по обустройству вашей комфортной жизни в Mac OS X.
Первая часть доступна тут.

1. Указать место для складирования ScreenShots (по умолчанию – ~/Desktop )
(те что создаются системным shortcut-ом Command+Shift+4 & Command+Shift+3)

vadim@Voituk:~>defaults write com.apple.screencapture location ~/Pictures/Screenshots
vadim@Voituk:~>killall SystemUIServer

Аналогично меняется и формат скриншотов (злые языки говорят что поддерживается png, jpg, tiff, pdf):

vadim@Voituk:~>defaults write com.apple.screencapture type jpg
vadim@Voituk:~>killall SystemUIServer

2. Иногда при перезагрузке (часто если подключен внешний монитор) пропадает Bluetooth.
Решение сродни “давайте выйдем и зайдем – авось заведется” – выключаю Мак, отключаю все внешние устройства, вынимаю батарею.
Жду минуты 2-3 и включаю.
Время “простоя” использую для протирания ноутбука влажной салфеткой :)

3. Поначалу очень непривычно было, что в column mode Finder, в списках, директории и файлы идут вперемешку.
Частично эту проблему можно решить, нажав Command+J и выбрав “Arrange by Kind”.
В результате  директории будут в списке рядом, но не всегда в начале списка.
Окончательно можно решить проблему “грязным хаком”: сделать чтоб при сортировке по типу, директория (тип Folder) шла самой первой.

Для этого открываем файл
/System/Library/CoreServices/Finder.app/Contents/Resources/English.lproj/InfoPlist.strings

и сразу за комментарием /* General kind strings */ меняем строку
“Folder” = “Folder”;
на
“Folder” = ” Folder”;
(с пробелом перед буквой “F”)

После редактирования перезапускаем “Finder”. /me счастлив

Useful TODO-list service – GMail Hack

Рубрика: Разное | 6 November 2009, 11:44 | Vadim Voituk

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

За последние несколько лет я перепробовал порядка 2х десятков разных сервисов для формирования TODO-листов. Больше 2х дней ни одим не пользовался, и во всех случах по одной причине – о списке забывается, если он не находится постояно перед глазами.
Для примера, сегодня я нашел записи полу-годичной (!!!) давности в своем GMail Tasklist :) Тут уже и шутка из эпиграфа статьи превращается совсем не в шутку.
И это GMail, которым я пользуюсь ежедневно! А что уже говорить про всякие “оторванные” от рабочего процесса TadaList, TooDoo и им подобные?

В результате уже больше года я вынашиваю идею взять Юру, пива и за вечер налабать реализовать нормальный удобный web-ориентированный TODO-лист, который можно будет спокойно загрузить в sidebar браузера и он всегда будет на виду.

Уже даже начал писать functional overview и requirements specification, и наверное даже через недельку-две уже и приступил бы к реализации, если бы не сегодняшний утренний твит Макса Ищенко:

sreenshot

После чего необходимость реализовывать что-то свое попросту отпало – все уже украдено изобрели до нас:
Открываем Firefox, создаем новый Bookmark на видимой панели закладок, называем его TODO (ну или по желанию), как URL указываем “http://mail.google.com/tasks/ig?pli=1″, ставим галочку “Load this bookmark in the sidebar” – и вуаля!

Получится что-то вроде:

Gmail Tasks Screenshot

Т.е. на 100% то – что я искал.

Единственное, что смущает – не придумал как перенести этот sidebar  на правую сторону браузера, но думаю это решаемо.

MySQL: Slave could not parse relay log event entry

Рубрика: Development, MySQL | 17 September 2009, 10:09 | Vadim Voituk

При использованиии MySQL Master-Slave (или же Master-Master) репликации бывает ситуация что по разным причинам версия слейва ниже чем версия мастера.
Если при этом используется опция binlog_format=MIXED, в результате возможна ситуация когда мастер запишет в свой binlog запись вида:
BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'
Которую слейв не сможет выполнить, ибо он ее попросту “еще не умеет”.

Первой ласточкой того, что это произошло станет сообщение “SLAVE DOWN” от мониторинговой системы и запись в MySQL-логе слейва сродни этой:

090917 14:55:51 [ERROR] Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 71, event_type: 19
090917 14:55:51 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O error
090917 14:55:51 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' o
n the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL
code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave. Error_code: 0
090917 14:55:51 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'bin-us1.000022' position 17007149

Попытки пропустить неугодные записи старым добрым методом:
slave stop;
set global sql_slave_skip_counter=1;
slave start;

в данном случае не помогают.

Как вариант решения предлагаю:

  1. Останавливаем slave: “SLAVE STOP;”
  2. “Выуживаем” из текста ошибки имя бинлога и позицию, на которой произошла ошибка.
    В данном случае это bin-us1.000022 и позиция 17007149
  3. На мастере выполняем запрос “FLUSH LOGS;”
  4. Делаем дамп бинлога начиная с найденной позиции:
    mysqlbinlog --start-position=17007149 bin-us1.000022  >  bin-us1-from17007149.sql
  5. Загружаем полученный дамп на слейве с ключем “–force”
    mysql --force -uuser -ppassword database < bin-us1-from17007149.sql
  6. Выполняем на слейве “FLUSH LOGS;”
  7. В data-директории находим relay-log с максимальным номером и размером около 100 байт (в моем случае это mysqld-relay-bin.000037)
  8. В той же директории в файле relay-log.info
    первую строку заменяем на имя только что найденного relay-log-а, во вторую вписываем 0, в третью – следующий после “испорченного” бинлог, в четвертую – 0
    Получится что-то вроде:
    /var/lib/mysql/mysqld-relay-bin.000037
    0
    bin-us1.000023
    0
  9. Дальше на слейве выполняем:
    CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
    SLAVE START;
  10. Ну и потом чтоб удостоверится что все “завелось”
    SHOW SLAVE STATUS\G

Должно работать.
Подозреваю что пункты 4 и 5 можно обьеденить в один, более простой и элегантный.
Но как это сделать – не гуглил.

Code WTF: JavaScript HTML entities

Рубрика: JavaScript/Ajax, Юмор | 2 July 2009, 10:49 | Vadim Voituk

Извините за “неформат” для данного блога, но не смог удержаться.
Вот так вот мой “юннат” реализует замену html-entities на JavaScript:


function properHtmlFromText(text){
	while (text.search(/\</) != -1)
		text = text.replace(/\</, '&lt;');
	while (text.search(/\&/) != -1)
		text = text.replace(/\&/, '&amp;');
	while (text.search(/\r/) != -1)
		text = text.replace(/\r/, '');
	while (text.search(/\n/) != -1)
		text = text.replace(/\n/, '<br />');
	return text;
}

Как увидел – плакал…
Наверное все-таки будем возобновлять ежедневные code-review…

P.S. В комментариях предлагаю поделиться “правильным” решением :)

MySQL: Single row lock implementation

Рубрика: Development, MySQL | 24 June 2009, 16:01 | Vadim Voituk

При разработке приложений с использованием баз данных, часто возникает сценарий “insert if not exists”:

if ( <row exists in table> )
   then <insert new record into table>

Из-за того, что данный блок псевдо-кода не выполяняется атомано, может возникнуть ситуация, когда между проверкой <row exists in table> и выполнением действия <insert new record> паралельный поток (клиент)  выполнит добавление новой записи и в итоге в БД окажется 2 одинаковых записи (или произойдет ошибка “duplicate key”).

Такой, не самый приятный case, в книгах по паралельному программированию называют race condition и обходят путем создания синхронизирующих блокировок , использованием “выпрямителей” и тд.
[Далее...]

Страница 1 из 34123456789101112131415...Последняя »