Пользователи ожидают обновление данных в реальном времени. Твиты должны появляться без задержек. Заказы должны быть подтверждены и обработаны мгновенно. Приложения должны быть отзывчивыми. Мы, как разработчики, не хотим блокировать потоки в ожидании результатов. Мы хотим чтобы результаты были переданы нам как только будут готовы. Более того - при работе с коллекциями данных каждый отдельный объект должен быть передан сразу как будет готов. У нас есть инструменты для создания уведомлений, это легко. Нам нужны удобные инструменты для реакции на оповещения.
Из доклада вы узнаете как создавать удобные, отзывчивые и тестируемые приложения при помощи Reactive Extensions, как многократно сократить код обработки событий, а также как совместить существующий код на основе событий с данным фреймворком
Михаил Рахманов рассказывает о паттерне Promise и его использовании в iOS разработке.
Краткие тезисы:
- Что такое promises?
- Использование promises в iOS разработке (существующие библиотеки и подходы)
- Реализация promises библиотекой PromiseKit (основные методы, цепочки promises, обработка ошибок)
- Какие задачи можно решить с помощью promises, а какие - нельзя
- Использование promises на примере приложения: драм-машины с возможностью сохранять аудио-дорожки
- Подведение итогов: преимущества и недостатки.
RDSDataSource - внутренние пятничные митапы iOS-команды RAMBLER&Co.
Guava - open-source библиотека, разработанная в основном инженерами компании Google, в которой есть множество полезных утилит для написания эффективного и красивого кода. В Guava решено множество типичных задач, которые часто возникают при работе с примитивами, строками, коллекциями, параллельными вычислениями, кэшированием данных и многим другим. В докладе поговорим о возможностях, которые предоставляет Guava, рассмотрим примеры использования утилит библиотеки.
Михаил Рахманов рассказывает о паттерне Promise и его использовании в iOS разработке.
Краткие тезисы:
- Что такое promises?
- Использование promises в iOS разработке (существующие библиотеки и подходы)
- Реализация promises библиотекой PromiseKit (основные методы, цепочки promises, обработка ошибок)
- Какие задачи можно решить с помощью promises, а какие - нельзя
- Использование promises на примере приложения: драм-машины с возможностью сохранять аудио-дорожки
- Подведение итогов: преимущества и недостатки.
RDSDataSource - внутренние пятничные митапы iOS-команды RAMBLER&Co.
Guava - open-source библиотека, разработанная в основном инженерами компании Google, в которой есть множество полезных утилит для написания эффективного и красивого кода. В Guava решено множество типичных задач, которые часто возникают при работе с примитивами, строками, коллекциями, параллельными вычислениями, кэшированием данных и многим другим. В докладе поговорим о возможностях, которые предоставляет Guava, рассмотрим примеры использования утилит библиотеки.
Yield at me 'cause I'm awaiting: асинхронные итераторы в C# 8Andrey Karpov
Язык C# продолжает интенсивно развиваться. Готовящаяся к выходу новая версия добавляет поддержку асинхронных итераторов. Что это такое? Для чего это нужно? Как это работает? В докладе мы ответим на все эти вопросы, разберём нововведения в BCL, сравним новые возможности с уже существующими средствами и, конечно же, заглянем под капот компилятора.
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
В своем докладе Олег расскажет о замене стандартных функций на более быстрые и об ускорении работы python. Также продемонстрирует несколько примеров быстрых конструкций python.
Вводная лекция в язык C#, для тех кто знает программирование и в особенности C++. В статье будет уделено внимание наиболее важным отличиям языков, будут обсуждаться вопросы производительности и эффективного кода.
Другие интересные статьи по C# ищите тут: http://itw66.ru/blog/c_sharp/
Написание компактного и эффективного кода в C#: http://itw66.ru/blog/c_sharp/520.html
Доклад вводит в рассмотрение универсальный адаптер, позволяющий обернуть любой класс с целью добавления новых свойств, отсутствующих в оригинальном классе. Получаемые классы могут иметь в точности такой же интерфейс, как и первоначальные, что позволяет прозрачно заменять их и оборачивать любое количество раз.
Это позволяет добавлять необходимые свойства объектам, не переписывая его с нуля. Предложенная обобщенная концепция будет последовательно введена и проиллюстрирована простыми, но интересными примерами.
Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)Ontico
HighLoad++ 2017
Зал «Найроби + Касабланка», 8 ноября, 11:00
Тезисы:
http://www.highload.ru/2017/abstracts/2950.html
Одним из приемов, позволяющих увеличить скорость обработки и получения данных, является написание хранимых процедур. В этом докладе будут рассмотрены преимущества и недостатки такого подхода на примере Tarantool.
Tarantool можно рассматривать как полноценный application server. При таком подходе к разработке приложения, запущенные на Tarantool, можно рассматривать как микросервисы.
...
Yield at me 'cause I'm awaiting: асинхронные итераторы в C# 8Andrey Karpov
Язык C# продолжает интенсивно развиваться. Готовящаяся к выходу новая версия добавляет поддержку асинхронных итераторов. Что это такое? Для чего это нужно? Как это работает? В докладе мы ответим на все эти вопросы, разберём нововведения в BCL, сравним новые возможности с уже существующими средствами и, конечно же, заглянем под капот компилятора.
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
В своем докладе Олег расскажет о замене стандартных функций на более быстрые и об ускорении работы python. Также продемонстрирует несколько примеров быстрых конструкций python.
Вводная лекция в язык C#, для тех кто знает программирование и в особенности C++. В статье будет уделено внимание наиболее важным отличиям языков, будут обсуждаться вопросы производительности и эффективного кода.
Другие интересные статьи по C# ищите тут: http://itw66.ru/blog/c_sharp/
Написание компактного и эффективного кода в C#: http://itw66.ru/blog/c_sharp/520.html
Доклад вводит в рассмотрение универсальный адаптер, позволяющий обернуть любой класс с целью добавления новых свойств, отсутствующих в оригинальном классе. Получаемые классы могут иметь в точности такой же интерфейс, как и первоначальные, что позволяет прозрачно заменять их и оборачивать любое количество раз.
Это позволяет добавлять необходимые свойства объектам, не переписывая его с нуля. Предложенная обобщенная концепция будет последовательно введена и проиллюстрирована простыми, но интересными примерами.
Хранимые процедуры в NoSQL СУБД на примере Tarantool / Денис Линник (Mail.Ru)Ontico
HighLoad++ 2017
Зал «Найроби + Касабланка», 8 ноября, 11:00
Тезисы:
http://www.highload.ru/2017/abstracts/2950.html
Одним из приемов, позволяющих увеличить скорость обработки и получения данных, является написание хранимых процедур. В этом докладе будут рассмотрены преимущества и недостатки такого подхода на примере Tarantool.
Tarantool можно рассматривать как полноценный application server. При таком подходе к разработке приложения, запущенные на Tarantool, можно рассматривать как микросервисы.
...
Anemic Domain Model - антипаттерн или SOLID?GoSharp
Мартин Фаулер считает, что Anemic Domain Model (или бледная доменна модель) это плохо, и антипаттерн, противопоставляя ей Rich Domain Model с интегрированным поведением и бизнес логикой.
При этом есть другие мнения, возможно не столь распространенные. Я попробую рассказать об опыте использования Anemic Domain Model при разработке крупного корпоративного приложения. Какие плюсы и минусы мы нашли, и как преодолевали трудности.
Мы с вами узнаем, как предполагается использовать TPL Dataflow, рассмотрим плюсы и минусы его внедрения, а так же и особенности использования и настройки под конкретную задачу
Какие проблемы решают инструменты статического анализа. Обзор фич и как они помогают писать код быстрее и лучше. Рассказ о перспективах развития Решарпера и разработки в целом.
"За" и "против" дополнений для VisualStudio.
Обзор возможностей CodeRush.
Как использовать Шаблоны для ускорения разработки.
Рефакторинг, статический анализ.
Roslyn, VS 2014 и CodeRush.
Как попасть на следующий уровень карьеры и зарплаты в C#GoSharp
Есть ли потолок заработной платы? Что делать, если Вы уперлись в него. Как преодолевать уровни сопротивления и избегать в ловушек в карьере .net разработчика. Результат анализа более 6.000 резюме C# разработчиков в Москве.
Solit 2014, Реактивный Javascript. Победа над асинхронностью и вложенностью, ...solit
Виктор Русакович, Минск, Web-developer c 6-ти летним опытом разработки, компания GP Software.travel
«Реактивный JavaScript. Победа над асинхронностью и вложенностью». Development секция. Для разработчиков. Высокий уровень подготовки.
«Непрерывная интеграция сложного проекта. Кто всё сломал?». IT секция. Agile отделение. Для всех уровней подготовки.
Лекция для студентов АлтГТУ, проведенная 04.03.2015. В ходе лекции рассматривались следующие ключевые моменты:
1) Lambda project
2) Steam API
3) Date API
Java 8, самой заметной фичей которой стало появление лямбд, вышла два года назад, а в этом году мы даже начали её использовать в продакшен коде Идеи. Такое заметное нововведение в языке вызывает множество вопросов. Какие возможности перед нами открываются и какие проблемы при неаккуратном использовании лямбд могут возникнуть, как лямбды устроены внутри, во что они компилируются и как исполняются — вот темы, которые мы обсудим на докладе.
Асинхронность стала неотъемлемой частью как клиент-сайда, так и бек-энда. Будут рассмотрены основные паттерны и библиотеки, позволяющие сделать код читаемым и поддерживаемым.
Лекция 8. Итераторы, генераторы и модуль itertools.Roman Brovko
Два протокола итераторов: __next__ + __iter__ и __getitem__. Итераторы и цикл for, а также операторы in и not in. Генераторы, оператор-выражение yield. Генераторы как: итераторы, сопрограммы, менеджеры контекста. Модуль itertools.
Артемий Гарин "Выбор лучшего хранилища в Android (cпойлер: Realm)"IT Event
"Выбор хранилища для проекта — важная часть разработки. Раньше в Android, было сложно: много различных ORM-библиотек на SQLite, есть NoSQL библиотеки, но нет чего-то действительно быстрого и легкого в работе.
Появление Realm изменило всё. В докладе мы сравним его с популярными SQLite ORM библиотеками, посмотрим что быстрее, с чем проще работать. В конце доклада пара слов об еще одном, новом и интересном инструменте, который сравнимым с Realm."
Эволюция пользовательского интерфейса бизнес-приложений: от DOSa через окна в...GoSharp
Бизнес-приложения являются одним из самых массовых типов программного обеспечения; многие из людей проводят бОльшую часть своего дня, работая с ERP, CRM и другими программами, обслуживающими жизненный цикл предприятия. Как сделать программу, которая поддерживает сложные бизнес-процессы, простой в использовании? Чем можно пожертвовать ради удобства пользователя? На примере 1С мы рассмотрим, как эволюционировал пользовательский интерфейс деловых приложений со времен DOS до наших дней, какие методики используются для улучшения юзабилити.
UniversalApp "убийца" WPF или же это WPF+ ?GoSharp
Доклад освящает основные вопросы касающиеся Universal App и WPF, например:
• Развитие WPF и появление WinRT
• Унификация Windows-платформы и UAP
• Инвестиции в WPF
• Как WPF стыкуется с UAP + матрица миграции (когда и как стоит мигрировать, а когда нет)
UI тестирование WPF приложений в Дойче БанкеGoSharp
Мы расскажем о техническом решении для тестирования WPF приложений в Дойче Банке, использующем простую технику DLL-иньекции.
Поймем, что можно легко тестировать UI без библиотеки Microsoft UI Automation и даже напишем свой собственный подобный мини-фреймворк.
Практика применения Enterprise Architect и T4-шаблонов для разработки системы...GoSharp
Разработка любой крупной системы сопряжена со множеством трудностей, особенно когда система должна целиком функционировать в базе данных. А из-за невозможности создавать и поддерживать стандартные конструкции для проверки бизнес-правил, обработки исключений, логирования ошибочных данных разрабатываемые системы получаются еще и отнюдь не простыми в сопровождении.
В докладе будет представлено решение, основанное на совмещении рукописного кода и сгенерированных стандартных конструкций, поддерживающее разработку в подходе Model First и автоматизированное распространение изменений в структуру базы данных и хранимые процедуры. Реализация описанного подхода будет продемонстрирована на связке Enterprise Architect и T4-шаблонов кодогенерации.
Базовые возможности EF и их особенности, делающие применение EF в реальных проектах грустным и затратным занятием. Flexberry ORM — отечественный ORM, основные сценарии его применения, сравнение производительности с EF. Короткий рассказ с картинками и примерами в исходных кодах.
MVVM в WinForms – DevExpress Way (теория и практика)GoSharp
Из доклада вы узнаете о применении популярного паттерна MVVM для упрощения и ускорения процесса разработки desktop-приложений.
Будут рассмотрены общие проблемы этого паттерна и решения которые мы предлагаем в нашем кроссплатформенном MVVM фреймворке. Упор будет сделан на практические аспекты и техники в условиях использования платформы WinForms и контролов от DevExpress.
Проектирование сетевой инфраструктуры под SOA проекты ASP.NETGoSharp
При планировании сервисно-ориентированной архитектуры проекта крайне важно учитывать требования к работе сервиса в существующих реалиях Enterprise инфраструктуры. Если эти системы строятся независимо, то возникнут проблемы в размещении сервисов на боевом окружении, сложности управления, безопасности и надёжности. В докладе вы увидите подходы к проектированию инфраструктуры под сервисы и сервисов под инфраструктуру, а так же примеры борьбы со сложностью планирования инфраструктуры.
Мониторинг приложений ASP.NET на основе сервиса Application InsightsGoSharp
После запуска приложения в продакшн в большинстве случаев мы отправляем его в свободное плавание и не знаем о его работе ничего. Сервис Application Insights призван заполнить этот пробел и получить исчерпывающие знания о том, как работает ваше приложение и какие усилия мы должны приложить, чтобы сделать его лучше.
Опыт разработки сложных клиент-серверных приложений на TypeScript и ASP.NETGoSharp
Наша команда в DevExpress недавно выпустила Preview версию нового продукта, RTF web-редактора – ASPxRichEdit.
Продукт требует высокой отзывчивости на действия пользователя и максимальной производительности. Поэтому клиент получился «толстым» в отличие от «тонких клиентов» большинства бизнес-приложений.
В составе продукта два полнофункциональных компонента - клиентский и серверный текстовые процессоры. Оба компонента работают независимо друг от друга. Клиентская часть создавалась как оптимизированная версия серверного компонента, переписанного с .NET на TypeScript.
Клиентская часть не уступает в сложности серверной. Кроме того, возникают дополнительные проблемы синхронизации состояний моделей на клиенте и сервере и глубокого тестирования клиент-серверного взаимодействия.
В этом докладе вы узнаете, как мы разрабатывали этот продукт, какие проблемы встретили и какие методики тестирования использовали.
Из доклада Вы узнаете как работают две основные буквы mVC. Controller. Каким образом запросы находят необходимые Action. Жизненный цикл объектов при запросах. Views. Что такое View, каким образом рисуется представление для frontend. Как написать свой ViewEngine.
Помимо этого - о том как хостится приложение, на сервере и как можно совместно использовать ресурсы для нескольких приложений либо масштабировать приложения по нескольким ресурсам.
Кросплатформенная разработка на ASP.NET vNextGoSharp
Из доклада вы узнаете о возможностях поддержки других платформ в ASP.NET vNEXT. На живом примере будет показано, как разворачивать ASP.NET под *nix и как программировать в этой среде.
Внедрение зависимостей в ASP.NET MVС и ASP.NET vNextGoSharp
По мере развития веб-проекта сложность бизнес-логики неизбежно растёт. Это замедляет темпы разработки, системы становятся непонятными и запутанными. Связной – не исключение. Одним из наших решений проблемы является Dependency Injection. В докладе вы узнаете о том, как DI понижает сложность бизнес-логики, почему мы в Связном считаем DI DI в ASP.NET MVC эффективным решением и что нового для DI появилось в ASP.NET vNext.
Платформа ASP.NET стоит на пороге глобальных изменений. Какие из них самые важные? Как они повлияют на процесс разработки? Стоит ли бояться и как подготовиться? В рамках доклада мы обсудим новый виток развития технологии и возможности, которые появятся у нас с выходом ASP.NET 5(vNext) и Visual Studio 2015.
Коучинг команд разработки и коучинговые инструменты в работе тимлидаGoSharp
Работа тимлида – самая трудная менеджерская работа. Он уже менеджер, его подчиненные еще нет, они не хотят и не обязаны вникать в его трудности. Ответственность уже есть, возможностей еще не так много. К этой работе редко готовят специально. Как и куда расти тимлиду? Это Вы узнаете в докладе. Какие навыки развивать. И как их развивать. Что такое коучинг команд и подойдет ли он в вашем случае. Всему можно научиться на практике, но воспользоваться чужим опытом быстрее и дешевле во многих случаях. Кстати, как определить, что именно вам чужой опыт не подойдет, вы тоже узнаете в докладе.
Взаимное влияние Source Code Management и других средств организации разработкиGoSharp
1. Почему важны не используемые инструменты, а модель организации работы и стратегия выпуска релизов.
2. Переход к более информативной истории изменений: от летописи разработки к истории развития продукта.
3. Связь между системами управления проектом и исходным кодом должна быть двусторонней.
4. Выбор разумной политики создания веток.
5. Хорошая архитектура и постоянное слияние делают непрерывную интеграцию более эффективной.
Толкование термина Devops и почему это модный buzzword
1. Гибкая эксплутация, по аналогии с гибкой разработкой и в качестве ее логичного продолжения.
2. Зачем это все нужно на примере интернет стартапа.
3. В *nix все хорошо, у Windows не очень.
4. Как сделать конвейер по доставке изменений начиная с комита разработчика и заканчивая обновлением программы-агента на машине пользователя.
5. Git и gitflow как норма рабочего процесса в команде.
6. CI - билды, ветки, артефакты.
7. Участие QA в процессе, автоматические тесты.
8. Octopus deploy и счастье. Октопаки в качестве контейнеров.
9. Мониторинг серверов и оповещения - New relic, Pager duty.
Доски проектов и продуктов на TFS: Agile-визуализация на уровне компанииGoSharp
Визуализация - основной практический инструмент Lean, Agile, TOC и прочих современных подходов к разработке программного обеспечения. Например, Task board отображает процесс разработки, помогая понять статус работ и заметить возможные проблемы, а Burndown отображает прогресс по обязательствам спринта, помогая реагировать на риски отставания. Такие инструменты визуализации применяют команды в конкретных проектах, но применима ли визуализация на уровне целой компании? Я расскажу о визуализации на основе Microsoft Team Foundation Server, которая помогает согласовать возможности разработки, ожидания бизнеса и стратегию компании - разработчика программного обеспечения, ведущей 50 проектов по развитию 20 продуктов.
Архитектурные решения при создании облачного сервиса на Asp.NetGoSharp
На конференциях часто рассказывают, как хорошо и удобно разрабатывать облачные приложения на той или иной платформе. Однако при реальной разработке возникают вопросы, которые обычно обходят стороной. В докладе я расскажу с какими неочевидными проблемами столкнулся при разработке сервиса под Microsoft Azure, и каким образом эти проблемы были решены.
Архитектурные решения при создании облачного сервиса на Asp.Net
Живые приложения с Rx
1.
2. Почему
Reac,ve
Extensions?
• Отзывчивость
приложений
• Упрощение
кода
работы
со
временем
• Упрощение
управления
потоками
• Упрощение
подписки-‐отписки
для
событий
• Тестируемость
кода
• LINQ
для
событий
и
потоков
данных
• Наличие
реализаций
для
других
языков
программирования
2
4. Преимущества
Rx
перед
событиями
• События
однопоточны.
Все
обработчики
будут
вызываться
по
очереди
в
потоке
который
запустил
событие.
• Если
в
одном
из
обработчиков
события
будет
выброшено
исключение
все
остальные
обработчики
не
будут
вызваны
• Все
подписки
на
события
необходимо
отписывать.
Для
этого
придется
хранить
ссылку
на
метод
для
отписки
и
объект
• Rx
поддерживает
async/await
для
запросов
требующих
ожидания
конкретного
элемента
• Rx
предоставляет
методы
для
управления
временем
и
потоками,
а
также
тестовые
реализации
управляющих
объектов.
• Rx
предоставляет
методы
для
связи
нескольких
потоков
данных
в
один
• Rx
предоставляет
возможность
обрабатывать
данные
аналогично
LINQ-‐запросу
в
функциональном
стиле.
4
6. Простой
класс
с
Rx
public
class
LogoutManager
{
public
IObservable<Unit>
Logout
{
get;
private
set;
}
public
IObserver<Unit>
UserActionsObserver
{
get;
private
set;
}
public
IObserver<Unit>
LogoutCommandsObserver
{
get;
private
set;
}
public
LogoutManager(TimeSpan
timeout)
{
var
userActionsSubject
=
new
Subject<Unit>();
var
logoutSubject
=
new
Subject<Unit>();
UserActionsObserver
=
userActionsSubject.AsObserver();
LogoutCommandsObserver
=
logoutSubject.AsObserver();
Logout
=
userActionsSubject
.StartWith(Unit.Default)
.Throttle(timeout)
.Merge(logoutSubject);
}
}
6
7. Потоки
данных
в
LogoutManager
Logout
=
userActionsSubject
.StartWith(Unit.Default)
.Throttle(timeout)
.Merge(logoutSubject);
7
8. Интеграция
Rx
с
существующими
событиями
• Короткая:
Observable.FromEventPattern(source,
"PropertyChanged");
• Типобезопасная:
Observable.FromEventPattern
<PropertyChangedEventHandler,PropertyChangedEventArgs>(
handler
=>
source.PropertyChanged
+=
handler,
handler
=>
source.PropertyChanged
-‐=
handler)
• Промежуточные
варианты
с
указанием
типов
только
для
части
операндов
8
11. Расширенный
фильтр
на
Rx
• Исходная
коллекция
также
может
меняться
• Пока
пользователь
продолжает
ввод
не
имеет
смысла
перезапускать
поиск
• Логика
фильтрации
может
быть
достаточно
сложна
и
отнимать
много
времени
• Пользователь
должен
видеть
результаты
по
мере
их
поступления,
а
не
после
завершения
фильтрации
• Пользователь
может
начать
вводить
фильтр,
а
затем
вернуть
старый.
Повторную
фильтрацию
при
этом
не
надо
запускать
11
12. Расширенный
фильтр
на
Rx
public
interface
IReactiveCollection<TItem>
:
INotifyPropertyChanged,
IDisposable
{
//
Источник
данных
(полная
коллекция)
TItem[]
Source
{
get;
set;
}
//
Отображаемая
часть
данных
(отфильтрованная
коллекция)
TItem[]
View
{
get;
}
//
Строка
фильтра
string
Filter
{
get;
set;
}
}
12
18. Проблемы
реализации
при
помощи
событий
• Необходимость
реализации
задержки
для
событий
–
для
того,
чтобы
не
загружать
списки
клиентов
и
счетов
много
раз
• Постоянные
подписки
и
отписки
на
события
элементов
коллекции
клиентов,
отсутствие
отписок
быстро
приведет
к
утечке
памяти
в
приложении.
• Код
для
управления
потоками
–
фильтрация
в
отдельном
потоке,
вывод
результатов
в
другом
18
19. Применение
фильтра
на
Rx
Companies
=
new
ReactiveCollection<Company>((x,
y)
=>
string.IsNullOrWhiteSpace(y)
||
x.Name.Contains(y))
{
Source
=
CompanyList
};
Clients
=
new
ReactiveCollection<Client>((x,
y)
=>
string.IsNullOrWhiteSpace(y)
||
x.Name.Contains(y));
Accounts
=
new
ReactiveCollection<Account>(SlowFilter);
private
bool
SlowFilter(Account
x,
string
y)
{
Thread.Sleep(random.Next(50,
250));
return
string.IsNullOrWhiteSpace(y)
||
x.Number.ToString().Contains(y);
}
19
21. А
что
с
тестированием?
• Управление
временем
• Управление
потоками
• Буферизация
• Скорость
выполнения
тестов
21
22. Тестирование
Rx
при
помощи
интерфейса
IScheduler
public
class
LogoutManager
{
public
IObservable<Unit>
Logout
{
get;
private
set;
}
public
IObserver<Unit>
UserActionsObserver
{
get;
private
set;
}
public
IObserver<Unit>
LogoutCommandsObserver
{
get;
private
set;
}
public
LogoutManager(TimeSpan
timeout,
)
{
var
userActionsSubject
=
new
Subject<Unit>();
var
logoutSubject
=
new
Subject<Unit>();
UserActionsObserver
=
userActionsSubject.AsObserver();
LogoutCommandsObserver
=
logoutSubject.AsObserver();
Logout
=
userActionsSubject.StartWith(Unit.Default)
.Throttle(timeout,
)
.Merge(logoutSubject);
}
public
LogoutManager(TimeSpan
timeout)
:
this(timeout,
Scheduler.Default)
{
}
}
IScheduler
scheduler
scheduler
22
23. Тестирование
Rx
[Test]
public
void
OnInactivity_Logout()
{
var
testScheduler
=
new
TestScheduler();
var
manager
=
new
LogoutManager(TimeSpan.FromMinutes(5),
testScheduler);
manager.Logout.Subscribe(_
=>
Assert.Pass());
testScheduler.AdvanceBy(TimeSpan.FromMinutes(6).Ticks);
Assert.Fail();
}
23
24. Тестирование
Rx
[Test]
public
void
OnActivityWithinThreshold_DoNotLogout()
{
var
testScheduler
=
new
TestScheduler();
var
manager
=
new
LogoutManager(TimeSpan.FromMinutes(5),
testScheduler);
manager.Logout.Subscribe(_
=>
Assert.Fail());
for
(var
i
=
0;
i
<
10;
i++)
{
manager.UserActionsObserver.OnNext(Unit.Default);
testScheduler.AdvanceBy(TimeSpan.FromMinutes(3).Ticks);
}
}
24
25. Тестирование
Rx
[Test]
public
void
OnActivityCommand_LogoutImmediately()
{
var
manager
=
new
LogoutManager(TimeSpan.FromMinutes(5));
manager.Logout.Subscribe(_
=>
Assert.Pass());
manager.LogoutCommandsObserver.OnNext(Unit.Default);
Assert.Fail();
}
25
27. Тестирование
Rx
[Test]
public
void
OnFilter_FilterView()
{
var
testScheduler
=
new
TestScheduler();
var
collection
=
new
ReactiveCollection<string>(
(x,
y)
=>
x.Contains(y),
testScheduler)
{
Source
=
new[]
{"client",
"bad
client",
"item",
"second
item"},
};
collection.Filter
=
"item";
testScheduler.Start();
Assert.IsTrue(new[]
{"item",
"second
item"}.SequenceEqual(collection.View));
}
27
28. Тестирование
Rx
[Test]
public
void
OnFilter_RunFiltrationInAnotherThread()
{
var
testScheduler
=
new
TestScheduler();
var
filterThreadId
=
0;
new
ReactiveCollection<int>((x,
y)
=>
{
filterThreadId
=
Thread.CurrentThread.ManagedThreadId;
return
true;
},
NewThreadScheduler.Default,
testScheduler,
testScheduler)
collection.Source
=
new
int[10];
testScheduler.Start();
Assert.AreNotEqual(Thread.CurrentThread.ManagedThreadId,
filterThreadId);
}
28
29. Тестирование
Rx
[Test]
public
void
OnSlowFilter_BufferResults()
{
var
testScheduler
=
new
TestScheduler();
var
filterCounter
=
0;
var
collection
=
new
ReactiveCollection<int>((x,
y)
=>
{
if
(++filterCounter%3
==
0)
testScheduler.Sleep(TimeSpan.FromMilliseconds(250).Ticks);
return
true;
},
testScheduler)
collection.Source
=
new
int[10];
collection.PropertyChangedAsObservable(x
=>
x.View)
.Take(3)
.Subscribe(x
=>
Assert.IsTrue(collection.View.Length%3
==
0));
testScheduler.Start();
Assert.AreEqual(10,
collection.View.Length);
}
29
30. Тестирование
Rx
[Test]
public
void
OnSourceChanged_CallFilter_EvenWithinThreshold()
{
var
testScheduler
=
new
TestScheduler();
var
filterCounter
=
0;
var
collection
=
new
ReactiveCollection<int>((x,
y)
=>
{
filterCounter++;
return
true;
},
testScheduler)
for
(var
i
=
0;
i
<
10;
i++)
{
collection.Source
=
new
int[1];
testScheduler.AdvanceBy(TimeSpan.FromMilliseconds(100).Ticks);
}
Assert.AreEqual(10,
filterCounter);
}
30
31. Тестирование
Rx
[Test]
public
void
OnSameFilter_DoNotCallFilter()
{
var
testScheduler
=
new
TestScheduler();
var
filterCounter
=
0;
var
collection
=
new
ReactiveCollection<int>((x,
y)
=>
{
filterCounter++;
return
true;
},
testScheduler)
collection.Source
=
new
int[1];
collection.Filter
=
"firstFilter";
testScheduler.AdvanceBy(TimeSpan.FromMilliseconds(250).Ticks);
filterCounter
=
0;
for
(var
i
=
0;
i
<
10;
i++)
{
collection.Filter
=
"secondFilter";
testScheduler.AdvanceBy(TimeSpan.FromMilliseconds(150).Ticks);
collection.Filter
=
"firstFilter";
testScheduler.AdvanceBy(TimeSpan.FromMilliseconds(250).Ticks);
}
Assert.AreEqual(0,
filterCounter);
}
31
32. Тестирование
Rx
[TestCase(100,
false)]
[TestCase(150,
false)]
[TestCase(250,
true)]
[TestCase(500,
true)]
public
void
OnMultipleChangesWithinThreshold_DoNotCallFilter(
int
threshold,
bool
runFilter)
{
var
testScheduler
=
new
TestScheduler();
var
filterCounter
=
0;
var
collection
=
new
ReactiveCollection<int>((x,
y)
=>
{
filterCounter++;
return
true;
},
testScheduler)
{Source
=
new
int[1]};
testScheduler.AdvanceBy(TimeSpan.FromMinutes(1).Ticks);
filterCounter
=
0;
for
(var
i
=
0;
i
<
10;
i++)
{
collection.Filter
+=
"filter";
testScheduler.AdvanceBy(TimeSpan.FromMilliseconds(threshold).Ticks);
}
if
(runFilter)
Assert.AreNotEqual(0,
filterCounter);
else
Assert.AreEqual(0,
filterCounter);
}
32