Robust Software Dotting the Is and Crossing the
Robust Software – Dotting the I’s and Crossing the T’s Chris Oldwood ACCU Conference 2013 @chrisoldwood / gort@cix. co. uk
The I’s & T’s n Robustness n Handling Errors n Safely Ignoring Errors n Timeouts n Unit Testing Failures n Flexible Configuration n Monitoring Clarity
Robustness
Stable in the face of unexpected behaviour
Pop Quiz – Exit Code? int main(int argc, char* argv[]) { throw Unhandled. Exception(); }
Exit Code Convention program. exe if %errorlevel% neq 0 ( echo ERROR: Program failed exit /b 1 )
Big Outer Try Block int main(int argc, char* argv[]) { try { return Do. Useful. Work(argc, argv); } catch (const std: : exception& e) { /* Report failure */ } catch (…) { /* Report failure */ } return EXIT_FAILURE; }
Module Boundaries HRESULT Do. Something(. . . ) { try { return Impl: : Do. Something(. . . ); } catch (const std: : bad_alloc& e) { return E_OUTOFMEMORY; } catch (const std: : exception& e) { return E_FAIL; } catch (. . . ) { return E_UNEXPECTED; } }
Exception Safety Guarantees n None n Basic n Strong n No Throw
Exception Unsafe Code IService. Ptr Acquire. Service() { if (!m_service) { m_service = new Service(); m_service. Create. Instance(); } return m_service; } IService. Ptr m_service;
Exception Safe Code IService. Ptr Acquire. Service() { if (!m_service) { Service. Ptr service = new Service(); service. Create. Instance(); m_service. swap(service); } return m_service; } IService. Ptr m_service;
Forever is a Really Long Time Handle completed = Begin. Async. Operation(); . . . Wait(completed, INFINITE);
Cancellable Operations Handle. . . Handle completed = Begin. Async. Operation(); aborted = Get. Abort. Handle(); waitables[] = { aborted, completed }; signalled = Wait(waitables, timeout); if (signalled == aborted) {
Retries: immediate then queued
Unit Testing Failures
Testing Write+Rename Idiom [Test] public Void Original. File. Preserved. On. Exception() { var fake. Io = new Fake. Io(); fake. Io. Write = (file, buffer) => { throw new Io. Exception(); } var writer = new Writer. Service(fake. Io); var filename = “original. txt”; Assert. Throws(() => writer. Write. File(filename)); Assert. True(fake. Io. File. Exists(filename)); Assert. That(. . . ); }
Flexible Configuration
Monitoring Clarity
Release It!
Questions?
Blog: http: //chrisoldwood. blogspot. com @chrisoldwood / gort@cix. co. uk
- Slides: 21