вторник, 29 декабря 2009 г.

Автоматическое обновление и вечный косяк

Большинство современного софта вполне умеет обновлять самое себя через Интернет. Как сделать такое обновление вопрос широких дискуссий. Может быть это будет как в The Bat – просто проверка новой версии на сайте, может как в Google Chrome – скачивание и полностью автоматическая установка новой версии в фоновом режиме. В общем, кто во что горазд.

Но неизменно одно – софтина для обновления обязательно должна выйти в сеть. Без этого никуда. И сколько я перепробовал софта – у всех до единого один и тот же косяк. Если Ваш IE выставлен по умолчанию в offline режим, то софт не может выйти в сеть, и соответственно не может ничего обновить. И не важно из чего это самое “ничего” состоит: из репорта о доступности новой версии, или же это полная установка в фоновом режиме. Обновление не работает и всё тут, самый такой натуральный ППЦФ (“пипец фиче” – фича есть, фича могет, фича модная – только ни хира не работает).

И вот в этом случае, вот совершенно не нужно кивать что мол “только у тебя Гоха IE в вечном оффлайне” (© Arsen). Да мне пофиг! У меня есть свои причины в оффлайне его держать – и причины очень весомые. И тем не менее, несмотря на никакой оффлайновый режим IE, обновление в моей Aml Pages всегда работает.

Поскольку уже подзаколебало писать репорты коллегам – причем коллегам мною весьма уважаемым – про подобные траблы с обновлением, попробую-ка рассказать, как я решал эту проблему в Aml Pages. Опять же да здрям повторное использование кода – будет на что сослаться :), а не кропать заново.

Вкратце: в Aml Pages все обновление сводится к скачке файла с инфой о новых версиях. Дальше уже все на усмотрение пользователя – ставить или нет, посмотреть список изменений и.т.д. Ну да не в этом суть – файл с инфой скачать придется по любому, и обойти оффлайновый режим IE надо.

Оговорю сразу. Существует два вида проверки новой версии: автоматическая по прошествии сколько-то там дней, или ручная, явно запущенная пользователем из команды меню.

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

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

Можно сказать и кратче: есть новая версия? ОК – нужно об этом сказать пользователю. Нет новой версии, нет соединения, поврежден скачанный файл с информацией – все эти подробности ни на хер не нужны. Представьте, сидит себе пользователь, делает что-то свое и вдруг откуда ни возьмись на тебе репорты: “Нет соединения”, “Новых версий не обнаружено”. Да зачем ему вся эта инфа как черт из табакерки – нет и и нет, и нечего пользователя беспокоить.

Автоматическая проверка нужна только для одного: появилась новая версия – скажи, нет новой версии (и не важно по какой причине) - дык и не трахай мне мозг не беспокой меня.

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

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

Элементарно, Ватсон! Делается это просто – всего лишь единственным вызовом API-функции InternetGoOnline!

    BOOL InternetGoOnline (LPCTSTR lpszURL, HWND hwndParent, DWORD dwReserved)

В первом параметре нужно передать URL, по которому собрались обновляться. Второй параметр это HWND окна нашей софтины, он понадобится для сообщений. Третий параметр MS зарезервировала на будущее. Если есть подключение к сети – функция сразу вернет TRUE, в противном случае – FALSE.
Работает эта достославная функция следующим образом:

  • Если подключение к сети уже есть, она сразу вернет TRUE, причем безо всяких подтверждений. В этом случае можно быть уверенным, что IE уже в онлайн-режиме и начинать коннектиться к сайту.
  • Если подключения нет, то функция выдаст MessageBox “не желаете ли подключиться”. Именно для этого и нужен второй параметр с HWND нашего окна. Если пользователь согласится, то функция выполнит подключение и вернет TRUE. Если пользователь откажется – вернет FALSE.

В автоматической проверке вызовом InternetGoOnline, конечно же, грешить не стоит. Еще чего не хватало, чтобы исключительно вспомогательные и фоновые задания доставали пользователя запросами. Не удалось подключиться, и хрен с ним ладно. Совсем другое дело проверка, запущенная пользователем ручками. В этом случае пользователь принял решение сам, в этот момент его внимание по любому приковано к проверке, и он точно ожидает какого-то отклика. Вот в таком случае, имеет смысл и позвать InternetGoOnline – возможные MessageBox ну никак не смутят пользователя, он все равно ждет ответной реакции от софта. Дык почему б и не спросить, если известно что проблема “на этой стороне”? Это точно лучше, чем сказать невразумительное “ошибка соединения”, тем более что эта “ошибка” решаема здесь и сейчас.

Блин, сколько видел вполне толкового софта – все до единого на этом спотыкаются. И HippoEdit, и LeaderTask и многие другие. Долой непонятки – тем более что их решение, это всего две строки кода.

Вместо дисклаймера: мысль, о том что IE в оффлайн у очень немногих -  совсем не катит. Отмазы это для начальства, а не для пользователей.
Проблема тут вовсе не в дилемме “оффлайн vs онлайн” самой по себе – проблема тут исключительно в последствиях. Почему так, разговор длинный. Но если в двух словах: у кого IE запросто может быть в оффлайне-режиме? Да у гиков! А лично вам нужно чтобы именно гики не могли скачать новейшие апдейты?

PS: именно такой способ обновления и реализован в Aml Pages уже больше года назад. Пользователи довольны, обновляются с завидной регулярностью, ни малейших нареканий не возникало.

понедельник, 28 декабря 2009 г.

Softpedia жгет

Softpedia жгет! Выложил свеженькую сборку новой версии Aml Pages 9.15 Alpha. А Softpedia уже обновила версию в своем каталоге. Ну ладно, можно подумать, что новая версия аккурат попала под очередной гребок бота. Не-а! Ан фиг! Новая альфа-версия вышла еще вчера вечером (сборка 2076), и Google уже проиндексировал страницу сотфпедии, причем именно как сборку 2076. Но когда открываем ссылку на софтпедию, видим уже сборку 2077.

Все бы хорошо, но новейшую сборку 2077 выложил буквально один час назад. Оперативно ребята из софтпедии работают. Производит впечатление, ничего не скажешь. Если бы они такой расторопностью отличались бы еще в анонсах Aml Maple, цены бы им не было. И откуда такая дискриминация?

Уж не в аффилиатском ли партнерстве суть!?! Запрос, откуда такая разница в отношениях к этим софтинам – типа “дара-а-а-гой, а ты меня любишь” :) – отправлены в софтпедию. Ждем-с!

PS: Кстати, к вопросу о сабмитах. Дело нужное и архиважное – другой бы спорил. Но судя по гугловским алертам, анонс этой самой, только вчера впервые выложенной альфа-версии Aml Pages, уже начал расползаться по файлопомойкам. Один-два мне уже точно за сутки попадались.

четверг, 17 декабря 2009 г.

Пользовательские интерфейсы в синематографе

Голливудские интерфейсы

Присмотритесь-ка на этот скрин интерфейса из голливудского фильма. Строка “Comp.Sys.Kill” ничего не навевает?

Ох, никогда я не забуду
Дот.Нет на службе Голливуда :)

Взято отсюда.

вторник, 8 декабря 2009 г.

Борьба с false-alarm

Буду краток ©. Сегодня в телеграфном стиле, благо описываемое творится прямо в настоящий момент.

Протекторы vs антивири – тема вышла в тираж на RSDN.ru. Оппоненты все именитые: PolyTech – автор VMProtect, D. Mon –все здесь (привет альма-матери и да здрям Interstron), небезызвестный Мыщьх – полагаю, уж Криса представлять не надо. К сожалению, в оффлайн с участниками не знаком, но общаться лично доводилось и не по разу. Следить за всей этой дискуссией – жуть как интересно, тем более что “аффтары жгут”, но все остается в рамках приличий.

От себя: ух и наловился я этих фолс-позитивов с пару месяцев назад. Подтверждаю: все так. Упомянутые McAffee и ClamAV действительно параноидальны. Реакцию на сообщение о фолсе  можно охарактеризовать кратко - “всемвсёпох”. Касперский отреагировал в течении пары дней, Avira подтянулась следом, с Dr.Web уж и не помню, но и вроде проблем не было, с Avast изначально все ОК было.

Посмотрим во что вся эта дискуссия выльется…

Отдельное и самое искреннее спасибо D. Mon за помощь в свое время в вопросах виртуальных машин. Все-таки иногда полезно отложить бизнес-требования, веб дизайн, маркетинг и всю прочия и прочия да вспомнить где учился…

PS: а написанную тогда виртуальную машинку крякеры так и не сломали, они ее даже не нашли… Хех :)

понедельник, 7 декабря 2009 г.

Круговорот софта в природе

Сегодня получил вот такой вот uninstall feedback.

Мне очень нравится ваша программа, 8 версией я пользуюсь очень, хотелось получить, новую версию. но оплатить нет возможности. простите… С уважением поклонник Aml Pages.

Нифига себе, сказал я себе! С разработкой 8-ой версии я распрощался году так эдак в 2001-ом. Ну, может быть года до 2003-го пару-тройку раз еще выходили всякие мелкие баг-фиксы, но исключительно в целях поддержки. Хоть малейшего, хоть на десяточек строк развития 8-ой версии после 2001 года точно не было. 2010-ый считай уже на пороге – 9 лет прошло – впечатляет живучесть собственного же софта!

Что-то последнее время жизнь стала ставить эка занимательные вопросы… То вдруг студенческим телеграфом в компе сродственников появляется моя же софтина, да причем еще и авторство свое чуть ли не доказывать приходится. То вот этот привет из прошлой, да какой там прошлой – из уже позапрошлой жизни. Потом вдруг попадается софт на 80% по идеям повторяющий мой LOS аж из еще прошлого века… Призадумаешься однако над круговоротом софта в природе!

пятница, 4 декабря 2009 г.

Органайзеры… Доколе!?!

  На RSDN.ru опять поднимаются вечные темы – поиск наилучшего органайзера. И опять традиционная картина: если б молодость могла, если б старость хотела :). И снова вечный скепсис: ниша дохлая. Ага… Щазз! Если люди годами ищут удобный органайзер, и так и не могут найти, какая ж это дохлая ниша? Рыба есть – ловить уметь надо!

Нельзя написать одну программу для всех задач, на все времена и подо все платформы… и одинаково хорошую для всех задач. Приложения для планирования задач неудобны для ведения заметок, а заметки не очень-то подходят для планирования. И уж точно: ни первое, ни второе не относится к напоминалкам. Зато можно написать несколько разных программ, каждую заточенную под свои задачи. Только вовсе не обязательно писать их все – все программы, как и стихи, уже давно написаны. Вполне достаточно научить их взаимодействовать.

Вы никогда не задумывались почему интеграционный софт это просто золотое дно!?! Все очень просто: допустим есть две программы, каждая из которых выполняет свои задачи на “вполне хорошо”. К примеру, Aml Pages для заметок, и LeaderTask для планирования. Можно попеременно пользоваться обоими – ОК, но это простая сумма двух слагаемых.

Хех, integration, в переводе с английского означает “объединение в одно целое”. К чему это? Если научить обе программы хоть немного взаимодействовать, то они начинают увязываться пусть хоть и в простую, но уже систему. А система это всегда больше, чем сумма слагаемых. У системы появляются новые аспекты поведения, которых нет у простой суммы (соседства на харде?) двух программ. Вот поэтому интеграционный софт и есть золотое дно – это создание новых возможностей, которых нет у обоих софтин по отдельности.

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

Как-то писал почему в Aml Pages нет тайм-менеджмента? Да потому что, это не ее задача – Aml Pages это записная книжка, “записки на манжетах”, копилка для эврик, сохранялка для фрагментов веб страниц – да попросту оперативный блокнот под рукой. Какой там нафиг тайм-менеджмент – чего менеджить, и где там тайм? Это разные задачи вообще по своей сути.

Зато в Aml Pages уже сто лет в обед есть все механизмы для интеграции – на любую заметку можно сослаться откуда угодно, и эту ссылку можно в любой момент открыть извне вообще из любого кода. К примеру, плагин Aml Shortcut  именно на этом и построен – он всего лишь создает ярлык с нужными параметрами для открытия конкретной заметки и только. А чем открывать этот ярлык уже не его забота – пользователь ли кликнул или напоминалка по таймеру через этот ярлык открыла нужную заметку – это неважно.

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

“Совершенство – это когда не нечего добавить. Совершенство – это когда нечего убрать!” (© Антуан Сент-Экзюпери). В интеграционном софте нечего убирать, он обеспечивает только необходимое – возможность взаимодействия 2-ух софтин, и только. Убирать нечего – потому и совершенство.

PS: напоследок палю идеи. Обратите внимание на некоторые нюансы.

  1. По сути своей все напоминалки  напоминают периодически. Но почему это должен быть только текст? Открыть сайт, запустить приложение, открыть документ – это не почти ли то же самое? Взгляните на COM-интерфейс ITaskSheduler – все периодично, но что именно периодично можно описать в широких диапазонах. Можно заюзать и сам интерфейс. Не катит? Кто мешает воплотить ту же идею с нуля самому?
  2. Представим следующую ситуацию: вы с отладчиком наперевес уже почти с ногами залезли в окно кода и вовсе перестали реагировать на все внешние раздражители. И в этот момент любимая женщина вам говорит “дорогой, ты просил напомнить, что тебе надо позвонить Ивану”… Нет, нет – не отвлекает, а именно напоминает, привлекает Ваше внимания, но не требует вашей ежесекундной реакции. Не бывало такого?
    ОК, представили себе в уме, ну, а теперь к сути. Где вы видели у любимой кнопку “ОК”, которую нужно нажать чтобы хотя бы быстро закончить свои занятия?
    Так какого же хе… фига без конца показывать эти засранные MessageBox? Где необходимость сначала ответить на него, а только потом вернуться к своей задаче? Поверьте на слово – 30 минут размышлений, и решение находится – это действительно просто.
  3. Ну и последнее. Ни один вменяемый человек никогда не планирует что-то на через неделю ровно на 21:33. Нет, нет, конечно и такое бывает. Но это исключение. Чаще все значительно элементарнее: “завтра вечером”, “в пятницу после обеда”, “как протрезвею проснусь” и.т.д. Тогда на кой хрен, скажите мне, всё завязывать на точные элементы ввода вроде DateTimerPicker? Нарисуйте обычный статик со шкалой: слева утро, справа вечер. Подсветите его слева-направо цветами перехода от желтого (рассвет) к красному (закат) и позвольте пользователю выбирать кликом. Добавьте для наглядности снизу шкалу часов (дней). Пользователи не идиоты, поймут все с первого раза – образы всегда лучше воспринимаются. Очень надо? Ну, добавьте рядом этот DateTimePicker, и синхронизируйте его и выбор на шкале кликом - не помешает. Но поверьте, использоваться он будет исключительно как дополнительное средство и значительно реже.

Для начала, пожалуй, хватит. Авось кому и пригодится высказанное, кого-то вдохновит!?! Один фиг, у меня по-моему никогда не дойдут руки до реализации, особо если учесть что это не последние идеи – их есть у меня…

среда, 2 декабря 2009 г.

Про баги: падать или не падать

Здравствуй, дорогой и горячо любимый Access Violation Елена Сагалаева начала серию статей “Искусство отладки” и даже уже опубликован первый пост “Как предупредить появление багов”. Тема конечно же глубинная. Ре-хех, чуется да будет драка… Да чего уж там, судя по комментариям “гнать из команды”, “не пишем код и не будет багов” – драка уже началась! Ну, как говорится: “amen. понеслася!”. Но посты прелюбопытнейшие, даже порой заглядываю перечитать и поразмышлять. Чего уж тут!?! Достали меня уже в ноль анализы засранных бизнес-требований (сами не знают, чего хотят), бесконечные флеймы в форуме технической поддержки, и все прочие маркетинги-и-иже-с-ними. Давайте-ка лучше маленько подебажим :)

Хех, баги есть, были и всегда будут. А кончатся? Не пропадем – съездим к трем вокзалам и возьмем наплодим новых! Когда баги вползли по невнимательности, ну или по банальной опечатке (такое бывает: начинаю уже тихо материться на автозавершение кода (autocompletion), о  сколько багов оно наплодило в моем коде) - с этим более менее понятно как бороться: code review, нормальные комментарии, assertions где только возможно. В общем, все понятно: баги подобного рода нужно максимально переловить на стадии альфа (бета) релиза.

Но ведь бывает и иначе: “Ты суслика видишь? Нет… А он есть!”. То бишь, ну неоткуда багу взяться, хоть тресни неоткуда и всё тут! Но он есть. И хорошо, если четко диагностируемый и постоянный, а если мигающий да зависящий от конфигурации!?! Imho, в альфа-версиях лучше уж пусть софтина рухнет, грохнется с самым поганым Access Violation, погребя под собою весь процесс вместе с пользовательскими данными заодно. Ну и ладно, зато проблема станет явной.

Буквально последние дни доделываю новую фичу в Aml Pages. Фича весьма неслабая. Мало того, что вовсю используются виртуальные списки (SysListView), когда данные в одном месте, а визуализация их происходит по мере прокручивания списка пользователем. Дык там еще и сами данные выдергиваются многопоточно (а юзер – нет, ну вот зараза какая – старается еще и изменить данные уже в третьем треде). Лично по мне, пусть вся Aml Pages рухнет с треском в релизной сборке, если где-то вдруг у нас порою закрался баг. Всё лучше, чем кряхтя и поднатужившись продолжит выполнение, непонятно в какой винегрет превращая пользовательские данные.

Нет, нет! Никто не собирается вывалить все эти баги на пользователя. Ни в коем случае. В коде уже очень многое предусмотрено: и контроль индексов, и корректная обработка висячих указателей, и проверка на deadlock при многопоточной обработке. Но все это будет задействовано только в первом публичном бета-релизе. В альфа-версии фиг – все максимально сбое-вероятно, пусть уж лучше мой код покажет свое истинное нутро.

Всё просто: проблема не в баге  - проблема в том, откуда он вообще взялся. Если написано, что индекс должен быть от массива “А”, то именно для него он и должен быть, и причем валидным, а не для соседнего. А коль индекс не валидный, то вынуть по нему данные все равно не получится. Выкрутиться можно, но вот вынуть данные корректно, это фиг. В публичном релизе будет и такая страховка. Но проблема в данном случае, не в том что пытаемся вытащить данные по кривому индексу, а в том, откуда такой кривой индекс вообще взялся.

Если весь алгоритм сразу проектировался так, что даже взрыв ядреной бомбы за окном не может повредить индексы, то кривой индекс означает только одно: ядреная бомба где-то в коде. И уж пусть софтинка рухнет намертво – зато проблема станет явной, и явной именно сейчас, в стадии альфа-версии, а не в финальном релизе на машине пользователя. Сиди потом, медитируй на тему “ё-маё, что ж  я сделал, и как они пытаются это использовать”.

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

  1. Банальное переименование некоторых функций. Причина проста: семантически параметры некоторых функций изменились, но не изменились синтаксически. То бишь надо все эти, а желательно еще и соседние, моменты проверить. Но компилятор сам такие ляпы не поймает, т.к. ну нет никакого ляпа с его точки зрения. И что делать? Шерстить глазами? Дык не годится – человеку, и его глазам в частности, свойственно ошибаться. А коли свойственно, то ошибка допущена будет.
    Делаем просто: переименуем старую функцию, ну скажем, GetDataByIndex в нечто вроде GetDataByIndex2 и перекомпилируемся. Компилятор, ясное дело ругается на все вызовы функции по старому имени. Аккуратно просматриваем всю “ругань”, не спеша и тщательно проверяя семантику параметров. Приводим код в полную работоспособность. Ну и под конец, не грех переименовать GetDataByIndex2 во что-нибудь более говорящее, вроде GetDataByArrayIndex чтобы в будущем не путать, что за индекс.
  2. Везде где можно применяются assertions: т.е. проверяется истинность почти всего подряд: висячесть указателей, выход индексов за пределы массива, pre- и post-условия выполнения. В отладочном коде при неверности условия, будет отрабатывать отладочный код, а хоть бы и жутко “матерный” MessageBox. В релизной сборке таких проверок нет, и тем более нет этого “матерного MessageBox`а”. Но даже если что-то было и упущено, то в релизной сборке программа просто рухнет, и проблема станет явной. Чего и добивались – чтобы найти решение проблемы, о ней хотя бы нужно знать. 

Собственно всё! Уже только этих два приема сходу выловили с пяток косяков точно. Остальные ждём-с в релизной сборке – нехай падает.
Имхо, в тестовых версиях баг это благо – он повод задуматься “а с какого-такого перепуга”. Качество и надежность кода – это задача финальных версий. Но без вопроса “с какого перепуга” эта самая пресловутая надежность кода никогда не будет достигнута. Нет вопроса – не будет и ответа.

PS: в комментариях к первому посту Елены упоминал книгу Роббинса по отладке – собственно вот она на Books.ru. К сожалению, в свое время, так и не удалось найти самую первую “отладку” Роббинса. Но, у него есть еще одна любопытная книга: “Отладка Windows приложений” – тоже вещь впечатляющая, а главное и актуальная по сей день. Имхо, must have обе. Но… блин, первую отладку похоже не скоро переиздадут, а жаль – солидное чтиво – мозги на нужный лад настраивает.

PPS: стоп! А как же самый главный пост-скриптум!?! Елене отдельное СПАСИБО за интереснейший цикл статей. Так держать!