November 9th, 2009

glider

А где же посты?

В своем последнем мыле рассылки интересных вещей своим друзьям я пообещал, что в ближайшие пару недель тут будет дофига постов (и не безосновательно, ибо в моей knowledge base в гмыле за лето накопилось уже 200-300 записей, из которых где-то пятая часть содержит мои мысли, а не тупо ссылки на интересные вещи).

Дык вот, отвечая на вопрос в заголовке поста - все будет, причем начнем сегодня, надо только раскидать свою knowledge base и упорядочить все, что стоит запостить. Часть инфы будет на инглише, ее, наверное, переводить не буду.
glider

In-memory транзакции в хозяйстве и на отдыхе

Самая тривиальная ассоциация со словом "транзакция" это, конечно, база данных банка и перевод баблоса со счета на счет. В моск успешно въелись хелловорлды по транзакциям, чуть более, чем все из которых акцентируют внимание на атомарности. Но ограничивать использование транзакций исключительно такой пошлостью не стоит, ибо у этой концепции есть масса других красивых применений. Например, атомарность далеко не всегда самое полезное из свойств транзакций, да и durability в определенном контексте может быть совсем неактуальна.

Если мы абстрагируемся от деталей, то по факту транзакции обеспечивают удобную работу с данными. А так как самые близкие данные приложения находятся прямо в его адресном пространстве, то познавательно рассмотреть применимость транзакций, работающих с объектами в памяти.

Вот пример. Предположим, по бизнес-процессу надо пробежаться по нескольким скринам и на каждом что-то заполнить, выбрать и изменить. Увенчаться этот эффорт должен внесением изменений в сущности предметной области и сохранием всей пачки в базу. В мейнстриме такая задача решается стандартно. Интересные нам объекты грузятся из базы, пошагово изменяются в памяти и потом записываются обратно. Случись вдруг на одном из шагов ошибка - в базу ничего не запишется и все довольны.

Но все ли довольны? Скажем, пользователь вдруг захотел отменить свои действия на последнем шаге. Или, что если по нажатию какой-нибудь кнопки к БД отправляются несколько запросов, по ходу меняющих состояние объектов в памяти, а посередине падает исключение? Выкидывать изменения в мусор и перегружать объекты из базы не самая лучшая идея, потому что к времени перезагрузки версия объектов в базе может поменяться, а это ставит под угрозу целостность данных. Ручное восстановление объектов по состоянию GUI муторно и чревато ошибками.

Решением может быть вынесение шагов процесса в in-memory транзакции, которые в силу журналируемости предоставляют нам прекрасные возможности отката. So far so good, но как это реализовать? Я могу предложить три подхода к решению такой проблемы.

Первый из них топорный - клонирование всех интересных нам объектов (кстати, точное определение такого множества интересных объектов - нетривиальная задача) перед началом транзакции и, в случае чего, откат к исходному состоянию. Минусы очевидны - расход памяти и слишком грубая гранулярность отката. Зато, в отличие от варианта с обращением БД, данные всегда будут согласованы друг с другом. Но все же минусы весьма серьезные, поэтому обратимся к альтернативам.

Другой способ - выделение операций с объектами предметной области в команды. Из плюсов отметим отличную гранулярность и, как следствие, возможность интеллектуального анализа и оптимизации последовательности команд (например, из всех изменений некоторого свойства можно оставить только последнее или, возможно, несколько подряд идущих команд можно объединить в единственную эквивалентную). Также в плюсы можно записать то, что однажды написанные команды можно заюзать в GUI. Из минусов - от разработчика требуется неслабое терпение и внимательность ибо надо полностью все(!) модификации объектов выразить в командах, кроме того нарушается связность доменной логики и генерируется куча мусора в коде.

Напоследок я оставил то, ради чего и писался этот пост. Этот солюшен далеко не универсален, но в своей области применимости он легко уделывает предыдущие два. Встретил я его на сайте тулзы DejaVu, хотя идея восходит корнями еще к STM. Вкратце смысл в том, что все данные, которые могут поменяться (абсолютно все - категоричность прямо как в случае с командами) мы жестоко инкапсулируем в прокси (ессно, это требование можно облегчить кодогенерацией, но сейчас не об этом).
Copy Source | Copy HTML
private readonly UndoRedo<String> _firstName = new UndoRedo<String>(null);
public String FirstName
{
  get { return firstName.Value; }
  set { firstName.Value = value; }
}

Дальше, собственно, все понятно - если нам удалось обернуть все потенциально мутабельные данные, то на любой момент времени можно максимально точно узнать, что изменилось и как это что-то откатить, причем любые операции с данными трекаются одинаково хорошо. Да, в отличие от солюшена с командами, гранулярность невысокая, т.е. мы не сможем откатывать лишь отдельные фрагменты транзакции, но не это главное. Кроме того, в честь использования прокси мы получаем пачку бесплатного функционала, например, нотификации OnChanging/OnChanged.

P.S. Их хороших новостей. Проделав работу по вычленению изменяемых кусочков наших данных и упорядочению доступа к ним, мы в одном шаге от реализации многопоточности. Всего навсего остается прикрутить к этим кусочкам локинг. А так как транзакции сами по себе являются способом объединить логически связанный код, мы нахаляву получаем поддержку гибкой гранулярности локов. Ну а если повезло заюзать солюшен номер 3, то уже практически написан STM, который inherently потокобезопасен.
glider

Удобный тул для заметок и баз знаний

Идею юзать OneNote мне подкинул Ваня (mechanism_by) еще пару лет назад, но тогда это было не вовремя. Для меня эта идея стала актуальной только недавно, когда я поступил в аспирантуру и начал вести базу знаний проекта (кстати, о нем на днях будет пост). В качестве эксперимента я решил подъюзать OneNote ибо контент, который я генерил, потом надо было шарить с коллегами. В процессе я разогнался и привык делать там повседневные заметки об ad-hoc идеях и отмечать интересные моменты в поступающей информации. А вот сегодня закончил миграцию своей основной базы знаний из противоестественного формата - почтового ящика gmail.

Рискну предположить, что OneNote будет полезен для всех, кто занимается какими-то проектами (лабы, курсачи, работа), ведет заметки на бумаге или хочеть запечатлеть памятные моменты на носителе понадежнее мозга. Но тут есть одна проблема. Обычно, даже если тул очень классный, то начать юзать новый подход не так просто, ибо временно надо перейти в режим выработки новых привычек, а не всегда на это есть мозговые силы. Чтобы облегчить этот процесс тем, кто заинтересуется, я решил отпоститься о том, как обычно юзаю сабжевый тул.

1) Делаю что-то за компом, проснулось желание записать нечто (возможно, не связанное с текущей деятельностью). Нажимаю Win+Shift+N, выскакивает ВанНоут, представляющий собой набор ноутбуков, каждый из которых содержит набор закладок, каждая из которых содержит набор страниц. Навигируюсь в нужное место и пишу текст, при необходимости вставляю линки, картинго, вроде бы даже можно аттачить файлы. Время, потраченное на переключение контекстов с текущей задачи и обратно - 2-3 секунды навигации по ВанНоуту + пару секунд написания заметки, что качественно отличается от всего, что я пробовал раньше.

2) Юзаю прогу или сижу на сайте. Проснулось желание дословно зафиксировать увиденное. Нажимаю Win+S и мышкой выделяю область экрана, которая мне интересна. Делается скриншот этого куска экрана и далее я его помещаю в нужный мне ноутбук.

3) Надо расшарить знания между рабочим и домашним компами или поделиться с кем-то. Есть три варианта - 1) сохранить ноутбук или любую его логическую единицу в виде файла и послать его по мылу, 2) сконвертировать штуки из пункта 1 в файлики mht, тогда их можно прочитать, но не отредактировать, 3) запаблишить в виде сайта вот этим тулом: http://blogs.msdn.com/davidtse/archive/2007/07/08/onenote-web-exporter-v0-5-0-is-released.aspx (сайт не сильно чтобы классно сделан, но юзать можно). Походу, можно даже юзать OneNote для коллаборации, смотреть и мержить изменения, но сам я эту штуку не пробовал, но вот ли

Пример. Щяс я пешу потсы для бложека, до сегодняшнего дня хранил их в доках. Это удобно, но в процессе замечаешь недостатки. 1) Что делать, если надо сделать ссылку на еще не опубликованный пост, 2) что делать, если надо часто переключаться между документами, 3) что делать, если надо сделать какие-то заметки, но писать их в теле потса не хочется, чтобы не мозолить глаза. С утра назад мигрировал набор документов + заметки на бумаге в ноутбук ВанНоута и что могу сказать. 1) Появилась целостность, 2) удобно навигироваться, 3) когда приходит в голову мысль, нажимаешь Win+Shift+N, выбираешь нужную закладку и пишешь (от желания до реализации проходит 1-2 секунды, это качественно новый уровень по сравнению со всем, что я юзал раньше).