Заметки Alexxz

понедельник, 7 марта 2011 г.

GitHub и ключики

Одной из особенностей github.com явлеется активное использование SSH ключей. Для общения с GIT репозиторием по SSH каждый пользователь должен в вебе указать свои public SSH ключи. Но в том SSH все авторизуются все под одним пользователем git и система уже по ключу определяет к каким репозиториям давать доступ.

Таким образом получается, что public key для github.com может принадлежать только одному пользователю. Всё бы ничего и система вполне себе удобная и рабочая, но она не предусматривает наличия клинического идиота типа меня.

Я когда-то давно зарегистрировался на github.com со своим ником Alexxz, одноразовым паролем и имейлом. Ну, надо мне там что-то было, а пользоваться я не собирался. Тогда же я похоже и указал там один из своих public keys.

Недавно я там зарегистрировался с другим ником (Alexxz ведь уже занят) и завёл репозиторий. И вот сейчас мне захотелось добавить тот самый ключик на github.com к новому аккаунту и естественно я получил милую надпись
Oops! The key has already been taken. 
В ответ на это я написал им в поддержку письмо и жду ответа. Очень надеюсь, что они смогут вернуть мне мой основной ник.

А мораль у этой истории одна. Используйте самоустойчивый почтовый ящик, чтобы не было нужды пользоваться одноразовыми email адресами.

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

Первое использование github

Решил тут опробовать github. Понять насколько он удобен и практичен. Для опыта выбрал разработку невидимой флешки, которая управляется яваскриптом и единственное назначение которой - проигрывать интернет-радио (Icecast, Shoutcast). Честно говоря, у меня не возникло никаких проблем с использованием github, а также я удивился насколько легко и просто удалось создать этот проект. Самая сложная и непонятная часть github для меня оказалась - хостинг сайта проекта. Но это - не основная задача github, потому записывать в минусы нельзя 8).

А вот собственно и сам проект Invisible radio player .

PS. Actionscript оказался тоже достаточно понятным и приятным языком. Надо будет при случае повторить знакомство с ним и написать более сложный проект.

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

C++ оглядываясь назад

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

Программируя 3 года на PHP я, конечно, сильно расслабился. Прочитать файл - один вызов. Регуляркой выкусить нужное значение - второй вызов. Проверить аргументы командной строки - третий вызов. Записать изменённое значение в файл - четвёртый вызов.

Вот то, от чего я отвык:

Я отвык объявлять переменные в таком количестве. Отвык, что для того, чтобы указать, что переменная используется надо за собой тащить ещё булев флаг, который указывает использовалась переменная или нет.

Я отвык, что преобразование строки в число и числа в строку это проблема. Мне ни разу не очевидно, почему, когда надо получить первое число из строки, мне надо хардкодить, вместо того, чтобы вызвать одну готовую функцию.

Ещё расстроило немного то, что хоть C++ и объектно ориентированый язык, аргументы командной строки в него передаются также как в С через argc и argv. Пришлось даже функцию написать, которая преобразовала это безобразие в коллекцию строк.

А, в целом, я понимаю, что это я расслабился в нетипизированном языке, когда умный интерпретатор сам за меня всё сделает. Вобщем, очень полезный опыт я получил, написав букавально 80 строк на C++. Надо будет знакомых программистов поспрошать, может я просто гвозди микроскопом забивал...

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

php unserialize

Обнаружил, что в PHP функция unserialize может серьёзно задуматься, если целевой объект - большой массив. В причинах пока не разобрался.

ini_set('memory_limit', '512M');
$file = '/tmp/1';
$data = range(1,2000000);

echo "Test serialize\n";
$time0 = microtime(1);
file_put_contents($file, serialize($data));
$time1 = microtime(1);
unserialize(file_get_contents($file));
$time2 = microtime(1);

$timeset = $time1-$time0;
$timeget = $time2-$time1;

echo "Serialize set time $timeset get time $timeget\n";


echo "Test JSON\n";
$time0 = microtime(1);
file_put_contents($file, json_encode($data));
$time1 = microtime(1);
json_decode(file_get_contents($file), true);
$time2 = microtime(1);

$timeset = $time1-$time0;
$timeget = $time2-$time1;

echo "JSON set time $timeset get time $timeget\n";

Результат работы

Test serialize
Serialize set time 1.39576292038 get time 31.2712199688
Test JSON
JSON set time 0.270380973816 get time 1.33044695854

среда, 4 августа 2010 г.

МТС: Как отключить рекламу в SMS

Компания МТС не перестаёт меня радовать. Оказывается через интернет помощник можно не только отключить все левые "бесплатные" услуги от оператора. Так можно ещё отказаться от получения рекламы. Узнал я об этом просто написав им в поддержку. Вот ответ.

Алексей, для отказа от SMS-рассылки Вы можете воспользоваться бесплатным сервисом "Интернет-Помощник". Предварительно установите, пожалуйста, пароль для доступа (от 4 до 7 цифр) к сервису, набрав с мобильного телефона комбинацию *111*25# клавиша вызова (запрос бесплатный). Для входа в "Интернет-Помощник" перейдите, пожалуйста, по ссылке https://ihelper.mts.ru/selfcare/logon.aspx, где Вам будет предложено ввести 10-значный номер телефона и пароль. Затем выберите, пожалуйста, подраздел "Тарифы, услуги и скидки", далее "Управление услугами"/"Подключить новые услуги". Добавьте услугу "Запрет приема информационных SMS и SMS/MMS с сайта МТС".



Описание услуги есть на странице http://www.mts.ru/services/communication/sms/ (вкладка Запрет приема SMS)

Вобщем я приятно удивлён. Спасибо МТС!

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

PHP socket_select - не подходит для написания сетевых приложений

UPD В первой редакции статьи я ошибочно писал про stream_select. Статья отредактирована подобающим образом.

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

Алгоритм до безобразия прост.

Шаг 1. socket_select рапортует, что данные в буфере. Вычитываешь их и обрабатываешь.

Шаг 2. Вычитываешь и обрабатываешь предпоследний пакет данных. И пока ты его обрабатываешь в буфер приходит недостающий последний пакет.

Шаг 3. Ты вызываешь socket_select и ждёшь данные. Так как данные уже пришли, socket_select тебе об этом не говорит. Получается, что в буфере уже лежат нужные тебе данные, но не предоставляется никакого механизма узнать об этом. Потому ты будешь ждать ответа пока данные снова не придут в этот сокет. А они могут вообще не придти, если протокол последовательный.

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

Выводы:
socket_select в общем случае не подходит для задачи написания сетевого приложения. В общем случае надо использовать работу с неблокирующими сокетами и перебор сокетов. Обнаружил, что недавно зарелизилась libevent для PHP надо будет попробовать инструмент в действии. В конце концов она работает не на селектах, а на epoll и kqueue.

UPD Для написания сетевого приложения можно использовать stream_select, она лишена указанного недостатка socket_select

PS. Спасибо Clanth

четверг, 24 июня 2010 г.

readme задолбал. Начинаю борьбу

Написал скрипт для greasemonkey, который убивает onclick у всех ссылок и перекидывает на целевую страницу.

function gs_init(){

els = document.getElementsByTagName('a');
for(el in els){
els[el].onclick="";
}
if(document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href)
document.location = document.getElementsByClassName('newstext')[0].childNodes[1].childNodes[0].href;
}
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", gs_init, false);
}