Skip to content

Commit 77605cf

Browse files
authored
Merge pull request #2266 from oasisprotocol/kostko/feature/rofl-reg-retry-backoff
rofl-app-core: Retry registration using exponential backoff
2 parents deca936 + 04f302b commit 77605cf

3 files changed

Lines changed: 33 additions & 16 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rofl-app-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ anyhow = "1.0.86"
1313
async-trait = "0.1.77"
1414
base64 = "0.22.1"
1515
rand = "0.8.5"
16+
backoff = { version = "0.4", features = ["tokio"] }
1617
slog = "2.7.0"
1718
tokio = { version = "1.38", features = [
1819
"rt",

rofl-app-core/src/registration.rs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ where
3939
env,
4040
logger: get_logger("modules/rofl/app/registration"),
4141
notify: rx,
42-
last_registration_epoch: None,
4342
};
4443

4544
Self { imp: Some(imp), tx }
@@ -64,7 +63,6 @@ struct Impl<A: App> {
6463
logger: slog::Logger,
6564

6665
notify: mpsc::Receiver<()>,
67-
last_registration_epoch: Option<EpochTime>,
6866
}
6967

7068
impl<A> Impl<A>
@@ -80,20 +78,39 @@ where
8078
async fn run(mut self) {
8179
slog::info!(self.logger, "starting registration task");
8280

83-
// TODO: Handle retries etc.
81+
let mut last_registration_epoch: Option<EpochTime> = None;
82+
8483
while self.notify.recv().await.is_some() {
85-
if let Err(err) = self.refresh_registration().await {
86-
slog::error!(self.logger, "failed to refresh registration";
87-
"err" => ?err,
88-
);
84+
let backoff = backoff::ExponentialBackoff::default();
85+
86+
let result = backoff::future::retry(backoff, async || {
87+
let result = self.refresh_registration(last_registration_epoch).await;
88+
if let Err(ref err) = result {
89+
slog::error!(self.logger, "failed to refresh registration";
90+
"err" => ?err,
91+
);
92+
}
93+
94+
result.map_err(backoff::Error::transient)
95+
})
96+
.await;
97+
98+
match result {
99+
Ok(epoch) => last_registration_epoch = Some(epoch),
100+
Err(_) => continue,
89101
}
90102
}
91103

92104
slog::info!(self.logger, "registration task stopped");
93105
}
94106

95107
/// Perform application registration refresh.
96-
async fn refresh_registration(&mut self) -> Result<()> {
108+
///
109+
/// On success, it returns the epoch for which the registration was refreshed.
110+
async fn refresh_registration(
111+
&self,
112+
last_registration_epoch: Option<EpochTime>,
113+
) -> Result<EpochTime> {
97114
// Determine current epoch.
98115
let state = self.state.consensus_verifier.latest_state().await?;
99116
let epoch = tokio::task::spawn_blocking(move || {
@@ -103,8 +120,8 @@ where
103120
.await??;
104121

105122
// Skip refresh in case epoch has not changed.
106-
if self.last_registration_epoch == Some(epoch) {
107-
return Ok(());
123+
if last_registration_epoch == Some(epoch) {
124+
return Ok(epoch);
108125
}
109126

110127
// Query our current registration and see if we need to update it.
@@ -126,16 +143,15 @@ where
126143
if existing.expiration >= epoch + 2 {
127144
slog::info!(self.logger, "registration already refreshed"; "epoch" => epoch);
128145

129-
self.last_registration_epoch = Some(epoch);
130146
self.env
131147
.send_command(processor::Command::RegistrationRefreshed)
132148
.await?;
133-
return Ok(());
149+
return Ok(epoch);
134150
}
135151
}
136152

137153
slog::info!(self.logger, "refreshing registration";
138-
"last_registration_epoch" => self.last_registration_epoch,
154+
"last_registration_epoch" => last_registration_epoch,
139155
"epoch" => epoch,
140156
);
141157

@@ -185,21 +201,20 @@ where
185201

186202
slog::info!(self.logger, "refreshed registration"; "result" => ?result);
187203

188-
if self.last_registration_epoch.is_none() {
204+
if last_registration_epoch.is_none() {
189205
// If this is the first registration, notify processor that initial registration has
190206
// been completed so it can do other stuff.
191207
self.env
192208
.send_command(processor::Command::InitialRegistrationCompleted)
193209
.await?;
194210
}
195-
self.last_registration_epoch = Some(epoch);
196211

197212
// Notify about registration refresh.
198213
self.env
199214
.send_command(processor::Command::RegistrationRefreshed)
200215
.await?;
201216

202-
Ok(())
217+
Ok(epoch)
203218
}
204219

205220
async fn collect_provider_metadata(

0 commit comments

Comments
 (0)