Clean up the update_awaiter function

This commit is contained in:
Clément Renault 2019-11-04 11:11:58 +01:00
parent 2a50e08bb8
commit c2cc0704d7
No known key found for this signature in database
GPG Key ID: 92ADA4E935E71FA4

View File

@ -21,72 +21,62 @@ pub struct Database {
indexes: RwLock<HashMap<String, (Index, Arc<ArcSwapFn>, thread::JoinHandle<()>)>>, indexes: RwLock<HashMap<String, (Index, Arc<ArcSwapFn>, thread::JoinHandle<()>)>>,
} }
macro_rules! r#break_try {
($expr:expr, $msg:tt) => {
match $expr {
core::result::Result::Ok(val) => val,
core::result::Result::Err(err) => {
log::error!(concat!($msg, ": {}"), err);
break;
}
}
};
}
fn update_awaiter(receiver: Receiver<()>, env: heed::Env, update_fn: Arc<ArcSwapFn>, index: Index) { fn update_awaiter(receiver: Receiver<()>, env: heed::Env, update_fn: Arc<ArcSwapFn>, index: Index) {
for () in receiver { for () in receiver {
// consume all updates in order (oldest first) // consume all updates in order (oldest first)
loop { loop {
let mut writer = match env.write_txn() { // instantiate a main/parent transaction
Ok(writer) => writer, let mut writer = break_try!(env.write_txn(), "LMDB write transaction begin failed");
Err(e) => {
error!("LMDB write transaction begin failed: {}", e);
break;
}
};
let (update_id, update) = match index.updates.pop_front(&mut writer) { // retrieve the update that needs to be processed
Ok(Some(value)) => value, let result = index.updates.pop_front(&mut writer);
Ok(None) => { let (update_id, update) = match break_try!(result, "pop front update failed") {
Some(value) => value,
None => {
debug!("no more updates"); debug!("no more updates");
writer.abort(); writer.abort();
break; break;
} }
Err(e) => {
error!("pop front update failed: {}", e);
break;
}
}; };
let mut nested_writer = match env.nested_write_txn(&mut writer) { // instantiate a nested transaction
Ok(writer) => writer, let result = env.nested_write_txn(&mut writer);
Err(e) => { let mut nested_writer = break_try!(result, "LMDB nested write transaction failed");
error!("LMDB nested write transaction begin failed: {}", e);
break;
}
};
match update::update_task(&mut nested_writer, index.clone(), update_id, update) { // try to apply the update to the database using the nested transaction
Ok(status) => { let result = update::update_task(&mut nested_writer, index.clone(), update_id, update);
match &status.result { let status = break_try!(result, "update task failed");
Ok(_) => {
if let Err(e) = nested_writer.commit() {
error!("update nested transaction failed: {}", e);
}
}
Err(_) => nested_writer.abort(),
}
let result = // commit the nested transaction if the update was successful, abort it otherwise
index if status.result.is_ok() {
.updates_results break_try!(nested_writer.commit(), "commit nested transaction failed");
.put_update_result(&mut writer, update_id, &status); } else {
nested_writer.abort()
}
if let Err(e) = result { // write the result of the update in the updates-results store
error!("update result store commit failed: {}", e); let updates_results = index.updates_results;
} let result = updates_results.put_update_result(&mut writer, update_id, &status);
if let Err(e) = writer.commit() { // always commit the main/parent transaction, even if the update was unsuccessful
error!("update parent transaction failed: {}", e); break_try!(result, "update result store commit failed");
} break_try!(writer.commit(), "update parent transaction failed");
if let Some(ref callback) = *update_fn.load() { // call the user callback when the update and the result are written consistently
(callback)(status); if let Some(ref callback) = *update_fn.load() {
} (callback)(status);
}
Err(e) => {
error!("update task failed: {}", e);
nested_writer.abort();
writer.abort()
}
} }
} }
} }