dimanche 25 septembre 2022

Is there a design pattern for this usage?

(Not necessarily restricted to Rust, it happens to be the tech stack I'm working with)

My use case is the following: users would like to measure external variables (eg. amperage, temperature, anything numerical) and pipe that measurement into a public API I am building. Let's say that users will perform their measurement via some Device and feed that input into my Analyser. The user will repeatedly measure and feed the measurement into my Analyser; the analyser generates an AnalyserOutput which the user uses as feedback for their device. High-level pseudocode looks like this:

// User inits their device. This can be anything the user wishes to use
let device = TemperatureGauge::Device::new();

// Init analyser (my public API)
let analyser = Analyser::new();

loop {
   // read some value
   let read_val: f64 = device.read();
   
   // problem: 
   // calculate feedback immediately after read
   // if there was a significant delay between these
   // calls eg. I inserted a thread::sleep(1000)
   // then the output generated would be inaccurate. How can
   // I enforce that there is nothing between these two
   // invocations?
   let output_feedback = analyser.next(read_val);

   // set some external variable via device based on feedback
   device.set(read_val + output_feedback);

   thread::sleep(1);
}

Here is the problem: the analyser.read(read_val) method is dependent on the time at which the current read_val was read and the time in which the previous read_val was read at. This means that I need the user to call .next() immediately after their .read() invocations.

I'm struggling with designing an API to enforce this constraint. I have no control over what and how the user is measuring. It could be some driver or it could be a simple calculation. Now, I'm stuck with assuming that the user has invoked my API under the correct circumstances.

Are there design patterns that can help me enforce this constraint: immediately following some-kind of a user 'read' invocation is an analyser.read() invocation?

Aucun commentaire:

Enregistrer un commentaire