Upload
anatoly-sharifulin
View
1.002
Download
2
Embed Size (px)
DESCRIPTION
Доклад с #yr2012 Оригинал http://www.slideshare.net/sharifulin/developing-apps-using-perl
Citation preview
Создание приложений со знанием Perl
Анатолий ШарифулинYAPC::Russia 2012
Hello, World!
«СчастливыйPerl-программист»
Андрей Шитов про меня
Я стал меньше программировать на Perl
Но не стал его меньше любить :-)
JFDI превратилось JFTIJust F*cking Talk about It
Success-storyодного приложения
И как Perl мне/нам помог в этом
Нам — это Applifto
Наши приложения
Опрос аудитории
Подробно«Зачем?» и «Почему?»
http://www.slideshare.net/sharifulin/ss-12313103
Веский повод для меняЯ переезжал с ЖЖ в Posterous, написал скрипты переноса, но настроил кросс-постинг в Твиттер и Фейсбук, получил реплаи «Толя, хватит!»
Существующее аналоги — не очень
Медленные, неудобные, некрасивые, «криво» удаляют:TwitWipe, TwitCide, Delete My Tweets, ...
«Хватить техдирить, пора попрограммировать»
И выступить на #yr2012 с докладом :-)
Подход и решение
Основные цели
• Приложение должно быстро удалять твиты• Чёткое удаление• Кросс-платформенное приложение:
iOS, Android, Web, ...
Серверное API — привет, Perl!
Вся логика на стороне сервера (не Твиттер API),клиенты — «тупые» интерфейсы
Знакомствос Твиттер API
Опыта мало:
• Получение профилей пользователей после авторизации через Твиттер на сайте
• Автоматический постинг в Твиттерс помощью Net::Twitter(::Lite)
• AnyEvent::Twitter::Stream для риал-тайм поиска (привет, @miyagawa!)
Блокирующий вариантНа базе Net::Twitter(::Lite) можно решить задачу
LWP::UserAgent::POE Можно заменить транспорт в Net::Twitter(::Lite)
НЕТ
Идея — 2 независимые асинхронные очередиПолучение таймлайна и удаление твитов,
используя REST Twitter API и асинхронные запросы
Такой вариант должен работать быстро!
Авторизация и OAuth
Net::OAuth::AllМы давно написали свой модуль для OAuth.Поддерживает все версии OAuth (1.0, 1.0A, 2.0).
Net::OAuth::Allhttps://github.com/likhatskiy/Net-OAuth-All
my $oauth = Net::OAuth::All->new( consumer_secret => $conf->{consumer_secret}, consumer_key => $conf->{consumer_key },
token => $data->{access_token }, token_secret => $data->{access_token_secret},);
$oauth ->via('GET') ->protected_resource_url('https://api.twiiter.com/...’) ->put_extra( include_rts => 'true', user_id => $user->{id}, count => 200, ) ->request('protected_resource');$oauth->to_header;$oauth->url; # $oauth->url_with_extra;
Пропатчил модульПользователь неавторизован:
ограничение150 запрос в час по IP, а не 350 запросов в час на пользователя
Асинхронные запросы
Я использую MojoliciousНи для кого не секрет :-)
Mojo::UserAgentMojo::IOLoop
Отличный асинхронный HTTP-клиент
my $delay = Mojo::IOLoop->delay;for (@$tasks) { ... $delay->begin; $ua->get($url => {'Authorization' => $h} => sub { my ($ua, $tx) = @_; ... $delay->end( ... ); });}
say $delay->wait;
Серверное API
Серверное APIAPI поддерживает GET и POST запросы,формат передачи данных — JSON,
коды ответа: 200 и 50x.
Серверное APIStarman + Mojolicious
Mojolicious::Plugin::ApiHelpers
package App::Api;use App::Base -controller, with => [ 'App::Task', 'App::User' ];
sub error { shift->api_error(code => 1) }sub any { shift->api_error(code => 5) }
...
1;
my $api = $r->route('/api')->to('api#', api => 1);$api->route('/:action', action => qr/login|oauth/)->to;
my $apiu = $api->bridge->to('#auth', sign => 1);$apiu->bridge('/task/new')->to('#task_check') ->route->to('#task_new');
$api->bridge('/')->to('#auth', maybe => 1, sign => 0) ->route->to('#hello');
10 методов,123 теста и документация
Большинство методов требуют авторизацию пользователя и проверка sign (api_id + secret)
Test::Mojo и Test::MoreТестируется доуступ к методам API,
входные-выходные данные, проверка подписи и т.д.
Test::Mojo и Test::MoreСтавится реальная задача от тестового пользователя
Покрыты все методыНо нет никаких Mock-объектов, нет проверки, правильный ли удалён диапазон твитов
Это трудоёмкои излишне
Нет тестирования реального цикла:постинг твитов — удаление — проверка
$t->get_ok("$url/") ->status_is(200) ->header_is('Access-Control-Allow-Origin', '*') ->json_content_is({hello => 'Hello DLTTR!'});
$t->get_ok(sign get => "$url/task/new") ->status_is(200) ->json_content_is({error => {msg => 'User authorization failed', code => 2}});
Опасно тестить на своём аккаунте :-)
— Тебе всё равно на свой Твиттер?— Да!— Давай я удалю все твиты?— Нееееееееет!!!
Простой debug-запросов
Для проверки качества работы «клиентов» удобно логировать запросы с помощью before_dispatch + after_dispatch
Три очереди-демона
1. Очередь работыс таймлайном
Фильтрация и поиск нужных для удаления ID твитов,пейджинг с помощью since_id и max_id
1. Очередь работыс таймлайном
Максимум 200 твитов за один запрос,получение таймлайна один за одним,
проверка Rate Limit
«Ограничения» Твиттера
Нет доступа ко всем твитам, только к последним ~3200 или не позднее определённой даты,
счётчик не-ноль и т.д.
2. Очередь по удалению твитов
Удаление «пачками» по 200 штук, нет ограничений.«Отбойный молоток» или «Пушка» :-)
2. Очередь по удалению твитовОбработка ошибок — не всегда ошибка
от Твиттер API означает невыполнение задачи
3. Очередь по отправке Push
Для iOSNet::APNS::Persistent (ещё есть AnyEvent::APNS),
для проверки валидности токенов — Net::APNS::Feedback
3. Очередь по отправке Push
Для AndroidWWW::Google::C2DM и WWW::Google::ClientLogin
База данных
Очень просто — mysqlДля хранения и очереди задач, чтобы не парится совсем :-)
Два нюанса:
1. Правильно создать индексыДля очередей задач
2. Отключить кеширование запросов
select SQL_NO_CACHE * from task where ...
Сайт и веб-версия
Сайт и веб-версия
• Starman + Mojolicious
• Mojolicious::Plugin::I18N2— мой форк I18N-плаггина
• Mojolicious::Plugin::OAuth— логин через Net::OAuth::All
• Mojolicious::Plugin::ShareHelpers
• Mojolicious::Plugin::UtilHelpers
Админ и статистика
«Большой Брат»Есть вся информация по пользователям, количеству задач, фидбекам, а также риал-тайм статистика
Статистика по пользователям
Стена пользователей
Такой статистикинет у «обычных» приложений
Удалено 1М+ твитов,3К+ пользователей,
20% покупаютЗа 2 месяца
Промоутинг
Промоутинг в ТвиттереФолловинг, фаворитс, поиск и реплаинг —
Net::Twitter(::Lite)
Но меня уже три раза заблочили :-)
Промоутинг в Твиттере
Резюме
Плюсы• Получилось простое решение на Perl
(чистое время разработки ~30 часов)
• Быстро, очень быстро работает• Чётко удаляет твиты• Любое изменение, доработка, расширение сервисов по удалению — на стороне сервера, несложно
• Риал-тайм статистика
Единственный минусУпал/сломался сервер — не работает приложение, пользователи негодуют, ставят колы и матерят :-)
Check out DLTTR!http://dlttr.com/app http://dlttr.com/android
www.dlttr.com
«С виду простое приложение, а на самом деле
— крутое и на Perl»
P. S.
На #BarCampKrrя рассказывал
«Разработка приложения: от идеи до запуска»
(без упоминания о Perl)
И всё свелось к ... Perl :-)
«На каком языке программирования пишите?», «А почему?»,
«Трудно ли найти таких программистов?» :-)
use Perl or die;
Спасибо за внимание!Анатолий Шарифулин
YAPC::Russia 2012