вторник, 14 июня 2011 г.

Добавление флагов к API для обхода багов не масштабируется

Это перевод Adding flags to APIs to work around driver bugs doesn't scale. Автор: Реймонд Чен.

Некоторые люди предложили добавление флага к IShellFolder.EnumObjects для указания использования быстрого или медленного перечисления в качестве решения этой проблемы.

Добавление флага, чтобы обойти баг драйвера, не является нормальным решением.

Предположим, что мы бы использовали этот метод (добавление флага) для обхода всех багов в видеодрайверах Windows за всё это время - тогда функции вроде ExtTextOut имели бы несколько десятков флагов, контролирующих различные оптимизации, которые работают всюду, кроме одного бажного драйвера. Тогда вызов ExtTextOut превратился бы в это:
ExtTextOut(hdc, x, y, ETO_OPAQUE or
           ETO_DRIVER_REPORTS_NATIVE_FONTS_CORRECTLY or
           ETO_DRIVER_WILL_NOT_DITHER_TEXT_DURING_BLT or
           ETO_DRIVER_DOES_NOT_LIE_ABOUT_LOCAL_TRANSFORMS or
           ETO_DRIVER_DOES_NOT_CRASH_WITH_STOCK_BRUSHES,
           rcOpaque, lpsz, cch, nil);
где каждый из этих странных флагов указывал бы, что вы хотите получить бонус производительности, потому что вы знаете, что вы запущены на системе, где нет драйверов, которые имеют баг в реализации каждого этого поведения.

И тогда (мы всё ещё говорим чисто гипотетически) вы обнаружите, что ваша программа в Windows Vista работает медленнее, чем она работала в Windows XP: предположим, что был найден баг в видеодрайвере, при котором строки длиннее 1024 символов выводились испорченными. Поэтому Windows Vista разбивает все строки на 1024-символьные блоки, но для оптимизации вы можете указать новый флаг ETO_PASS_LONG_STRINGS_TO_DRIVER, чтобы указать GDI не использовать этот обходной путь. Ваша программа собрана для Windows XP и поэтому не имеет этого флага, поэтому она будет работать медленнее на Windows Vista. Вам придётся выпустить обновление для своей программы, просто чтобы вернуться к тому, что уже было.

Это не ограничивается только флагами. По сути, предложив использовать флаг для указания поведения, вы следуете такой философии системы: "Не пытайся разобраться с багами драйверов, просто переложи ответственность и позволь приложениям самим разбираться с ними". Тогда у вас были бы примерно такие странные параграфы, как вот это (гипотетическое) дополнение (к описанию FindNextFile):
Если функция FindNextFile возвращает False и устанавливает код ошибки в ERROR_NO_MORE_FILES, тогда это значит, что были перечислены все файлы и больше нет файлов, удовлетворяющих критерию.

Примечание: некоторые очень старые сервера Lan Manager (выпуска 1994-го) могут возвращать это состояние раньше положенного времени. Поэтому, если вы перечисляете файлы на сервере со старым Lan Manager и функция FindNextFile говорит вам, что файлов больше нет - вызовите эту функцию повторно, чтобы убедится, что файлов действительно нет.
Может быть я один тут так считаю, но мне кажется, что подобные исправления багов не должны становиться практикой. Я думаю, что одной из целью операционной системы является сглаживание всех этих особенностей и предоставления однородной программной модели приложениям. У приложений и так полно проблем: разбираться с их собственными багами; не стоит сваливать на них ещё и баги драйверов.

Прим.пер.: если система не знает, что делать с багом, и перекладывает ответственность на приложение - откуда приложение-то узнает, что делать с багом, если этого не знает система? Причём каждое приложение вынуждено будет делать это решение, вместо единого централизованного решения в ОС. Введение подобных флагов приведёт просто к тому, что все будут указывать все флаги - конечно же, мы хотим получить бонус производительности, и у нас "всё работает". Поэтому все приложения всегда будут содержать полный набор флагов (известных на момент сборки приложения), так что это решение никогда и не будет работать. Даже если приложение каким-то чудом не будет содержать намертво зашитый набор флагов и будет читать их из настроек - получится, что мы имеем кучи идентичных настроек для каждого индивидуального приложения, вместо того, чтобы иметь их в одном месте (в системе). Пожалуй, это пример проблемы, обратной к решению локальной проблемы глобальным решением. В этом случае получается наоборот: мы решаем глобальную проблему (system-wide) локальным способом (application-wide).

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.