Елена Шишкина, ведущий программист Деньги Mail.Ru. Она покажет практический пример лени как двигателя прогресса в отдельно взятом веб-проекте:
- Надоело писать код? Будем думать, как его не писать!
- Боремся с однотипным кодом. Боремся с неоднотипным кодом.
- Код, которого не существует, и код, который существует.
- Следите за руками: программируем на конфигах!
- Как жить дальше?
Ruby - или зачем мне еще один язык программирования?Pavel TsukanovРасскажу зачем он нужен мне, а вы решите зачем он нужен вам. Также рассмотрю его реализацию на платформе .Net - IronRuby
"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...YandexВыбор языка для разработки под iOS не ограничен Objective-C — всё зависит от конкретных задач. Но даже если код пишется на Objective-C, у разработчика есть и другие инструменты, кроме Xcode, способные облегчить жизнь. Есть сторонние тестовые фреймворки, менеджеры зависимостей, браузеры документации и, конечно, альтернативные IDE — например, AppCode.
В докладе я расскажу, почему в JetBrains создали собственную IDE для Objective-C, а не просто плагин к Xcode. Обсудим, чем AppCode отличается от Xcode, и как мы реализовали интеграцию с этой средой. А также поговорим о возникавших сложностях и планах по развитию интеграции и всего продукта.
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...Moscow.pmВидео: http://video.mail.ru/corp/p.scherbinin/6/7.html
Tаблица символов — это только небольшой шаг в мир внутреннего устройства Perl, но и он открывает программисту огромные возможности:
— Runtime-кодогенерация.
— Генерация по запросу.
— Изменение кода сторонних модулей на лету и многое другое.
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Moscow.pmВидео: http://video.mail.ru/corp/p.scherbinin/6/11.html
— Знай свою среду. Почему нужно изучать язык, на котором пишешь.
— Магии нет. Есть непонимание процессов.
— Не верь предрассудкам. Они сложились при других обстоятельствах.
— Доверяй, но проверяй. Прежде, чем использовать решение, проверь.
— Не используй не изучив. Не используй не понимая.
— Код можно менять. Как делать это с умом.
— Можно ли доверять синтетике? Синтетические тесты и реальная нагрузка.
— Немного примеров. Плохих и хороших.
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)OnticoTypeScript – светлое будущее ES6 уже вчера.
Почему не "Кофе"? Чай полезней.
Что не так с Flow от Facebook?
Реальная практика использования: плюсы и минусы.
Не VisualStudio единым. Особенности работы в других IDE.
Интеграция с уже существующим JS кодом.
Использование совместно с RequireJS. Подводные камни.
Использование TypeScript совместно с React.
TypeScript и Angular.
Плюшки, которых нет в ES6/7 (пока нет): [static] enum, интерфейсы, private, protected, декораторы... Что дают и зачем?
Суперсилы Chrome developer tools2ГИС ТехнологииВ своей работе мы постоянно используем инструменты, призванные облегчить нам жизнь. Но как хорошо мы ими на самом деле владеем? И почему мы пренебрегаем их суперсилами? Например, Chrome DevTools — это не только отладчик и инспектор HTML. Но когда у нас в руках молоток, кругом мерещатся гвозди. Десятки мегабайт и процентов загрузки процессора на вкладку браузера — верный признак того, что пора учиться пользоваться микроскопом.
Роман предложит освоить что-то посложнее молотка и расскажет о том, какую реальную пользу можно получить от профилирования, как найти в огромном отчёте проблему с кодом и что лучше — написать в коде десяток console.log или async debug.
Component InspectorRoman DvornovЗанимаясь разработкой интерфейсов, мы постоянно разбираемся как и что устроено. Вы задумывались, сколько времени у вас уходит на то, чтобы найти нужный фрагмент кода, который отвечает за компонент на странице? В своем докладе я покажу как это можно сделать за один клик, а так же раскрою технические детали.
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...OnticoАсинхронность в Javascript больше не страшна. Классические триллеры вроде "Callback Hell" и "Pyramid of Doom" потеряли свою актуальность настолько, что даже Java-программисты перестали пугать ими невинных джуниоров.
Всё благодаря паттернам и библиотекам. Streams, Promises, Async-Await и другие изменили наш код. Теперь он прекрасен.
Пока ещё вымысел? Поговорим о том, как сделать эту картину реальностью. Об основных практиках асинхронного программирования, принципах их работы, отличиях и сценариях использования.
Что нового в Perl? 5.10 — 5.16Anatoly SharifulinПеревод презентации @rjbs "What's new in Perl? v5.10 — v5.16" http://www.slideshare.net/rjbs/whats-new-in-perl-v510-v516
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)OnticoTypeScript – светлое будущее ES6 уже вчера.
Почему не "Кофе"? Чай полезней.
Что не так с Flow от Facebook?
Реальная практика использования: плюсы и минусы.
Не VisualStudio единым. Особенности работы в других IDE.
Интеграция с уже существующим JS кодом.
Использование совместно с RequireJS. Подводные камни.
Использование TypeScript совместно с React.
TypeScript и Angular.
Плюшки, которых нет в ES6/7 (пока нет): [static] enum, интерфейсы, private, protected, декораторы... Что дают и зачем?
Суперсилы Chrome developer tools2ГИС ТехнологииВ своей работе мы постоянно используем инструменты, призванные облегчить нам жизнь. Но как хорошо мы ими на самом деле владеем? И почему мы пренебрегаем их суперсилами? Например, Chrome DevTools — это не только отладчик и инспектор HTML. Но когда у нас в руках молоток, кругом мерещатся гвозди. Десятки мегабайт и процентов загрузки процессора на вкладку браузера — верный признак того, что пора учиться пользоваться микроскопом.
Роман предложит освоить что-то посложнее молотка и расскажет о том, какую реальную пользу можно получить от профилирования, как найти в огромном отчёте проблему с кодом и что лучше — написать в коде десяток console.log или async debug.
Component InspectorRoman DvornovЗанимаясь разработкой интерфейсов, мы постоянно разбираемся как и что устроено. Вы задумывались, сколько времени у вас уходит на то, чтобы найти нужный фрагмент кода, который отвечает за компонент на странице? В своем докладе я покажу как это можно сделать за один клик, а так же раскрою технические детали.
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...OnticoАсинхронность в Javascript больше не страшна. Классические триллеры вроде "Callback Hell" и "Pyramid of Doom" потеряли свою актуальность настолько, что даже Java-программисты перестали пугать ими невинных джуниоров.
Всё благодаря паттернам и библиотекам. Streams, Promises, Async-Await и другие изменили наш код. Теперь он прекрасен.
Пока ещё вымысел? Поговорим о том, как сделать эту картину реальностью. Об основных практиках асинхронного программирования, принципах их работы, отличиях и сценариях использования.
Что нового в Perl? 5.10 — 5.16Anatoly SharifulinПеревод презентации @rjbs "What's new in Perl? v5.10 — v5.16" http://www.slideshare.net/rjbs/whats-new-in-perl-v510-v516
Архитектура кода нового 2ГИС Web API или куда мы дели MVCDevDayСергей Коржнев
Архитектор версии 1.4 2ГИС Web API
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Тезисы:
● Как организован код в старой версии.
● Вдумчиво смотрим, как мы используем Yii, хватаемся за голову и клавиатуру. Там отрезаем, тут пришиваем, и вуаля!
● Ну и делаем выводы, как мы забороли две классические проблемы программирования: борьба с дублированием кода и сложностью системы.
Опыт разработки и тестирования RESTful JSON сервисаIlya ChesnokovКое-что о процессах и технологиях, которые используются при разработке системы, основой которой является RESTful JSON API.
HSE{Consult}: DevOps – новая методология разработкиBusiness incubator HSEМетодология DevOps - новое течение в управлении разработкой и эксплуатацией. DevOps дает возможность бизнесу быстрее добиваться своих целей, активнее меняться и постоянно пробовать новое.
Основные направления DevOps:
- новая инженерная культура, построенная на взаимной - ответственности коллектива;
- автоматизация и инструменты;
- управление изменениями и мониторинг;
- распространение знаний между всеми участниками технической команды.
DevOps или исскуство ухода за Интернет-проектомAlexander TitovПоловина дела - создать интернет-проект, другая половина - позволить
ему работать и зарабатывать для вас деньги при любом количестве
пользователей и переменчивых погодных условиях вплоть до атаки инопланетян.
Жизнь есть жизнь, и она наполнена рисками - пренебрежение
эксплуатацией может оставить вас без бизнеса. Совсем.
http://devconf.ru/offers/81
Доклад будет о правильном и бережном уходе за интернет-проектами. О применении культуры DevOps на практике, о путях внедрениях и сложностях на пути технического директора, который осознанно встал на путь DevOps.
О работе с документами .xls, .xlsx, .rtfMoscow.pmНаталья Савенкова, ex-СТО SHOP2YOU.RU. В e-commerce файлы формата Excel – основной инструмент обмена данными. Они используются везде: для документов покупателям и транспортным компаниям, для отчетов менеджерам, для импорта и экспорта товаров в магазин, для обмена остатками между поставщиками. Их нужно уметь читать и писать. Наталья объяснит, как это делать с документами разной структуры, а также поговорит о сложностях и их решениях. Доклад посвящен классическому формату Excel 1997-2003 (XLS) и модулям: Spreadsheet::ParseExcel, Spreadsheet::WriteExcel и Excel::Template.
Fast queue – как мы сделали свою очередь на perl и redisMoscow.pmИван Соколов, teamlead REG.RU. Очередь – один из наиболее используемых механизмов в программировании. Например, для интеграции с платежными системами или для обработки медиа-контента, загруженного пользователем, необходимо наличие очередей.
В REG.RU тоже не обходятся без очередей. Поэтому потребность найти решение появилась достаточно давно. Учитывая специфику компании как доменного регистратора большинство существующих решений не подходило, и программисты решили «написать свой велосипед». Иван расскажет об архитектуре их очереди, ее возможностях, и в каких задачах она используется.
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013Moscow.pm- Как создать презентацию не вылезая из любимого текстового редактора (notepad++, padre, vim).
- Как perl помогает автоматизировать работу без написания кода.
- Пара скриптов, которые облегчают работу на разных платформах.
- Те же скрипты на perl6.
- Автоматизация и тестирование Firefox.
Разработка документации для RESTful API: как убить трёх зайцев одним. Moscow....Moscow.pm- Расскажу и покажу инструменты, которые мы используем для документирования собственного RESTful API.
Особенности создания XS-модулей на языке C++. Владимир Тимофеев. Moscow.pm 4 ...Moscow.pm- Почему C++? Плюсы, минусы.
- Как найти компилятор (поддержка в EUMM, MB, стандартные и не очень решения).
- Конфликты имён.
- Трансляция C++ исключений в Perl-исключения.
Ленивые итераторы для разбора разнородных данных. Михаил Озеров. Moscow.pm 6 ...Moscow.pm— От циклов к коллбэкам
— От коллбэков к итераторам
— Борьба со сложностью, изоляция аспектов
— Гибкость и модифицируемость кода
— Преимущества и недостатки
Преобразование Perl-структур в XML. Трефилова Екатерина. Moscow.pm 6 июля 2013Moscow.pm— Парсинг XML-документов.
— Формирование простых и сложных XML
— Немного о DOM и парсерах, основанных на событиях SAX
— Какими модулями удобно пользоваться и почему
Play Perl — распределенная социальная игра для Perl-разработчиков. Вячеслав М...Moscow.pmВидео: http://video.mail.ru/corp/p.scherbinin/6/10.html
Расскал о том:
— Как настоящие соцсети будущего будут поощрять действие, а не потребление.
— Как геймификация изменит мир.
— Как Play Perl спасет сообщество perl-разработчиков от застоя и сделает нас всех более продуктивными.
3. С чего все начиналось
• Веб-сервис (JSON API)
– nginx
– Mojolicious
– PostgreSQL
– Вся логика в процедурах СУБД
• Архитектура веб-приложения
– Вертикальная нарезка на сервисы: auth, profile, contactlist, chat, …
– Горизонтальная нарезка
• www-layer
• Service layer
• Data layer
– Сервисы могут обращаться к друг другу через service layer
3
4. Типичная функция веб-слоя
• Проверка CSRF-токена
• Аутентификация
• Авторизация
• Чтение и валидация входных данных
• Обращение к сервисному слою
• Перехват и маппинг ошибок
• Генерация вывода
4
5. Функция веб-слоя
sub message {
my $self = shift;
my $result = eval {
my $form = $self->helper->read_form('chat/message');
die $form->export_errors if $form->has_errors;
die 'ERROR_CSRF_TOKEN'
unless $self->helper->token_ok($form);
die 'ERROR_NOT_AUTHORIZED'
unless $self->helper->check_auth($form);
$self->service->message($form->export);
};
unless ($result) {
my $err = $@;
$self->helper->logerr($err);
$result = $self->helper->map_error($err);
}
$self->render(json => $result);
}
5
6. Типичная функция сервисного слоя
• Обработка входящих данных
• Обращение к слою данных
• Сохранение в ленту активности пользователя
• Рассылка уведомлений
• Подготовка возвращаемых данных
–result: OK или код ошибки
–собственно данные:
• нет данных
• одно значение
• хэш
• массив хэшей
6
7. Функция сервисного слоя
sub message {
my ($self, $opts) = @_;
my $result = $self->data->message($opts);
$self->send_notify(chat_message => {
sender => $opts->{profile_id},
addressee => $result,
message => $opts->{message},
});
return $self->ok;
}
7
8. Типичная функция слоя данных
• Запрос данных из кэша (для статических запросов)
• Вызов процедуры СУБД
• Сохранение в кэш
• Инвалидация кэша
• Нормализация выходных данных
8
9. Функция слоя данных
sub contactlist {
my ($self, $opts) = @_;
my $cache_key = $self->to_cache_key(
'proifle.contactlist',
$opts
);
my $result = $self->cache->get($cache_key);
unless ($result) {
$result = $self->db->table(
'profiles.contactlist',
[ $opts->{profile_id} ]
);
$self->cache->set($cache_key, $result);
}
return $result;
}
9
10. Новая фича
• 1 процедура СУБД
• 3 копипасты с небольшими изменениями
В половине случаев меняются только названия,
ключи конфигов и имена процедур!
10
11. Можно как-нибудь так:
sub god_method {
my $self = shift;
my $cfg = $self->resolve;
my $result = eval {
my $form = $self->helper->read_form($cfg->{form});
die $form->export_errors if $form->has_errors;
if ($cfg->{check_token}) {
die 'ERROR_CSRF_TOKEN'
unless $self->helper->token_ok($form);
}
if ($cfg->{check_auth}) {
die 'ERROR_NOT_AUTHORIZED'
unless $self->helper->check_auth($form);
}
$self->service->god_method($cfg, $form->export);
};
unless ($result) {
my $err = $@;
$self->helper->logerr($err);
$result = $self->helper->map_error($err);
}
$self->render(json => $result);
}
Но это скучно!11
12. Будем генерировать методы на лету
• Не делаем лишних телодвижений: генерируем из
AUTOLOAD
• Чтобы не попросили странного, нам нужен список
разрешенных методов
• Генератор в базовом классе, списки методов – в
наследниках
• В наследниках можно описать вариации поведения
12
13. Проверка по списку разрешенных методов
sub _has_method {
my ($module, $method) = @_;
my $methods = ${ "$module::valid_methods" };
if (ref $methods && ref $methods eq 'HASH') {
return $methods->{$method};
} else {
return;
}
}
13
14. Метод-генератор
use Sub::Name;
sub _generate_sub {
my ($module, $method) = @_;
my $sub = subname "$module::$method", sub {
...
};
no strict 'refs';
*{"$module::$method"} = $sub;
return $sub;
}
14
15. AUTOLOAD
our $AUTOLOAD;
sub AUTOLOAD {
my $self = $_[0];
my ($method) = $AUTOLOAD =~ /^.+::(.*)$/;
my $package = blessed $self ? ref $self : $self;
return if !$method || $method eq 'DESTROY' || !
_has_method($package, $method);
my $sub = _generate_sub($package, $method);
goto ⊂
}
15
16. Oops! Mojolicious зовет can…
sub can {
my ($self, $method) = @_;
my $module = blessed $self ? ref $self : $self;
if (_has_method($module, $method)) {
return _generate_sub($module, $method);
} else {
return __PACKAGE__->SUPER::can($method);
}
}
16
17. Модули с фичами
use strict;
use warnings;
package MyProject::Controller::Chat;
#package MyProject::ServiceLayer::Chat;
#package MyProject::DataLayer::Chat;
use Mojo::Base 'MyProject::Controller::Base';
#use parent 'MyProject::ServiceLayer::Base';
#use parent 'MyProject::DataLayer::Base';
our $valid_methods = {
message => 1
};
1;
17
20. Функция веб-слоя
Всегда:
• читает и валидирует входные
параметры
• зовет сервисный слой
• перехватывает и маппит ошибки
• генерирует вывод
Может:
• читать определение веб-формы
из разных конфигов
• проверять CSRF-токен
• проверять аутентификацию
• проверять авторизацию
20
21. Определение метода для веб-слоя
use strict;
use warnings;
package
MyProject::Controller::Chat;
use Mojo::Base
'MyProject::Controller::Base';
our $valid_methods = {
message => {
check_token => 1,
check_auth => 1,
form => 'chat/message'
}
};
1;
Немного упростим
• Токен будем проверять по
умолчанию
• Аутентификацию тоже будем
проверять по умолчанию
• Имя формы = имя модуля + имя
метода
21
22. Определение метода для веб-слоя
use strict;
use warnings;
package MyProject::Controller::Chat;
use Mojo::Base 'MyProject::Controller::Base';
our $valid_methods = {
message => { }
};
1;
22
24. sub _generate_sub {
my ($module, $method) = @_;
my $def = dclone(_get_definition($module, $method) || {});
my $form_name = _form_name($module, $method, $def);
$def->{check_token} = 1 unless exists $def->{check_token};
$def->{check_auth} = 1 unless exists $def->{check_auth};
my $service_method = $def->{service_method} || $method;
my $sub = subname "$module::$method", sub {
my $self = shift;
my $result = eval {
my $form = $self->helper->read_form($form_name);
die $form->export_errors if $form->has_errors;
if ($def->{check_token} && !$self->helper->token_ok($form)) {
die 'ERROR_CSRF_TOKEN';
}
if ($def->{check_auth} && !$self->helper->check_auth($form)) {
die 'ERROR_NOT_AUTHORIZED';
}
$self->service->$service_method($form->export);
};
unless ($result) {
my $err = $@;
$self->helper->logerr($err); $result = $self->helper->map_error($err);
}
$self->render(json => $result);
};
no strict 'refs'; *{"$module::$method"} = $sub;
return $sub;
} 24
25. Функция сервисного слоя
Всегда:
• обращается к слою данных
• подготавливает возвращаемые
данные
Может:
• обрабатывать входящие данные
• сохранять данные в ленту
активности пользователя
• рассылать уведомления
• возвращать данные в разных
структурах:
– нет данных (только код
результата)
– одно значение
– хэш
– массив хэшей
25
26. Определение метода для сервисного слоя
use strict;
use warnings;
package MyProject::ServiceLayer::Chat;
use parent 'MyProject::ServiceLayer::Base';
our $valid_methods = {
message => {
returns => 'none',
notify => 1,
save_history => 0
}
};
1;
26
28. use Sub::Name;
use Storable qw(dclone);
sub _generate_sub {
my ($module, $method) = @_;
my $def = dclone(_get_definition($module, $method) || {});
my ($service) = $module =~ /^.+::(.*)$/;
my $data_method = $def->{data_method} || $method;
my $sub = subname "$module::$method", sub {
my ($self, $opts) = @_;
my $result = $self->service->$method($opts);
if ($def->{notify}) {
$self->send_notify((lc $service) . "_$method", $opts,
$result);
}
if ($def->{save_history}) {
$self->save_history((lc $service) . "_$method", $opts,
$result);
}
return $self->parse_answer($result, $def->{returns} || 'none');
};
no strict 'refs';
*{"$module::$method"} = $sub;
return $sub;
}
28
29. Функция слоя данных
Всегда:
• вызывает процедуру СУБД
Может:
• запрашивать данные из кэша
• передавать в процедуру разные
наборы параметров
• читать результат работы процедуры
в разном формате:
– нет возвращаемого значения
– одно значение
– строка
– таблица
• сохранять данные в кэш
• инвалидировать кэш
• нормализовывать выходные
данные
29
30. Определение метода для слоя данных
use strict;
use warnings;
package
MyProject::DataLayer::Chat;
use parent
'MyProject::DataLayer::Base';
our $valid_methods = {
message => {
args => [qw(profile_id
room_id reftime message)],
returns => 'table',
func => 'chat.message',
}
};
1;
Немного сократим
• Кэш по умолчанию не зовем и
не валидируем
• Имя процедуры базы строим по
шаблону:
– tablespace = имя модуля
– имя процедуры = имя метода
• Возвращаем по умолчанию
таблицу
30
32. use Sub::Name;
use Storable qw(dclone);
sub _generate_sub {
my ($module, $method) = @_;
my $def = dclone(_get_definition($module, $method) || {});
my ($service) = $module =~ /^.+::(.*)$/;
$service = lc $service;
my $db_func = $def->{func} || $service . '.' . $method;
my $layer_func = $def->{returns} || 'table';
$layer_func = 'exec' if $layer_func eq 'none';
my $sub = subname "$module::$method", sub {
my ($self, $opts) = @_;
my $cache_key = ($def->{use_cache} || $def->{invalidate_cache})
? $self->to_cache_key($service . '.' . $method, $opts)
: undef;
my $result = $def->{use_cache}
? $self->cache->get($cache_key)
: undef;
unless ($result) {
$result = $self->db->$layer_func($db_func, @$opts{@{ $def->{args} }});
$self->cache->set($cache_key, $result) if $def->{use_cache};
}
$self->cache->invalidate($cache_key, $opts) if $def->{invalidate_cache};
return $result;
};
no strict 'refs';
*{"$module::$method"} = $sub;
return $sub;
}
32
33. Чего мы добились
• Поигрались с кодогенерацией
• Убрали дублирование кода
• Формализовали декларацию данных для генерации
методов
Получилась отличная модель, но…
33
35. Гладко было на бумаге…
• После логина надо поставить куки
• После регистрации надо отправить email
• При добавлении фотографии нужно сохранить файл и
собрать метаинформацию
• При добавлении поста в ленту нужно распарсить и
обработать ссылки
• …
Нужен механизм для вызова произвольного кода!
35
36. Добавляем в определение метода коллбэки
prepare
• Вызывается до обращения к
нижележащему слою
• В качестве аргумента получает
входящие параметры метода
(для веб-слоя – объект формы)
• Может модифицировать
параметры (форму)
finish
• Вызывается после обращения к
нижележащему слою
• В качестве аргумента получает
данные, которые вернул
нижележащий слой
• Может модифицировать эти
данные
36
37. Для веб-слоя
our $valid_methods = {
method_name => {
prepare => sub {
my ($self, $form) = @_;
...
return $form;
},
finish => sub {
my ($self, $data) = @_;
...
return $data;
}
}
};
37
38. Чего мы добились
• Поигрались с кодогенерацией
• Убрали дублирование кода
• Формализовали декларацию данных для генерации
методов
• Научились добавлять вариативное поведение
Но нам все еще нужно добавлять по три файла,
в которых почти нет кода!
38
40. Избавляемся от файлов-модулей
• Собираем воедино разрозненные определения методов
• Выделяем инструмент – генератор модулей
• Выносим отдельно заполнение определения методов
значениями по умолчанию
• Добавляем в определение HTTP-метод запроса (GET, POST,
PUT, DELETE)
• Строим роутинг веб-фреймворка
40
41. Новое определение метода в сервисе
• URL запроса (по умолчанию – имя_сервиса/имя_метода
• Метод запроса (по умолчанию – GET)
• Параметры веб-слоя
• Параметры сервисного слоя
• Параметры слоя данных
41
42. Параметры веб-слоя
• Проверка токена (по умолчанию включена)
• Проверка аутентификации (по умолчанию включена)
• Имя формы (по умолчанию имя_сервиса/имя_метода)
• Коллбэки prepare и finish (по умолчанию отсутствуют)
• Имя метода сервисного слоя (по умолчанию то же самое)
42
43. Параметры сервисного слоя
• Имя метода слоя данных (по умолчанию то же самое)
• Отправка уведомлений (по умолчанию выключена)
• Сохранение в историю (по умолчанию выключена)
• Формат возвращаемых данных (по умолчанию
определяется слоем данных)
• Коллбэки prepare и finish (по умолчанию отсутствуют)
43
44. Параметры слоя данных
• Взятие данных из кэша (по умолчанию выключено)
• Инвалидация кэша (по умолчанию выключена)
• Имя процедуры СУБД (по умолчанию
имя_сервиса.имя_метода)
• Набор входящих аргументов процедуры СУБД
• Формат возвращаемых данных (по умолчанию – таблица)
44
45. Простейшее определение метода
my $services => {
chat => {
message => {
data_layer => {
args => [qw(profile_id room_id reftime
message)],
},
},
},
};
45
46. Генератор сервиса
• package MyProject::Core::ServiceGenerator;
sub init_service {
my ($self, $service_name, $definition) = @_;
$service_name = ucfirst $service_name;
no strict 'refs';
$definition = $self->normalize_definition($definition);
for my $layer (qw(Controller ServiceLayer DataLayer)) {
unshift @{*{ "MyProject::$layer::$service_name::ISA" }},
'MyProject::$layer::Base';
*{ "MyProject::$layer::$service_name::_get_definition" } =
sub {
return $definition;
};
}
my $method = lc($definition->{method});
$self->routes->$method($definition->{url})->to(
controller => $service_name,
action => $name
);
}
46
49. Добавляем в генератор сервиса проверку ISA
my $module = "MyProject::$layer::$service_name";
unless ($module->isa('MyProject::$layer::Base')) {
unshift @{*{ "$module::ISA" }}, 'MyProject::$layer::Base';
}
*{ "MyProject::$layer::$service_name::_get_definition" } = sub {
return $definition;
};
49
50. С AUTOLOAD все ОК, но can надо поправить
sub can {
my ($self, $method) = @_;
my $module = blessed $self ? ref $self : $self;
no strict 'refs';
if (my $sub = *{"$module::$method"}{CODE}) {
return $sub;
} elsif (_has_method($module, $method)) {
return _generate_sub($module, $method);
} else {
return __PACKAGE__->SUPER::can($method);
}
}
50
51. Чего мы добились
• Поигрались с кодогенерацией
• Убрали дублирование кода
• Формализовали декларацию данных для генерации методов
• Научились добавлять вариативное поведение
• Собрали определение сервисов и методов воедино
• Сделали определение типичных методов максимально
лаконичным
• Для новых и отлично ложащихся в шаблон сервисов мы даже
избавились от модулей
• Но при этом сохранили обратную совместимость
• А также возможность добавлять нестандартные методы
• Ленивая инициализация – при запуске сервера не генерируется
ничего лишнего
Но определение сервиса и метода –
это все еще код! 51
53. Декларациям место в текстовом формате
• Окончательно разделяем код и декларации
• Коллбэки prepare и finish выносим в модули, а в
декларациях оставляем имя модуля и функции
• Более компактный формат
• Легкое отключение сервиса на отдельных нодах: просто
удаляем конфиг!
53