odin-detector/odin-data

View on GitHub
docs/developer/explanations/design-decisions.md

Summary

Maintainability
Test Coverage
# Design Decisions

The frameReceiver and frameProcessor are implemented as two separate applications for a
few key reasons:

## Separation of concerns

There are fundamentally two separate problem domains: data capture - receiving data from
the network interface onto the system - and data processing. These two operations can be
almost completely isolated with no coordination of the two processes other than to pass
pointers to data frames in memory. By splitting the data acquisition process into these
two parts they can be developed and debugged in isolation rather than within in a single
process with multiple threads.

By focusing one process on data capture, it is possible to optimise as required, such
as by allowing it higher priority to ensure sufficient resources. Once data is on the
system, it enters the domain of procesing and writing to persistent storage. In this
domain bottlenecks in the processing can be overcome by increasing the resources of the
processing server, such as by adding more memory, or by optimising the logic of an
isolated FrameProcessorPlugin.

## Monitoring

The first failure point in the data acquisition pipeline is receiving data from the
network interface into system memory. If this is not done quickly enough, packets will
be dropped at the kernel layer with no indication of what went wrong. Allowing the
frameReceiver to do the minimum work to gather data into memory means this usage can be
monitored and when it is exhausted it will be clear where data was lost. This monitoring
extends throughout the frameProcessor through processing time metrics for each plugin
and watchdog timers around certain I/O to show when a call is blocking for longer than
expected.