Add strategic backoff in WinRT backend to (hopefully) eliminate a deadlock.

This commit is contained in:
Nolan Darilek 2020-12-07 14:58:59 -06:00
parent 49e8c0e5dc
commit a905439d9c
3 changed files with 31 additions and 8 deletions

View File

@ -16,6 +16,7 @@ crate-type = ["lib", "cdylib", "staticlib"]
use_tolk = ["tolk"]
[dependencies]
backoff = "0.2"
dyn-clonable = "0.9"
lazy_static = "1"
log = "0.4"

View File

@ -1,7 +1,8 @@
#[cfg(windows)]
use std::collections::HashMap;
use std::sync::Mutex;
#[cfg(windows)]
use std::{collections::HashMap, time::Duration};
use backoff::{ExponentialBackoff, Operation};
use lazy_static::lazy_static;
use log::{info, trace};
use winrt::*;
@ -133,6 +134,13 @@ impl WinRT {
playback_list,
})
}
fn backoff(&self) -> ExponentialBackoff {
ExponentialBackoff {
initial_interval: Duration::from_millis(3),
..Default::default()
}
}
}
impl Backend for WinRT {
@ -167,12 +175,18 @@ impl Backend for WinRT {
if self.player.playback_session()?.playback_state()? != MediaPlaybackState::Playing {
self.player.play()?;
}
let mut uid = NEXT_UTTERANCE_ID.lock().unwrap();
let utterance_id = UtteranceId::WinRT(*uid);
*uid += 1;
drop(uid);
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
mappings.push((self.id, item, utterance_id));
let mut op = || {
let mut uid = NEXT_UTTERANCE_ID.try_lock()?;
let utterance_id = UtteranceId::WinRT(*uid);
*uid += 1;
Ok(utterance_id)
};
let mut backoff = self.backoff();
let utterance_id = op.retry(&mut backoff)?;
{
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
mappings.push((self.id, item, utterance_id));
}
Ok(Some(utterance_id))
}

View File

@ -99,6 +99,8 @@ impl Default for Features {
pub enum Error {
#[error("IO error: {0}")]
IO(#[from] std::io::Error),
#[error("Backoff error")]
Backoff,
#[error("Value not received")]
NoneError,
#[cfg(target_arch = "wasm32")]
@ -113,6 +115,12 @@ pub enum Error {
OutOfRange,
}
impl<E> From<backoff::Error<E>> for Error {
fn from(_: backoff::Error<E>) -> Self {
Error::Backoff
}
}
#[clonable]
trait Backend: Clone + std::fmt::Debug {
fn id(&self) -> Option<BackendId>;