2/11/2010 12:07:42 PM

Вышли релиз-кандидаты Visual Studio 2010 и TFS 2010. Поставил, смотрю…

Про “студию” могу сказать пока только то, что работать стала существенно быстрее, чем прошлая Beta2. Предыдущая версия своей производительностью, признаться, наводила на мысль о том, не пошло ли использование WPF в ущерб. Однако, теперь этого ощущения нет. Работает не медленнее 2008-й – это точно.

А вот TFS стоит отметить отдельно. Устанавливать его теперь гораздо приятнее, чем его 2008-го предка, с которым ещё намучаешься устанавливая, да и немало (помню, как в Алкателе сидел до 10 вечера, выполняя установочные инструкции по шагам).
Установка же 2010-й версии проста и даже примитивна. Два этапа: собственно, установка, которая занимает всего пару минут, и конфигурация в визарде, что тоже занимает примерно столько же времени.
Сразу скажу, что я пробовал только Basic конфигурацию (там есть ещё пара вариантов), так как устанавливал на локальную машину. Приятно, что в Basic-варианте работает и билд сервис, и даже web access, и при этом ему не нужно ничего, что начинается с “Sharepoint”. И работает даже с SQL Server Express.
Поставил – и работай. Просто, удобно, как и хотелось.

Много всяких интересных штук там, в TFS 2010, но я хочу отметить две:

  1. Билд-сервисы:
    • На одной машине можно без хаков иметь несколько build-агентов, что не может не радовать;
    • Билд-скрипт, который был раньше MSBuild-проектом, теперь представляет собой Workflow. Редактировать его в Workflow-дизайнере, добавлять и даже создавать свои собственные задачи теперь гораздо удобнее и приятнее.
  2. Gated Check-Ins.
    Здесь я, признаться, в замешательстве. Поясню: Gated check-in – это когда разработчик делает check-in в репозиторий, при этом выполняется build, если хотите – прогон unit test’ов, и если что-то пошло не так, то внесённое изменение отвергается и не попадает в систему контроля версий. А если всё прошло как надо, то изменение попадает в соурс контрол, конечно. Соответственно, в соурс контроле мы имеем ветку, которая никогда не будет сломана и всегда будет как минимум компилироваться, а как максимум – зависит от вашего покрытия юнит тестами.

Так вот, Gated Check-Ins работают в TFS2010 замечательно, билд никогда не ломается и всё такое. Но есть у меня одно недопонимание, одна фича, которую, как я надеялся, исправят после Beta2, но она осталась…

Выглядит это так:

  1. Я изменяю код и делаю check-in.
  2. Поскольку мои изменения, пока не прошла валидация, де-факто не попадают в репозиторий, я всё ещё вижу изменённые файлы как checked-out.
  3. Билд и юнит-тесты проходят успешно, код попадает в репозиторий.
  4. Здесь я ожидаю, что файлы станут checked-in, если я их больше не трогал. Онако, этого не происходит.
  5. Я пытаюсь делать Get Latest Version или Check In снова, не важно что из этого.
  6. TFS, внимание, заявляет, что у меня локально присутствует версия файла #7, а в репозитории она уже #9 (очевидно, #8-это мой промежуточный check-in, #9 – финальный после валидации).
  7. Мне необходимо сделать merge версий 7 и 9! Хотя, ежу понятно, что они одинаковы, ибо это изменение делал я, только я и никто больше!
  8. Я признаю, что merge в VS2010 и в VS2008 – вещи очень и очень разные в пользу VS2010, там надо нажать ровно одну кнопку, даже никаких всплывающих окон, но сам факт… И так, делаю auto merge, всё проходит отлично, так как нет разницы, но файлы-то остаются в состоянии checked out!
  9. Я должен снова сделать check-in, и тогда оно мне скажет: изменений нет. И пометит файлы как checked in, чего мне и хотелось.

Звучит, возможно, сложнее, чем есть на деле, но вы попробуйте :)

Я понимаю, что это, наверное, достаточно сложно – отследить, что я действительно не менял файлов пока шла валидация, поэтому нельзя просто сделать их checked out когда она закончена.. Ну, вдруг я менял.
Я понимаю, что в общем случае при таком вот “отложенном” check-in может возникнуть automerge от нескольких разработчиков и в этом случае нужно просить делать merge…
Но я не понимаю, разве нельзя было ввести ещё один статус “в процессе валидации" для файлов в солюшн эксплорере? И “сбрасывать” его обратно в “checked out” если я меняю эти файлы? Пусть даже и на основе read-only атрибута в файловой системе?
Разве нельзя отследить, что во всём этом процессе вот для этого конкретного файла не было никакого автоматического merge’а сделано на уровне TFS? И не просить меня делать merge если файл не меняли ни локально, ни в TFS?
Во всех остальных случаях – спрашивайте, пожалуйста, я только рад буду и буду делать merge с удовольствием!

Короче, тут можно, конечно задать вопрос “Вам шашечки или ехать?”, и утверждать, что целостность билда важнее всех этих мелких неудобств.. Но ведь хочется, чтобы и их не было… :)

В общем, пока как-то так…

1/22/2010 1:39:36 PM

Большое количество проблем, связанных с производительностью SQL Server на больших данных так или иначе упираются в IO. В нашем случае, когда речь идёт о действительно больших объёмах, это ощущается по полной программе. Для примера, маленькая дивелоперская база данных, используемая локально на моей машине, занимает сейчас чуть менее 14 гигабайт. Это так, считай ничего, локально фичи писать/отлаживать.

На моей рабочей машине установлено “всего” 12 гигабайт памяти, из которых SQL Server’у разрешено использовать 6. Поэтому, понятное дело, о полном кешировании базы в памяти речь идти не может. Да и, думаю, редко где такая возможность существует.

И вот тут мы упираемся в IO. Особенно на scan’ах.

Решать эту проблему можно двумя путями:

1) Грамотным построением SAN’а (Storage Access Network, всё имеющееся дисковое пространство), умным разбиением оного на LUN’ы (Logical Unit Number, логическая группа физических дисков), объединение LUN’ов в соответствующие задачам RAID’ы, распределением по ним файлов базы данных и т.д, что позволяет добиться отличных результатов за счёт параллельной работы дискового массива;

2) Настройкой и распределением самой базы данных SQL Server.

Сразу скажу, что 1 и 2 не исключают друг друга, наоборот, гармонично дополняют и всячески сопутсвуют.
Далее я буду говорить только о втором пункте, потому как первое – это работа администратора, в этом я не силён. Кроме того, часто бывает так, что конфигурацию “железа” особо выбирать не приходится (либо уже настроено на максимум), а производительность повысить надо.
В любом случае, не пользоваться возможностями SQL Server’а по оптимизации смысла нет.

Для оченки производительности именно в разрезе IO я перед каждым запросом делаю DBCC DROPCLEANBUFFERS, чтобы очистить clean buffers, которые в SQL Server являются кешем прочитанных с диска страниц в памяти.

Для начала – краткое и простое (без углублений) пояснение того, откуда и как вообще берётся нагрузка на диски.

SQL Server читает с диска данные так называемыми “страницами” по 8 килобайт. На каждой такой странице находится какое-то количество строк. Столько, сколько может уместиться на 8-килобайтовой странице. Соответственно, даже если требуется “выдать” всего одну строку, SQL Server прочитает с диска минимум страницу.
С другой стороны, чем больше строк “умещается” на страницу, тем меньшее количество раз SQL Server’у нужно обратиться к диску для получения результата.
Здесь мы приходим к важному:

  • Размер имеет значение.

Часто работая с кодом, мы не придаём значения размеру типов переменных: long, int, byte – какая разница. В большинстве случаев это действительно так – разницы никакой. Но в случае с SQL Server всё иначе, здесь размер действительно имеет значение. Ибо, скажем, bigint занимает места в 2 раза больше, чем int, соответственно, данных с колонкой типа bigint на страницу поместится в два раза меньше, чем данных с колонкой типа int, что означает, что для чтения одного и того же набора данных SQL Server’у потребуется прочитать в 2 раза больше страниц. То есть – мы имеем в 2 раза большую нагрузку на диски (IO).
Так и с другими типами данных. Именно поэтому SQL Server и имеет всякие разные настройки точности типов, вроде datetime2(4) и т.д.
Это не значит, что надо бросаться переделывать все bigint на int, это значит, что в данном случае о размерности типов надо думать.

Говоря об IO, в общем-то, вся задача сводится к одному простому вопросу: как заставить SQL Server читать с диска меньше страниц (про “читать быстрее”, повторюсь, речь не идёт)?

Про “умещать на страницу больше данных” с помощью “правильного” выбора типов колонок я уже сказал, однако SQL Server (начиная с 2005 и в Enterprise версии, насколько я помню)  предлагает и ещё один вариант:

  • Компрессия данных.

Существует два вида компрессии: Page (на уровне страниц) и Row (на уровне строк). Они друг от друга сильно отличаются.

Row-компрессия представляет собой “классический” вариант сжатия с помощью архивирования. Проще говоря, данные в строке сжимаются с помощью deflate (тут не уверен, кстати, может и не им), соответственно, в сжатом виде на 8-килобайтовую страницу “влезает” больше строк.

Page-компрессия представляет собой некий “справочник” в заголовке страницы, в котором записывается, что такое-то значение встречается в таком-то столбце столько-то раз. Соответственно, само повторяющееся значение сохраняется всего один раз вместо того, чтобы хранить его в каждой ячейке. Никакого архивирования при этом не происходит, но, опять же,  за счёт того, что не надо хранить повторяющиеся значения, на страницу умещается больше данных.

Забавно, но во всех случаях, которые я видел, Page-компрессия “сжимала” данные лучше, чем Row-компрессия. Хотя я, признаться, ожидал обратного. Коэфициент сжатия сильно зависит от самих данных, конечно. У меня получалось по-разному: бывало и 25-30%, а бывало и 70%…
Попробовать и оценить можно прямо из Management Studio – когда делаете компрессию там есть кнопочка “посчитать”. Или можно просто системной процедурой воспользоваться, названия не помню (дома я).

Уместить на страницу “да побольше, побольше” – это половина решения. Вторая половина заключается в том, что и как туда умещать.
Ну вот представьте, мы выбираем из таблицы Orders все записи, сделанные для компании VPupkin LTD. SQL Server читает, он читает постранично, он всегда так делает. На первой (подходящей, допустим сервер знает какие страницы надо читать и где есть интересующая нас информация) странице у нас одна нужная запись, на второй – ещё одна, на четвёртой – две и ещё одна на шестой. SQL Server вынужден прочитать с диска страницы 1,2,4 и 6. И совершенно не важно, что на каждой из этих страниц ещё по 196 записей, которые к нашему запросу отношения не имеют.
Отсюда вопрос: как бы сделать так, чтобы интересующие нас записи располагались “рядышком”, а не “расползались” по всему файлу данных?
И на это есть хороший ответ:

  • Создание разделов (партиций)

По-моему эта штука доступна тоже только в Enterprise-версии, но я не уверен.
Смысл её состоит в том, что для какой-либо таблицы мы можем задать несколько разделов (партиций, я буду писать “партиций”, не привык я к “разделам”) и указать критерий, по которому SQL Server будет решать, в какую именно партицию попадёт запись.

То есть, буквально, мы просто говорим SQL Server’у: все Orders для компаний с ID от 1 до 100 – в эту партицию, а от 100-200 – вон в ту. Таким образом мы создаём некую физическую группировку данных, то есть, при наличии, скажем, 10 партиций заказы одной компании будут находиться в одной пратиции => “раскиданы” по 1/10 таблицы, а не по всей, => в 10 раз увеличивается плотность заказов одной компании => меньшее количество страниц нужно будет считать с диска.

К тому же SQL Server достаточно умён для того, чтобы понять: раз все записи для указанной компании находятся на одной партиции, то во все другие вообще смотреть не надо, в запросе учавствует только кусок таблицы. В 10 раз меньше данных.
Ну и существует синтаксис для того, чтобы явно обратиться к какой-то одной партиции и сделать запрос только к её данным, существует возможность для определения, в какой именно партиции лежат интересующие данные, если мы хотим обратиться к ней явно и т.д. и т.п.

При всём вышесказанном, таблица продолжает оставаться целой таблицей во всех её проявлениях, “извне” ничего не меняется, что просто замечательно.

При разбиении таблицы на партиции для каждой из них можно указать файловую группу, то есть, это таки способ “распределить” таблицу по разным дискам.

Ещё одна замечательная открывающаяся возможность – это паралеллизм. SQL Server, выполняя запрос, в котором учавствует такая “разбитая” таблица, оптимизирует работу, выполняя запрос к каждой партиции параллельно. Это очень существенно уменьшает время выполнения запроса, особенно на scan’ах. Даже если файловые группы партиций находятся на одном физическом диске, видимо, за счёт “группировки” на страницах и этого самого паралеллизма.
В цифрах: у меня есть запрос, выполняющийся за 1 минуту 09 секунд. После разбивки таблицы (для теста, на глазок) всего на 5 партиций, находящихся на одном физическом диске (том же, другого у меня нет), время выполнения запроса сократилось до 40 секунд.

Максимальное число партиций – 1000 на одну таблицу. По словам человека из Microsoft – цифра взята “с потолка”, надо же было какое-то ограничение придумать :)

Теперь об “побочных эффектах”.

В смысле разбиения по партициям – никакого отрицательного побочного эффекта, в общем-то, и нет. Есть ещё несколько интересных возможностей, такие, как staging-таблицы, например, но я и не работал с этим, да и не по теме несколько.

В контексте компрессии overhead есть – это +3-4% CPU на упаковку/распаковку. Впрочем, как показывает опыт, SQL Server достаточно редко “ест” CPU так, что не найти “лишних” 4%, а уж если мы уткнулись в проблемы с IO – то уж CPU-то гарантировано свободен.
И ещё. К сожалению, ни один из видов компрессии не получится использовать на таблицах, в которых есть sparse columns.

10/31/2009 10:46:00 AM

В Сидней приезжает Тори Амос (Tori Amos). Будет выступать в главном зале знаменитой сиднейской оперы.
Ещё давно, несколько месяцев, наверное, назад были успешно куплены билеты и оставалось только ждать этой даты – 17-го ноября.

Однако, совершенно неожиданно с этой датой совпало проведение PDC (Professional Developers Conference). Точнее, неожиданностью оказалась не дата проведения конференции, а тот факт, что я на неё попадаю. Тем не менее, завтра с утра у меня интервью в американском консульстве на предмет получения визы, и если всё сложится удачно, то на концерт Тори Амос я, к сожалению не попадаю.

На работе смеются – для австрала персональное интервью в консульстве перед поездкой куда-то выглядит крайне забавно и необычно. Интересуются “а зачем”, “а страшно ли”, “а что там спрашивают”, удивляются.

Ничего всё это я уже проходил при получении первой британской визы (вот как раз факт того, что я был в Британии я и забыл указать в анкете, надеюсь простят), на вопрос “let me see the conference program” ответить смогу.

А австралы, кстати, тоже регистрируются где-то по какой-то визовой программе, не просто так едут. Ходить им, конечно, никуда не надо, но, видимо, какая-то электронная регистрация у них всё же есть. Ну а отпечатки пальцев снимать и фотографировать лица будут у всех одинаково :) Ну, за исключением босса – он хотя и не гражданин Австралии оказался, но канадец, а посему въезд в США для него свободный.

Вот. В Лос Анджелесе я ещё не был. Надеюсь, у них там в далёкой Америке есть интернет, напишу, оттуда, что там и как :) Уже договорился, что на время поездки мне выдадут другой, более лёгкий ноутбук…

Но 13.5 часов в самолёте! Это, я вам скажу, похлеще, чем в Австралию из России лететь. Тут придётся честно все 13.5 часов отвисеть в воздухе, тогда как перелёт в Австралию хоть и занимает 17-19 часов, но с отдыхом посередине этого временного отрезка! В прошлый раз было так неплохо поспать ночь в Японии в хорошем таком отеле, который, кстати, предоставлялся бесплатно. А тут 13.5 часов в воздухе. Мрак. Хорошо хоть ночью летим, надо будет не выспаться наконуне.

Программу конференции ещё не смотрел, оставил на “после получения визы”, но меня уже зарегистрировали на пред-конференционную сессию по теме “шаблоны параллельного программирования” (это надо было сразу выбирать, ибо оплачивается отдельно).

В общем, каждый раз после проведения PDC я смотрел видео доклады в интернете (очень советую) и каждый раз думал, что обязательно надо собраться как-нибудь и съездить. Ибо ролики – это одно, а личное присутствие – совсем другое, что бы там ни говорили те, кто всегда смотрит и никогда не присутствовал, это я по TechEd и ReMix знаю :)

Вот, представился шанс…

7/24/2009 5:56:39 PM

Подписали билды Windows 7 и Windows Server 2008 RC2. Следовательно, релиз состоялся. По плану и даже чуть раньше. Прогнозы “аналитиков” о том, что делать будут “аж до хрен знает когда, раз Висту так задержали” не оправдались.

7/24/2009 5:59:00 AM

Прислали ссылку: http://habrahabr.ru/blogs/silverlight/65191/

Почитал новость, потом комментарии к оной.
Самое смешное это, конечно, как всегда комментарии линуксоидов. “Я отнюдь не за распространение этой технологии”, как красиво и смешно сказано! Отож, призрак Microsoft маячит за “технологией”, ничего, что mono-ребята реализовывали всё open source и с нуля по спецификациям. И призрак этот ну просто откровенно мешает людям жить! Поэтому технологию, конечно, распространять не надо.
Смешно.

Причем проблемы себе создают сами.
- Попробуйте установить мунлайт? Работает.
- Какой дистрибутив, какой репозиторий?

Ужас. То, что в цивилизованном мире делается совершенно неподготовленным пользователем с помощью одного клика по большому баннеру “сильверлайт”, в однопроцентном мире требует знания понятий “дистрибутив”, “репозиторий”, понимания разницы между различными репозиториями и т.д. Ужас.

По-моему же проблема ситуация формулируется гораздо проще даже безо всяких допущений, сгребём всех в одну коробку: не работает на одном проценте клиентских машин, у пользователей которые всё равно параллельно установлена виндовс в качестве операционной системы, куда они и переключаются, устав от бесконечного “администрирования” (ух, Линукс настроил, а что с ним дальше делать?) для решения реальных задач (от “поиграть” до “курсовик допинать”).
Решение проблемы ситуации: да и хрен с ними! :) У кого заработает (как они говорят “руки из того места растут”) – хорошо, остальные – хрен с ними. Ибо их всё равно в разы меньше чем тех, кто тупо отключает Javascript в браузерах. Статистически, а статистика - вещь упрямая. Поэтому глупо притягивать за уши HTML5+JS к Сильвер/Мунлайту.

P.S. Про призрак. Недавно прочитал, MS планирует опубликовать в основную ветку ядра Линукса несколько тысяч строк кода различных дополнений. Интересно, эти чистые душою и идеологией люди перестанут пользоваться некошерной и осквернённой веткой ядра? :)

P.P.S. Поставил Silverlight 3 на Mac OS X. Просто, ради посмотреть, как оно там живёт. Живёт оно точно так же: нажал кнопарь – установилось. Отлично показываются видеоролики и всё остальное. Про “репозиторий” и “дистрибутив” меня никто не спросил. Всё просто работает. И, что показательно, выбор между HTML5+JS и сильверлайтом делать не заставляют.
Бедные однопроцентники, даже жалко их :) Мыши плакали, кололись, но продолжали есть кактус, не иначе…

7/6/2009 12:28:00 PM

Что получается...

Когда я жил в Костроме, у меня было модемное подключение. По тарифу мне полагалось 100 мегабайт входящего трафика. Один мегабайт тогда скачивался у меня за шесть минут, помню.
Когда как получалось: когда перебирал немного, когда недобирал этот трафик. Чаще недобирал...

Потом мы переехали в Санкт-Петербург (это Питер который). Там у нас появилось интернет-соединение со скоростью 1 мегабит в секунду. А в тариф был включен 1 гигабайт трафика. Это был целый гигабайт! Можно было включить картинки в браузере (в Костроме они всегда были отключены с целью экономии трафика и повышения производительности). Сейчас, конечно, смешно вспоминать - интернет с отключенными картинками :) Но ощущения тогда были... Все выглядит по-новому, красочно! Куда трафик девать - непонятно, а "не девать" его - жалко. Оплачено же :) Потом так и было - поначалу старались выкачать все чуть ли не до байта, потом плюнули считать. Иногда перерасходовали, чаще - недобирали.

Через год мы переехали в Бельгию. Мы с коллегой поселились в одном доме, в одном подъезде, с разницей в несколько этажей. Так у нас появилась собственная беспроводная сеть. Мы напополам купили роутер, оформили подключение на мой адрес. Это был 4-х (после двух лет стал 8-ми) мегабитный канал; по тарифу нам полагалось 15 гигабайт трафика. На двоих, но что делать с 7.5 гигабайтами ни я после Питера, ни он после Челябинска не знали. Однако "втянулись". Сначала старались выбирать положеную нам квоту, потом устали от этого занятия. Евро-другой ничего не меняют (а гигабайт "сверху" стоил как раз евро). Иногда приходилось доплачивать, а иногда и нет. За статистикой уже никто не следил.
Потом коллега, узнав о моем переезде в Австралию, подключил себе собственный интернет, так что на нашу долю перепали все 15 гигабайт. Та же история. Прижились, иногда укладывались, редко - нет...

Переехав в Австралию я подключился на тариф, которого я даже не хотел. Шутка ли: 15 гигабайт дневного трафика и 20 гигабайт - ночного. Я говорю жене: "я понимаю, куда девать 15 дневного, но нафига нам 20 ночного?! Ночью я сплю!". Но выбор не велик, так и повелось.
Вот, живу в Сиднее уже без двух недель год. (Ого, год! Я еще от Бельгии не отвык, тут все еще в новинку, а уже год прошел! Вроде таааак тянулся, а тут бац!). Бывало, конечно, что трафика не хватало. Но редко.
А пару месяцев назад жена настоятельно предложила за дополнительные 10 долларов перейти на тариф "30 гигабайт дневного и 30 гигабайт ночного трафика". Я ей говорю: "Лена! Нафига нам в 2 раза больше дневного?! Солить, чтоли?! Про ночной я вообще молчу! 20 выбираем иногда - ну и хватает же!".
Значится, привел убедительные аргументы. Я же мертвого уговорить могу выйти из могилы и сплясать :)
Короче, полез я на сайт провайдера и перешли мы на этот тариф. Попутно я еще ползунок там нашел, регулирующий скорость... Стоял на половине.. Выкрутил его сначала на три четверти, потом полностью. Пусть. Сказано "аж до 20 с чем-то мегабит в секунду" - пусть будет.

Интересная штука - этот интернет. Расчетный месяц заканчивается у нас 13-го числа. На текущий момент скачано уже 92% дневного трафика и где-то 89-90% ночного.
Забавно. Получается, что ощущения удовлетворенности интернетом и потребности в его использовании от цифры не зависят. Адаптируются они к цифре как-то. Потому как при любом значении допустимой нормы она иногда перерасходуется, чаще не добирается...
А пользователь остается одинаково доволен! Во как...

7/2/2009 4:20:12 PM

Как-то нужно стало стандартизировать работу с бранчами. Ну, чтобы не кто как хочет, а чтобы была какая-то общая стратегия. Которая, впрочем, оставляла бы и достаточно свободы разработчику.

Пока думаю о следующем:

  1. Development Branch (Trunk/Main).
    Основная, с точки зрения разработчика, ветка. В эту ветку допускаются… check ins, commits, как это по-русски… “чекины” буду говорить. Так вот, в эту ветку допускаются чекины изменений, который с точки зрения разработчика готовы к тестированию. Кроме того, здесь фиксятся баги, найденные тестерами.
    Поэтому с точки зрения тестера эта ветка – самая нестабильная в проекте, первый этап.
  2. Feature Branches (Trunk/<FeatureName>).
    Это ветки (“песочницы”, как любил говорить мой бывший коллега) разработчиков. Каждый разработчик, или группа товарищей, могут создавать себе таких веток столько, отпочковывая их от Trunk/Main, сколько им нужно. Предполагается, что в такой ветке идёт разработка какой-то фичи, новой функциональности. Когда разработчики считают, что фича готова, прошли тесты и код-ревью (у кого есть, завидую) и всё такое – они сливают свою ветку обратно с Trunk/Main, отмечают работу как “готова к тестированию” и фича переходит в руки тестеров.
  3. UAT (User Acceptance Test) Branch.
    Бета, так сказать. Стабильная, уже с точки зрения тестеров, ветка. Как туда попадают фичи – отдельный разговор. Ну, например. В случае “классического” итерационного процесса (любой Agile) завершение итерации знаменуется достижением поставленных для данной итерации задач. “Достижение” – это когда фичи сделаны и тестеры довольны. И вот тут мы можем слить изменения из DEV в UAT.
    Либо же изменения вливаются “пофичево”. Фичу оттестировали на DEV – слили в UAT. Это требует больше усилий, правда. И иногда может оказаться не совсем возможным.
    Предмет разговоров, короче. Самое интересное место.
  4. Release Branches (Release/<ReleaseName>).
    Стабильные, релизные ветки. Здесь всё просто: то, что прошло UAT время от времени назначается релизом. Например, когда достигнуты все цели, поставленные перед релизом, то есть, сделаны и оттестированы все необходимые фичи.
    Делается ветка для этого релиза, которая никогда больше не будет ни с чем сливаться, ни в одну, ни в другую сторону.
    Зачем тогда ветка? А просто потому, что там тоже могут оказаться баги :) Которые может быть нужно срочно пофиксить. И тогда это фиксится прямо в ветке текущего релиза. И никуда не сливается. Просто потому, что разработка идёт дальше и как сам баг, так и его фикс уже могут просто не иметь смысла в контексте текущей разработки.
    К тому же фикс в релизе может означать просто какую-то заглушку, какой-то, скажем прямо, хак. В то время, как в дивелоперской ветке этот баг, если он там имеет смысл, фиксится уже со всеми необходимыми рефакторингами и т.д.

С точки зрения “сливания” тоже получается, вроде, неплохо, однонаправленно.
Ветки разработчиков вливаются в DEV (хотя они могут и DEV в свою ветку слить, почему нет, это их право). Дальше всё строже: DEV сливается на UAT только в одну сторону. Поэтому с конфликтами тут всё очень и очень просто – их не должно быть, ибо никакой разработки в UAT не ведётся.

С релизными же ветками вообще никаких конфликтов, ибо они только бранчатся и никогда ни с кем не сливаются.

А как с этим у вас? Какие подходы применяются?

6/29/2009 12:20:12 PM

Ну вот, разобрался с последней “проблемой” WHS – сделал его тихим.

Купил такой вот кулер на eBay:

Scythe Infinity Scythe Infinity

“Scythe Infinity” он называется. Кулер, конечно, огромный, пропеллер, который на картинке – он 120-миллиметровый. Занял половину корпуса у меня. Сейчас подумал – винты добавлять будет проблематично, наверное. Снимать надо будет, а потом снова вешать, иначе, наверное, просто не запихаешь.

Пропеллер я снял.
Во-первых он б.у. и еле слышно гудит.
Во-вторых, подумал я, при таком радиаторе и такой нагрузке на процессор, как у WHS, он там совершенно не нужен.
Ну а в третьих кулер находится прямо напротив системного пропеллера, который тоже 120мм и который работает там на низких оборотах. Сантиметра два между ними. И его там отлично продувает.

Итак, кулер стал бесшумным, диски на резиновых прокладках, а остальное (вентилятор на блоке питания и системный) почему-то не шумит совсем. Приятно. Захожу в комнату-кабинет, прислушиваюсь, стараясь уловить звуки жизнедеятельности WHS, но слышу только что-то с улицы :) Чего и хотелось.

Последняя “проблема” решена.
Ну, может еще придумать какую-то пластину, чтобы синий светодиод не светил по ночам (кто-то же догадался на черном корпусе подсветить кнопку “вкл” по кругу). Но поскольку в той комнате всё равно пока никто не спит (и вообще заходят редко), то в ранг “проблемы” это пока не попадает :)

6/25/2009 2:34:06 PM

Зашел тут как-то спор на работе по поводу юнит-тестов. Спорили-спорили. Интересно, но все остались при своих. Полез смотреть в интернет, оказывается есть два “лагеря”, которые никак не могут примириться.

Проблема простая: тестировать или не тестировать приватные методы.

Сторонники одного лагеря настаивают на том, что юнит-тестами должны быть покрыты только публичные функции и классы. Объяснение этому такое:

  1. Тестировать нужно интерфейс класса или подсистемы, который не зависит от внутренней реализации.
    Любое изменение “внутренностей” этого класса или подсистемы не должно сказываться на функционировании интерфейса. Таким образом, покрыв юнит-тестами интерфейс мы всегда имеем возможность убедиться, что подсистема/класс функционирует именно так, как нам нужно. А что и как у неё делается внутри, с этой точки зрения не важно.
  2. Тестирование приватных функций отнимает много времени, усложняет поддержку и нерационально.
    В ходе любого проекта происходит масса рефакторинга. По моим оценкам, на рефакторинг уходит до 20% времени при “нормальной” организации работы и неплохом качестве архитектуры и кода. Как только в проекте появляются юнит-тесты, так сразу возникает необходимость поддержки не только кода продукта, но и юнит-тестов в актуальном состоянии. При этом реализация классов/подсистем меняется гораздо сильнее и чаще, чем интерфейсы. Всяческие там оптимизации и т.д. Поэтому поддержка юнит-тестов на уровне интерфейса – оправдана, так как даёт уверенность при использовании подсистемы/класса. А покрытие ими реализации – не оправдано, так как, во-первых, если “падает” какой-то внутренний функционал, то “падает” и один из “интерфейсных” вариантов использования, а во-вторых существенно увеличивает объем работы.
  3. Подход полностью соответствует TDD.
    Создавая публичный метод мы, де-факто, создаём интерфейс, его и тестируем. С этой точки зрения нам, опять же, совершенно не важно, что там делает этот метод внутри и как именно.

Второй лагерь настаивает на обратном:

  1. Полезно тестировать каждый отдельно взятый функциональный аспект приложения.
    В термине “юнит-тестирование” под “юнитом” понимается настолько малый и обособленный функциональный фрагмент, насколько это возможно. Фрагмент этот не обязательно должен быть публичным. Разработчики имеют право быть уверены в том, что каждый маленький, но важный кусок (а неважный никто и писать бы не стал – поленился бы) выполняет свою задачу. Независимо от зоны его видимости, которая, кстати, может меняться в процессе рефакторинга.
  2. Приватная функция может быть использована в нескольких местах.
    То же касается и приватного класса. Для того, чтобы использовать эту функцию или класс, неплохо было бы быть уверенным, что этот кусок кода хорошо делает свою работу.
  3. Бόльшая определённость в покрытии юнит-тестами.
    Для каждой отдельной конечной приватной функции достаточно легко написать тест, грамотно покрывающий варианты её использования. Другое дело, когда тестируются только публичные функции, вызывающие другие (приватные) функции. Написать тесты для такой сложной функции может оказаться сложнее. Кроме того, никогда точно не знаешь, какой объем вариантов использования покрыт.

В общем, нет согласия в рядах.

А к какому лагерю склоняетесь вы?

6/11/2009 3:08:21 PM

Прошел РеМикс. Неплохо получилось, на мой взгляд. Были интересные сессии, например, про Windows Azure или про Microsoft Surface. Были откровенно скучные, например, про IE8 – человек более получаса рассказывал про slices, accelerators… То есть то, что можно прочитать в интернете за 7 минут и еще за 5 сделать самому.

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

Был смешной момент, когда на основной сессии показали демо-ролик, в котором что-то делалось. И там был индикатор прогресса. И он крутился целую вечность, секунды две-три, наверное! Видеоролики эти были сделаны достаточно давно, когда оптимизация еще даже не была начата. Подозреваю, что возможно не на релизном билде.
Индикатор крутился, мы с коллегой переглянулись – неужели это было настолько медленно?! Просто сейчас (и это не имеет отношения к тем проблемам с БД, о которых я писал) это происходит практически сразу. Весело :)

Ну а в остальном как всегда :) Подарили сумку. Майкрософт всегда дарит сумку или рюкзак :) В сумке обнаружилось некое количество спонсорской литературы и диск с Windows 7 RC. Хорошая штука, мне нравится. Но у меня уже есть.
Еще в сумке был кирпич. В масштабе 1:3, наверное. Резиновый. С тремя дырками. Не знаю зачем. Жена сказала – подставка для ручек. Может быть, хотя ручек такой толщины, какой там три дырки, я никогда не видел.

Да, в сумке был еще казинак. Фруктово-ореховый. Правда, до него дело не дошло, так как кормили на РеМиксе хорошо. Майкрософт всегда хорошо кормит, даже на отвратительных конференциях (вспоминая корференцию об Офисе) :)

Больше всего понравился всё же про Windows Azure доклад. Мало я о нём знаю всё же. Собираюсь заняться “изучением”. Всё же за этим будущее. Стоооооолько проблем решает (даже не Azure, а сам подход), которые даже по нашему проекту актуально стоят и требуют “реши меня, реши меня!”, что ух!
Точнее, даже не решает, а просто вообще не встают такие проблемы, как масштабирование, репликации, бекапы, надёжность. При этом это гораздо, гораздо, гораздо дешевле, чем иметь какие-то свои сервера и т.д.
Это и безо всякого Азура понятно, конечно. Даже в нашем проекте есть требование иметь возможность хостить всё это дело “in the cloud” (сейчас это Amazon, но Azure выглядит куда лучше). Хотя мы сами себе провайдеры, у нас свои дейта-центры, свои кабели… А тем не менее – cloud computing выходит гораздо дешевле. Поддержка “старой” версии продукта стоит миллионы. Это только стореджи, бекапы и хостинги в разных частях света. Надо ли говорить, что затраты на “облако” в разы меньше. Цифры официальные, Майкл на сессии говорил, значит можно разглашать ;) Это при меньших усилиях по сопровождению и меньших рисках, а следовательно – еще меньшей цене.

Короче, очень интересная тема.

P.S. Как обычно, просили заполнить форму и оценить качество конференции. Обычно как бывает: ты сдаёшь форму и тебе дают за это какой-то подарок. Когда у кого-то денег на подарки нет и спонсоров нет, то придумывается приз, который разыгрывается между сдавшими форму.
Здесь было прикольнее: вышла девушка из организаторов и сказала: “мы просим вас заполнить форму, но вместо того, чтобы закупить в Китае каких-нибудь безделушек по 5 баксов и раздать вам, мы решили эти 5 баксов перечистить в фонд <…>. Каждая заполненная форма – пять долларов в фонд, пожалуйста, заполните формы”. Названия фонда я не запомнил, а не зацензурировал.
Вот так.

Powered by BlogEngine.NET 1.6.0.0

About the author

Alexey Raga Alexey Raga
.NET software developer.

E-mail me Send mail

Twitter


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in