improvements in block manager

This commit is contained in:
Alex Auvolat 2022-09-12 16:57:38 +02:00
parent 7f54706b95
commit b823151a0b
No known key found for this signature in database
GPG key ID: 0E496D15096376BE

View file

@ -11,7 +11,7 @@ use futures::Stream;
use futures_util::stream::StreamExt; use futures_util::stream::StreamExt;
use tokio::fs; use tokio::fs;
use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader}; use tokio::io::{AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::sync::{mpsc, Mutex}; use tokio::sync::{mpsc, Mutex, MutexGuard};
use opentelemetry::{ use opentelemetry::{
trace::{FutureExt as OtelFutureExt, TraceContextExt, Tracer}, trace::{FutureExt as OtelFutureExt, TraceContextExt, Tracer},
@ -261,7 +261,7 @@ impl BlockManager {
> { > {
let (header, stream) = self.rpc_get_raw_block_streaming(hash, order_tag).await?; let (header, stream) = self.rpc_get_raw_block_streaming(hash, order_tag).await?;
match header { match header {
DataBlockHeader::Plain => Ok(Box::pin(stream)), DataBlockHeader::Plain => Ok(stream),
DataBlockHeader::Compressed => { DataBlockHeader::Compressed => {
// Too many things, I hate it. // Too many things, I hate it.
let reader = stream_asyncread(stream); let reader = stream_asyncread(stream);
@ -389,11 +389,7 @@ impl BlockManager {
let write_size = data.inner_buffer().len() as u64; let write_size = data.inner_buffer().len() as u64;
self.mutation_lock[hash.as_slice()[0] as usize] self.lock_mutate(hash)
.lock()
.with_context(Context::current_with_span(
tracer.start("Acquire mutation_lock"),
))
.await .await
.write_block(hash, data, self) .write_block(hash, data, self)
.bound_record_duration(&self.metrics.block_write_duration) .bound_record_duration(&self.metrics.block_write_duration)
@ -470,8 +466,7 @@ impl BlockManager {
if data.verify(*hash).is_err() { if data.verify(*hash).is_err() {
self.metrics.corruption_counter.add(1); self.metrics.corruption_counter.add(1);
self.mutation_lock[hash.as_slice()[0] as usize] self.lock_mutate(hash)
.lock()
.await .await
.move_block_to_corrupted(hash, self) .move_block_to_corrupted(hash, self)
.await?; .await?;
@ -484,8 +479,7 @@ impl BlockManager {
/// Check if this node has a block and whether it needs it /// Check if this node has a block and whether it needs it
pub(crate) async fn check_block_status(&self, hash: &Hash) -> Result<BlockStatus, Error> { pub(crate) async fn check_block_status(&self, hash: &Hash) -> Result<BlockStatus, Error> {
self.mutation_lock[hash.as_slice()[0] as usize] self.lock_mutate(hash)
.lock()
.await .await
.check_block_status(hash, self) .check_block_status(hash, self)
.await .await
@ -499,8 +493,7 @@ impl BlockManager {
/// Delete block if it is not needed anymore /// Delete block if it is not needed anymore
pub(crate) async fn delete_if_unneeded(&self, hash: &Hash) -> Result<(), Error> { pub(crate) async fn delete_if_unneeded(&self, hash: &Hash) -> Result<(), Error> {
self.mutation_lock[hash.as_slice()[0] as usize] self.lock_mutate(hash)
.lock()
.await .await
.delete_if_unneeded(hash, self) .delete_if_unneeded(hash, self)
.await .await
@ -532,6 +525,16 @@ impl BlockManager {
path.set_extension(""); path.set_extension("");
fs::metadata(&path).await.map(|_| false).map_err(Into::into) fs::metadata(&path).await.map(|_| false).map_err(Into::into)
} }
async fn lock_mutate(&self, hash: &Hash) -> MutexGuard<'_, BlockManagerLocked> {
let tracer = opentelemetry::global::tracer("garage");
self.mutation_lock[hash.as_slice()[0] as usize]
.lock()
.with_context(Context::current_with_span(
tracer.start("Acquire mutation_lock"),
))
.await
}
} }
#[async_trait] #[async_trait]