SlideShare a Scribd company logo
Многозадачность как
имплементация Unit Of Work
Кирилл,
Харьков
Руководитель Android
разработки
Mail.Ru
Обзор
• Проблемы и задачи.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Требования
• Декомпозиция задач
Требования
• Декомпозиция задач
• Отделение контекста выполнения задачи от логики
Требования
• Декомпозиция задач
• Отделение контекста выполнения задачи от логики
• Возможность связывать различные иерархии задач
Требования
• Декомпозиция задач
• Отделение контекста выполнения задачи от логики
• Возможность связывать различные иерархии задач
• Декларативность в объявлении статических параметров типа задач
Типы задач
• Сетевые операции
Типы задач
• Сетевые операции // Retrofit можно припихнуть сюда, потому что модно..
Типы задач
• Сетевые операции // Retrofit можно припихнуть сюда, потому что модно..
• Операции над моделью
Типы задач
• Сетевые операции // Retrofit можно припихнуть сюда, потому что модно..
• Операции над моделью
• Аналитика
Типы задач
• Сетевые операции // Retrofit можно припихнуть сюда, потому что модно..
• Операции над моделью
• Аналитика
• Рендеринг
Ограничения
Ограничения
Ограничения
Ограничения
Ограничения
Изменение workflow
Изменение workflow
Изменение workflow
Изменение workflow
1. Запрос 1 – ОК
2. Запрос 2 – NoAuth
3. RefreshAuth - Relogin
Изменение workflow
1. Запрос 1 – ОК
2. Запрос 2 – NoAuth
3. RefreshAuth - ОК
4. Запрос 2 - ОК
5. Запрос 3 - ОК
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
• 1999. Refactoring: Improving the Design of Existing Code
• 2000. Planning Extreme Programming
• 2002. Patterns of Enterprise Application Architecture
Команда
Команда
public abstract class Command<P, V> implements Cancelable {
}
Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
}
Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
}
Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {
if (!isCancelled()) {
setResult(onExecute());
onDone();
return mResult;
}
return null;
}
}
Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {…}
protected abstract V onExecute();
}
Команда
public abstract class Command<P, V> implements Cancelable {
private final P mParams;
private V mResult;
public final V execute() {…}
protected abstract V onExecute();
protected void onDone() {
}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {
CommandEntry commandEntry = null;
while ((commandEntry = getNextCommand()) != null){
onExecuteCommand(commandEntry.getCommand());
}
return null;
}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){
…
}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
public void addCommand(Command<?,?> cmd){…}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
protected Object onExecute() {…}
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){…}
public void removeCommand(Command<?,?> cmd){…}
public void removeAllCommands(){…}
public void addCommand(Command<?,?> cmd){…}
public void addCommandAtFront(Command<?,?> cmd){…}
}
Команда
public abstract class CommandGroup extends Command<Void,Object> {
@Override
public void cancel() {
synchronized (this) {
super.cancel();
if(mCurrentFuture != null) {
mCurrentFuture.cancel(true);
}
if(mCurrentCommand != null){
mCurrentCommand.cancel();
}
}
}
}
Команда
Команда
Команда
class SimultaneousCommandGroup extends Command<Void, Map<Command<?, ?>, Object>> {
}
Команда
class SimultaneousCommandGroup extends Command<Void, Map<Command<?, ?>, Object>> {
@Override
protected Map<Command<?, ?>, Object> onExecute() {
final Set<Command<?, ?>> commands = new HashSet<>();
synchronized (this) {
commands.addAll(mCommandsResults.keySet());
}
for (Command<?, ?> cmd : commands) {
onExecuteCommand(cmd);
}
awaitForCompletion();
return convertToResult();
}
}
Команда
public class RemoveAttachment extends PostRequest<Params, EmptyResult> {
}
Команда
@LogConfig(logTag = "RemoveAttachmentCmd", logLevel = Level.D)
@Authorization(api = "LEGACY", factory = MailAuthorization.MailApiInterfaceFactory.class)
@HostProvider(prefKey="attach", defScheme = R.string..scheme, defHost = R.string.host)
@UrlPath(pathSegments = {"cgi-bin", "attach_upload2"})
public class RemoveAttachment extends PostRequest<Params, EmptyResult> {
}
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Ограничения
• Проблемы и задачи.
• Long running operations. Типы задач. Ограничения.
• Шаблонные операции, изменение workflow задач.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс.
• Фоновые задачи и их приоритезация.
• Особенности тестирования.
Планировщик задач
Планировщик задач
Планировщик задач
@ExecutionPool(pool = ExecutionPool.Pool.NETWORK)
@ExecutionPool(pool = ExecutionPool.Pool.NETWORK)
@ExecutionPool(pool = ExecutionPool.Pool.DATABASE)
Планировщик задач
Планировщик задач
Ограничения
Планировщик задач
public abstract class CommandGroup extends Command<Void,Object> {
@Nullable
@CheckForNull
protected <T> T onExecuteCommand(Command<?, T> cmd){
final Future<T> future = getExecutor().execute(cmd);
final T result = getResultFromFuture(future);
return result;
}
}
Планировщик задач
public <T> Future <T> executeSingleCommand(final Command<?, T> cmd) {
}
Планировщик задач
public <T> Future <T> executeSingleCommand(final Command<?, T> cmd) {
Callable<T> callable = createCallable(cmd);
FutureTask<T> newFutureTask = new RemoveFutureTask<>(callable, cmd);
Future<T> future = (Future<T>) mCache.putIfAbsent(cmd, newFutureTask);
if (future == null) {
executeOnPool(newFutureTask, getExecutionPool(cmd));
return newFutureTask;
}
return future;
}
Планировщик задач
public <T> Future <T> executeSingleCommand(final Command<?, T> cmd) {
Callable<T> callable = createCallable(cmd);
FutureTask<T> newFutureTask = new RemoveFutureTask<>(callable, cmd);
Future<T> future = (Future<T>) mCache.putIfAbsent(cmd, newFutureTask);
if (future == null) {
executeOnPool(newFutureTask, getExecutionPool(cmd));
return newFutureTask;
}
return future;
}
Команда
public abstract class Command<P, V> implements Cancelable {
@Override
public int hashCode() {
int result = this.getClass().hashCode();
result = 31 * result + (mParams != null ? mParams.hashCode() : 0);
return result;
}
}
Команда
public abstract class Command<P, V> implements Cancelable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (mParams != null ? !mParams.equals(((Command) o).getParams()) :
((Command) o).getParams() != null)
return false;
return true;
}
}
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Планировщик задач
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Приоритезация
Приоритезация
Приоритезация
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
Обзор
• Проблемы и задачи.
• Команды, компановщики, варианты исполнения.
• Планировщик задач, кэширование, прогресс, приоритезация.
• Особенности тестирования.
@twitter
Question?
facebook
www.info@mail.ru
Кирилл,
Харьков
Руководитель Android
разработки
Mail.Ru

More Related Content

What's hot

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
Sergey Platonov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
Sergey Platonov
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Sergey Platonov
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Sergey Platonov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
Eugeniy Tyumentcev
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Sergey Platonov
 
Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”
Platonov Sergey
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
Yandex
 
Практика использования Dependency Injection
Практика использования Dependency InjectionПрактика использования Dependency Injection
Практика использования Dependency Injection
Platonov Sergey
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
Technopark
 
Профайлинг.
Профайлинг. Профайлинг.
Профайлинг.
Nikita Romanov
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
corehard_by
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
Platonov Sergey
 
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...sqadays8
 
Быстрое введение в TDD от А до Я
Быстрое введение в TDD от А до ЯБыстрое введение в TDD от А до Я
Быстрое введение в TDD от А до Я
Andrey Bibichev
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
Andrey Karpov
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
Anton Arhipov
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 

What's hot (20)

Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 
Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”Михаил Матросов, “С++ без new и delete”
Михаил Матросов, “С++ без new и delete”
 
Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11Дмитрий Прокопцев — R-ссылки в С++11
Дмитрий Прокопцев — R-ссылки в С++11
 
Практика использования Dependency Injection
Практика использования Dependency InjectionПрактика использования Dependency Injection
Практика использования Dependency Injection
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
Профайлинг.
Профайлинг. Профайлинг.
Профайлинг.
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
Практика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-серверПрактика Lock-free. RealTime-сервер
Практика Lock-free. RealTime-сервер
 
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
Надежда Серкова -- Автоматическая генерация Perl скриптов для тестирования си...
 
Быстрое введение в TDD от А до Я
Быстрое введение в TDD от А до ЯБыстрое введение в TDD от А до Я
Быстрое введение в TDD от А до Я
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 

Viewers also liked

Никита Арыков и Анастасия Лагунова
Никита Арыков и Анастасия ЛагуноваНикита Арыков и Анастасия Лагунова
Никита Арыков и Анастасия Лагунова
CodeFest
 
Степан Колесников
Степан КолесниковСтепан Колесников
Степан Колесников
CodeFest
 
Саша Гладких и Андрей Старков
Саша Гладких и Андрей СтарковСаша Гладких и Андрей Старков
Саша Гладких и Андрей Старков
CodeFest
 
Дмитрий Кулижников
Дмитрий КулижниковДмитрий Кулижников
Дмитрий Кулижников
CodeFest
 
Дмитрий Евдокимов
Дмитрий ЕвдокимовДмитрий Евдокимов
Дмитрий Евдокимов
CodeFest
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
CodeFest
 
Павел Мочалкин
Павел МочалкинПавел Мочалкин
Павел Мочалкин
CodeFest
 
Jan Jongboom
Jan JongboomJan Jongboom
Jan Jongboom
CodeFest
 
Maurice de Beijer
Maurice de BeijerMaurice de Beijer
Maurice de Beijer
CodeFest
 
Анатолий Шарифулин
Анатолий ШарифулинАнатолий Шарифулин
Анатолий Шарифулин
CodeFest
 
Иван Величко
Иван ВеличкоИван Величко
Иван Величко
CodeFest
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
CodeFest
 
Андрей Себрант
Андрей СебрантАндрей Себрант
Андрей Себрант
CodeFest
 
Евгений Брянцев
Евгений БрянцевЕвгений Брянцев
Евгений Брянцев
CodeFest
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван Панченко
CodeFest
 
Денис Паясь
Денис ПаясьДенис Паясь
Денис Паясь
CodeFest
 
Вадим Макеев
Вадим МакеевВадим Макеев
Вадим Макеев
CodeFest
 
Роман Янке
Роман ЯнкеРоман Янке
Роман Янке
CodeFest
 
Максим Дорофеев
Максим ДорофеевМаксим Дорофеев
Максим Дорофеев
CodeFest
 
Никита Липский и Владимир Парфиненко
Никита Липский и Владимир ПарфиненкоНикита Липский и Владимир Парфиненко
Никита Липский и Владимир Парфиненко
CodeFest
 

Viewers also liked (20)

Никита Арыков и Анастасия Лагунова
Никита Арыков и Анастасия ЛагуноваНикита Арыков и Анастасия Лагунова
Никита Арыков и Анастасия Лагунова
 
Степан Колесников
Степан КолесниковСтепан Колесников
Степан Колесников
 
Саша Гладких и Андрей Старков
Саша Гладких и Андрей СтарковСаша Гладких и Андрей Старков
Саша Гладких и Андрей Старков
 
Дмитрий Кулижников
Дмитрий КулижниковДмитрий Кулижников
Дмитрий Кулижников
 
Дмитрий Евдокимов
Дмитрий ЕвдокимовДмитрий Евдокимов
Дмитрий Евдокимов
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
 
Павел Мочалкин
Павел МочалкинПавел Мочалкин
Павел Мочалкин
 
Jan Jongboom
Jan JongboomJan Jongboom
Jan Jongboom
 
Maurice de Beijer
Maurice de BeijerMaurice de Beijer
Maurice de Beijer
 
Анатолий Шарифулин
Анатолий ШарифулинАнатолий Шарифулин
Анатолий Шарифулин
 
Иван Величко
Иван ВеличкоИван Величко
Иван Величко
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Андрей Себрант
Андрей СебрантАндрей Себрант
Андрей Себрант
 
Евгений Брянцев
Евгений БрянцевЕвгений Брянцев
Евгений Брянцев
 
Олег Бартунов и Иван Панченко
Олег Бартунов и Иван ПанченкоОлег Бартунов и Иван Панченко
Олег Бартунов и Иван Панченко
 
Денис Паясь
Денис ПаясьДенис Паясь
Денис Паясь
 
Вадим Макеев
Вадим МакеевВадим Макеев
Вадим Макеев
 
Роман Янке
Роман ЯнкеРоман Янке
Роман Янке
 
Максим Дорофеев
Максим ДорофеевМаксим Дорофеев
Максим Дорофеев
 
Никита Липский и Владимир Парфиненко
Никита Липский и Владимир ПарфиненкоНикита Липский и Владимир Парфиненко
Никита Липский и Владимир Парфиненко
 

Similar to Кирилл Харьков

Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Yandex
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Sigma Software
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Dev2Dev
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Yandex
 
Java/Scala Lab: Юрий Литвиненко - Lightning talk
Java/Scala Lab: Юрий Литвиненко - Lightning talkJava/Scala Lab: Юрий Литвиненко - Lightning talk
Java/Scala Lab: Юрий Литвиненко - Lightning talkGeeksLab Odessa
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x Introduction
Fedor Vompe
 
Working with API
Working with APIWorking with API
Working with API
Mad Devs
 
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 27bits
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Yandex
 
Превышаем скоросные лимиты с Angular 2
Превышаем скоросные лимиты с Angular 2Превышаем скоросные лимиты с Angular 2
Превышаем скоросные лимиты с Angular 2
Oleksii Okhrymenko
 
20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliaminComputer Science Club
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf Conference
 
Techtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real lifeTechtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real life
DA-14
 
Tricky Java Generics
Tricky Java GenericsTricky Java Generics
Tricky Java Generics
Alexander Matorin
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
Alexander Podkhalyuzin
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
GoSharp
 
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Ontico
 
Разработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительностьРазработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительность
Вадим Воробьев
 

Similar to Кирилл Харьков (20)

Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин Как навести порядок в коде вашего web-приложения, Андрей Чебукин
Как навести порядок в коде вашего web-приложения, Андрей Чебукин
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Статический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий ЛевановСтатический и динамический полиморфизм в C++, Дмитрий Леванов
Статический и динамический полиморфизм в C++, Дмитрий Леванов
 
Odd
OddOdd
Odd
 
Java/Scala Lab: Юрий Литвиненко - Lightning talk
Java/Scala Lab: Юрий Литвиненко - Lightning talkJava/Scala Lab: Юрий Литвиненко - Lightning talk
Java/Scala Lab: Юрий Литвиненко - Lightning talk
 
Cpp0x Introduction
Cpp0x IntroductionCpp0x Introduction
Cpp0x Introduction
 
Working with API
Working with APIWorking with API
Working with API
 
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 2
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
Превышаем скоросные лимиты с Angular 2
Превышаем скоросные лимиты с Angular 2Превышаем скоросные лимиты с Angular 2
Превышаем скоросные лимиты с Angular 2
 
20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin20100927 28 reqformalization-kuliamin
20100927 28 reqformalization-kuliamin
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
 
Techtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real lifeTechtalk#8: Design patterns in real life
Techtalk#8: Design patterns in real life
 
Tricky Java Generics
Tricky Java GenericsTricky Java Generics
Tricky Java Generics
 
Tdd php
Tdd phpTdd php
Tdd php
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETОпыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NET
 
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
Moxy. Как правильно пользоваться? / Юрий Шмаков (Arello Mobile)
 
Разработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительностьРазработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительность
 

More from CodeFest

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
CodeFest
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита Прокопов
CodeFest
 
Денис Баталов
Денис БаталовДенис Баталов
Денис Баталов
CodeFest
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена Гальцина
CodeFest
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр Калашников
CodeFest
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина Иванова
CodeFest
 
Marko Berković
Marko BerkovićMarko Berković
Marko Berković
CodeFest
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис Кортунов
CodeFest
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр Зимин
CodeFest
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
CodeFest
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей Игнатов
CodeFest
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай Крапивный
CodeFest
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
CodeFest
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим Смирнов
CodeFest
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
CodeFest
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
CodeFest
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим Пугачев
CodeFest
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene Groeschke
CodeFest
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван Бондаренко
CodeFest
 
Mete Atamel
Mete AtamelMete Atamel
Mete Atamel
CodeFest
 

More from CodeFest (20)

Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Никита Прокопов
Никита ПрокоповНикита Прокопов
Никита Прокопов
 
Денис Баталов
Денис БаталовДенис Баталов
Денис Баталов
 
Елена Гальцина
Елена ГальцинаЕлена Гальцина
Елена Гальцина
 
Александр Калашников
Александр КалашниковАлександр Калашников
Александр Калашников
 
Ирина Иванова
Ирина ИвановаИрина Иванова
Ирина Иванова
 
Marko Berković
Marko BerkovićMarko Berković
Marko Berković
 
Денис Кортунов
Денис КортуновДенис Кортунов
Денис Кортунов
 
Александр Зимин
Александр ЗиминАлександр Зимин
Александр Зимин
 
Сергей Крапивенский
Сергей КрапивенскийСергей Крапивенский
Сергей Крапивенский
 
Сергей Игнатов
Сергей ИгнатовСергей Игнатов
Сергей Игнатов
 
Николай Крапивный
Николай КрапивныйНиколай Крапивный
Николай Крапивный
 
Alexander Graebe
Alexander GraebeAlexander Graebe
Alexander Graebe
 
Вадим Смирнов
Вадим СмирновВадим Смирнов
Вадим Смирнов
 
Константин Осипов
Константин ОсиповКонстантин Осипов
Константин Осипов
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
Максим Пугачев
Максим ПугачевМаксим Пугачев
Максим Пугачев
 
Rene Groeschke
Rene GroeschkeRene Groeschke
Rene Groeschke
 
Иван Бондаренко
Иван БондаренкоИван Бондаренко
Иван Бондаренко
 
Mete Atamel
Mete AtamelMete Atamel
Mete Atamel
 

Кирилл Харьков

Editor's Notes

  1. Всем привет, меня зовут Кирилл Харьков, я занимаюсь Android разработкой в Mail.Ru, Я бы хотел сегодня рассказать вам о том, как мы подходим к формированию и выполнению задач в наших проектах. Разнотипных задач в любом проекте много. Это АПИ взаимодействие, изменение объектов доменной модели, подсчеты, рендеринг и т.д. Держать это все в порядке нам нужно, причем нужно это делать не частично, а комплексно. Сразу хочу сказать, что мой доклад никак не противоречит использованию rxJava и retrofit, и это не еще одна попытка привнести плюшки Функциональных языков в ваш проект. Я предлагаю чуть шире посмотреть на процесс выполнения задач и расскажу о решениях, которые помогут более гибко им управлять. Свой доклад я предлагаю построить следующим образом:
  2. Сначала я расскажу как все плохо. Как много задач и какие страшные проблемы поджидают нас на пути их решения Также я немного расскажу о классификации этих задач, к чему это все применимо и рассмотрю несколько кейзов, в которых простые решения не работают.
  3. Возьмем пример казалось бы простой задачи: У нас есть письмо, которое необходимо показать пользователю. Из чего состоит эта задача
  4. Что это значит? С точки зрения написания кода выполнение должно казаться линейным и однопоточным. Но должна быть возможность выполнять каждую отдельную команду по-своему. В своем потоке, со своей стратегией публикации результата
  5. Например это запросы на разные сервера, которые ходят по разному API, соответственно имеют разную иехрархию классов, но должны быть перемешаны из-за кривой бизнес логики.
  6. Это в большей степени является проблемой, в тех случаях когда такая декларативность отсутствует. Часто бывает так, что в необходимая информация о каком-то запросе\задаче скрыта в предках настолько глубоко, что когда до нее нужно докопаться, это занимает кучу времени и сильно запутывает клиента класса. Итак, вся эта задумка изначально нацелена, конечно на long running operations, в принципе, … Рассмотрим типичную задачу «открытие новости» из чего она может состоять:
  7. Рассмотрим христоматийное приложение, например показ новостей.
  8. Рассмотрим христоматийное приложение, например показ новостей.
  9. Рассмотрим христоматийное приложение, например показ новостей.
  10. Рассмотрим христоматийное приложение, например показ новостей.
  11. Как это выглядит
  12. Мы сначала проверяем локальный сторадж, потом идем в сеть. Допустим у нас медленное соединение. Сеть нестабильна. Ограничение по параллельному исполнению задач достигнуты, потому что все ждут пока нам придет результат от сети.
  13. Пользователь устал ждать и хочет выйти в список, чтобы прочитать то, что он отложил себе в заметки, пока наше приложение пыхтит и пытается получить данные из сети. Он не может этого сделать, хотя запрос локального списка сейчас может легко выполниться, ведь в модель никто ничего не пишет и не читает оттуда. Модель свободна и доступна для чтения и записи Это проблема, причем очень неприятная проблема и мы вернемся к ней еще, когда я буду рассказывать подробнее о контексте выполнения задач и о планировщике.
  14. Теперь давайте рассмотрим еще такую модную и всячески пропагандируемую со стороны евангелистов android фичу, как префетчинг. Что это такое. Это предзагрузка данных. Приложение должно грузить данные заранее, чтобы для пользователя создать лучший user experience и максимально быстро показать ему информацию. Это круто. Но это дает возможность приложению начать запрашивать одни и те же данные из разных модулей приложения: из префетчинга и например из интерфейса пользователя.
  15. Естесственно, мы не можем гарантировать в какой последовательности эти операции попадут на выполнение. Если вторая задача, например от интерфейса поступит после того как первая полностью завершилась, то у нас нет проблемы. Если же произойдет как показано на этой схеме, то мы два раза запросим одно и то же. Зачем нам такое прекеширование, которое в два раза увеличит трафик приложения?
  16. В идеале мы хотим получить во вторую операцию результат выполнения первой операции, так как он будет доступен раньше. Давайте еще немного усложним задачу, и представим, что эти одинаковые операции имеют какой-то детерминированный прогресс. Соответственно задача, которая поступила позже должна не только получить результат от первой задачи, но еще и получать прогресс. Очевидно, что это прогресс для второй задачи начнется не с нуля, а с того места, на котором сейчас находится первая задача.
  17. Рассмотрим христоматийное приложение, например показ новостей.
  18. Рассмотрим христоматийное приложение, например показ новостей.
  19. Рассмотрим христоматийное приложение, например показ новостей.
  20. Рассмотрим христоматийное приложение, например показ новостей.
  21. Рассмотрим христоматийное приложение, например показ новостей.
  22. Рассмотрим христоматийное приложение, например показ новостей.
  23. Рассмотрим христоматийное приложение, например показ новостей.
  24. Рассмотрим христоматийное приложение, например показ новостей.
  25. Рассмотрим христоматийное приложение, например показ новостей.
  26. Рассмотрим христоматийное приложение, например показ новостей.
  27. Рассмотрим христоматийное приложение, например показ новостей.
  28. Рассмотрим христоматийное приложение, например показ новостей.
  29. Рассмотрим христоматийное приложение, например показ новостей.
  30. Рассмотрим христоматийное приложение, например показ новостей.
  31. Здесь важный момент это имплементация с точки зрения потокобезопасности. Мы должны безопасно получить следующую команду в многопоточном контексте выполнения, но не должны блокироваться на методе, иначе мы не сможем эту команду отменить. Всвязи с этим нужно осторожно подойти к имплементации метода получения следующей команды. Эта часть выходит за рамки доклада, если кому-то интересно, всю реализацию я могу показать и рассказать после сессии.
  32. Здесь важный момент это имплементация с точки зрения потокобезопасности. Мы должны безопасно получить следующую команду в многопоточном контексте выполнения, но не должны блокироваться на методе, иначе мы не сможем эту команду отменить. Всвязи с этим нужно осторожно подойти к имплементации метода получения следующей команды. Эта часть выходит за рамки доклада, если кому-то интересно, всю реализацию я могу показать и рассказать после сессии.
  33. Это точка расширения поведения и обработки результатов выполнения команды для потомков. Мы еще вернемся к этом методу, когда будем говорить о контексте выполнения операций. Базовая имплементация просто получает результат выполнения команды и удаляет выполненную команду. Наследники могут взять этот результат и обработать
  34. Таким образом мы можем реализовать обертку, которая будет следить за авторизацией команд.
  35. Пример с обновлением очень характерен, потому что мы не хотим показать пользователю закешированную информацию сначала, и идти на сервер за обновлениями, но мы не хотим ждать, эти задачи должны выполняться параллельно. Сначала мы делали две независимые задачи. Мы пробовали по-разному обыграть этот кейз, но в итоге обманывали сами себя. Сталкивались с проблемами повторного выполнения запросов и т.д. Тогда мы решили решать задачу так, как она сформулирована. Если от нас требуется делать что-то параллельно, то стоит попробовать делать это параллельно.
  36. Рассмотрим христоматийное приложение, например показ новостей.
  37. Разница с CommandGroup в том, что там мы отправляем на выполнение и ждем результат, а здесь сначала все команды отправляем на выполнение, а потом ждем пока все завершатся. Результатом параллельных независимых задач является Map, который собирается из результатов выполнения каждой отдельной команды
  38. Итак мы получаем этакие building blocks, с помощью которых у нас есть возможность выстроить compound операцию любой сложности. Я затрагивал проблему декларативности того что происходит. Причина в том, что в сложной бизнес логике невозможно выстроить структуру классов так, чтобы не пришлось идти на компромисс. Где то мы добавляем дублирование, где-то не можем переиспользовать имеющийся код, где-то добавляем костыли. Чаще всего речь идет о статических особенностях какого-то класса. В таком случае никогда не стоит забывать о таком мощном инструменте как аннотации
  39. Таким образом мы можем задавать и потом использовать, например в планировщике задач информацию о том, куда этот запрос пошел, сколько выполнялся, как его правильно логировать и так далее. К тому же при необходимости, все необходимая информация находится в объявлении класса. С параметрами мы пошли еще дальше и повесили на них полную информацию о том, как эти параметры будут передаваться серверу.
  40. Вспоминаем первый кейз: У нас сетевые операции из-за медленного интернета повесили весь пул потоков. Мы не можем выполнить выборку из модели, потому что исчерпали лимит.
  41. Рассмотрим христоматийное приложение, например показ новостей.
  42. Рассмотрим христоматийное приложение, например показ новостей.
  43. Рассмотрим христоматийное приложение, например показ новостей.
  44. Рассмотрим христоматийное приложение, например показ новостей.
  45. Теперь возвращаемся ко второму ограничению:
  46. Специфика android разработки такова, что архитектура приложения может и должна быть независимой друг от друга и состоять из обособленных модулей, которые могут работать вместе или по отдельности и в идеале вообще не знают о существовании друг друга. Эта особенность значительно усложняет задачу, потому что появляются повторные запросы в одно и то же время. Как я уже приводил пример, это может быть префетчер, который получил сигнал о том, что можно грузить новости и пользователь, который вдруг открыл именно ту новость, которую префетчер старательно подгружает для него. В целом проблема не новая, бывалые java разработчики сразу вспомнили про Future интерфейс
  47. Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
  48. Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
  49. Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
  50. Таким образом мы можем «склеивать» эквивалентные команды и выполнять только тот экземпляр команды, который поступил раньше.
  51. Рассмотрим христоматийное приложение, например показ новостей.
  52. Рассмотрим христоматийное приложение, например показ новостей.
  53. Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
  54. Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
  55. Теперь возвращаемся ко второму ограничению:
  56. Теперь возвращаемся ко второму ограничению:
  57. Теперь возвращаемся ко второму ограничению:
  58. Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.
  59. Для того чтобы добавлять прогресс, нужно всего лишь определиться со стандартом того, как этот прогресс передается В случае, если мы отдали на выполнение команду, которая уже отправлена на executor, мы просто можем приаттачить еще один ProgressListener и команда начнет уведомлять о своем прогрессе обоих слушателей.