2012-04-24 2 views
1

При разработке модульных приложений тихо ли очевидно, что нам необходимо использовать системы Fail-fast?Использование отказоустойчивого подхода при разработке модульных приложений

При создании модулей, если есть условие ошибки, которое модуль не может обработать, он должен сообщить об ошибке (например, выбросить исключение ..), не беспокоясь о том, кто ее обработает. Похоже, что это можно использовать в качестве ориентира при разработке модулей. Есть ли проблемы с этим?

Редактировать Пример:

В module.dll

public class SomeClass:ISomeInterface 
{ 

    public void CreateFile(string filename) 
    { 
     //The module have no idea who calls this. But there is something wrong   
     //somewhere so throw an exception early. The module writer has no control over 
     //how the exception is handled. So if this exception is not handled by the 
     //Client Application the application can potentially crash.Do he need to worry 
     //about that? 
     if(filename == null) 
     { 
      throw new ArgumentNullException("Filename is null"); 
     } 

     //I think the following is bad. This code is making sure that a module 
     //exception wont crash the application.Is it good? 
     //if(filename ==null) 
     //{ 
     //Logger.log("filename is null"); 
     //return; 
     //} 
    } 
} 

ответ

2

Есть две категории критических исключений, которые я вижу: те, в которых вся система могла быть скомпрометирована, и на самом деле не так много, на что можно смело предположить, что это не так, и те, в которых существенный аспект системы какой код будет ожидать «просто работать», не будет, но нет оснований полагать, что другие части системы скомпрометированы. В первом случае программа действительно не очень эффективна, кроме как умереть, возможно, пытаясь зарегистрировать то, что произошло, если она может это сделать, не повреждая данные «основной линии». В последнем случае, однако, убийство приложения будет чрезмерно «грубым». Лучшим подходом было бы ИМХО разработать подсистему, чтобы код мог «вытащить на нее плагин», чтобы предотвратить ее повреждение данных, вследствие чего любая дальнейшая попытка использовать его (кроме запроса «все еще работает») , возвращающее значение которого должно указывать на проблему), скорее всего, вызовет немедленное исключение, но позволит тем частям программы, которые не нуждаются в проблемной подсистеме, чтобы продолжать работать, как они есть, пока они не решат, что для них не так много обойтись без него.

+0

+1, интересно. Что мне нужно знать, есть ли способ убить проблемную подсистему? Для нашего приложения у нас есть разные GUI Designers для XML-файлов в соответствии с типами. Эти графические дизайнеры создаются в виде модулей (подсистем). Если по какой-либо причине дизайнер не может работать, я хочу, чтобы этот конкретный дизайнер уклонился от приложения, оставив систему работоспособной, как ожидалось. Но вот вопрос в том, как может подсистема умереть в случае ошибки, с которой она не справится? – Jimmy

+0

@ Jimmy: Один из подходов состоит в том, чтобы иметь мастер-свойство IsAlive (возможно, поддерживаемое переменной '_IsAlive') и иметь методы, которые будут использовать объект test для этой переменной. Другой подход (который также может использоваться с 'IsAlive') заключается в том, чтобы аннулировать поля, которые будут использовать методы подсистемы, возможно, обнуляя их или, возможно, заменяя их ссылками на фиктивные объекты, которые будут вызывать более информативные исключения, когда попытка чтобы использовать их. Для структур данных, защищенных замками, может быть полезно обернуть блокировки в защитном устройстве, которое включает флаг «опасность» и ... – supercat

+0

@Jimmy: ... есть код, который собирается (надеюсь, временно) нарушить инвариант, который предполагается, что всякий раз, когда блокировка освобождается, установите флаг опасности перед тем, как нарушить инвариант, и очистите его, когда восстанавливается инвариант. При вызове 'Dispose' на защите блокировки, когда установлен флаг опасности, следует аннулировать базовую структуру данных, а затем очистить блокировку; таким образом, другой код, желающий использовать структуру данных, не застрянет навсегда, ожидая блокировки, которая никогда не будет выпущена, но также не получит доступ к поврежденным данным. – supercat

0

Обычно, когда в C++ обычно я реализую критическую схему ошибок, я не позволяю такие критические исключения даже оставить обработчик исключений - я вызываю метод criticalExit() для экземпляра класса, доступного по всему миру (обычно у меня есть один из них для хранения «глобальных» методов и т. д., например, журналов, пулов объектов), с исключением и строкой, (строка часто просто имя модуля и функции). criticalExit() блокирует мьютекс, повышает приоритет на «THREAD_PRIORITY_TIME_CRITICAL», открывает «CriticalError.Log», добавляет сообщение об исключении и строку в файл, закрывает его и вызывает ExitProcess (1), (Environment.Exit (1)) ,

..и просто посмотреть, я пробовал делать это на C#. Это не так просто, чтобы создать глобально доступный единственный экземпляр :(

+0

«Модульная» система - это лозунг. Причина, по которой задавался этот вопрос, заключается в том, что этот сценарий представляет собой почти случай «один размер подходит всем» (если модули действительно предназначены для самостоятельной работы). Каждый модуль занимается только своими обязанностями. Если приложение использует модули, ответственность за приложения заключается в склеивании модулей и обработке ошибок. – Jimmy

+0

Ситуация, объясняемая в ответе, находится в монолитном приложении (это?), Я говорю о модулях – Jimmy

+0

Модуль является логической коллекцией кода в сборке. Для одного модуля C# небезопасно быть «CriticalErrorHandler» и вызываться из других модулей. –

1

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

Из определения Википедии. Что именно - это «уровень разработки более высокого уровня системы». Должен ли быть не по крайней мере уровень, сообщающий о сбое, чтобы кто-то мог принять корректирующие меры и устранить проблему? верхний уровень, предоставляемый клиентским кодом, который использует ваши классы. Или общий репортер ошибок который вызывается через AppDomain.UnhandledException. Оба полностью вышли из-под тебя.

Выбросить исключение.

+0

Существует segfault/AV, и стек выше был поврежден. Ты собираешься рисковать?

+0

Хмя, вы собираетесь сообщить об этом? –

+0

+1, В большинстве случаев модуль не знает, что вызвало ошибку. В этой ситуации почти невозможно сообщить об ошибке. Я согласен, брошу исключение и не беспокойся о том, кто его обрабатывает. Кстати, я с трудом соглашаюсь с этим. – Jimmy

Смежные вопросы