mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-17 10:17:55 +00:00
merge main
This commit is contained in:
+120
-31
@@ -1,3 +1,4 @@
|
||||
#![allow(clippy::map_entry)]
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use common::globals::GLOBAL_Local_Node_Name;
|
||||
@@ -17,19 +18,25 @@ use crate::{
|
||||
set_disk::SetDisks,
|
||||
store::{GLOBAL_IsDistErasure, GLOBAL_LOCAL_DISK_SET_DRIVES},
|
||||
store_api::{
|
||||
BucketInfo, BucketOptions, CompletePart, DeletedObject, GetObjectReader, HTTPRangeSpec, ListObjectsV2Info,
|
||||
MakeBucketOptions, MultipartUploadResult, ObjectInfo, ObjectOptions, ObjectToDelete, PartInfo, PutObjReader, StorageAPI,
|
||||
BucketInfo, BucketOptions, CompletePart, DeleteBucketOptions, DeletedObject, GetObjectReader, HTTPRangeSpec,
|
||||
ListObjectsV2Info, MakeBucketOptions, MultipartUploadResult, ObjectInfo, ObjectOptions, ObjectToDelete, PartInfo,
|
||||
PutObjReader, StorageAPI,
|
||||
},
|
||||
utils::hash,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
use tokio::time::Duration;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::info;
|
||||
use tracing::warn;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sets {
|
||||
pub id: Uuid,
|
||||
// pub sets: Vec<Objects>,
|
||||
// pub disk_set: Vec<Vec<Option<DiskStore>>>, // [set_count_idx][set_drive_count_idx] = disk_idx
|
||||
pub disk_set: Vec<SetDisks>, // [set_count_idx][set_drive_count_idx] = disk_idx
|
||||
pub lockers: Vec<Vec<LockApi>>,
|
||||
pub disk_set: Vec<Arc<SetDisks>>, // [set_count_idx][set_drive_count_idx] = disk_idx
|
||||
pub pool_idx: usize,
|
||||
pub endpoints: PoolEndpoints,
|
||||
pub format: FormatV3,
|
||||
@@ -37,6 +44,7 @@ pub struct Sets {
|
||||
pub set_count: usize,
|
||||
pub set_drive_count: usize,
|
||||
pub distribution_algo: DistributionAlgoVersion,
|
||||
ctx: CancellationToken,
|
||||
}
|
||||
|
||||
impl Sets {
|
||||
@@ -46,7 +54,7 @@ impl Sets {
|
||||
fm: &FormatV3,
|
||||
pool_idx: usize,
|
||||
partiy_count: usize,
|
||||
) -> Result<Self> {
|
||||
) -> Result<Arc<Self>> {
|
||||
let set_count = fm.erasure.sets.len();
|
||||
let set_drive_count = fm.erasure.sets[0].len();
|
||||
|
||||
@@ -72,10 +80,16 @@ impl Sets {
|
||||
|
||||
for i in 0..set_count {
|
||||
let mut set_drive = Vec::with_capacity(set_drive_count);
|
||||
let mut set_endpoints = Vec::with_capacity(set_drive_count);
|
||||
for j in 0..set_drive_count {
|
||||
let idx = i * set_drive_count + j;
|
||||
let mut disk = disks[idx].clone();
|
||||
|
||||
let endpoint = endpoints.endpoints.as_ref().get(idx).cloned();
|
||||
set_endpoints.push(endpoint);
|
||||
|
||||
if disk.is_none() {
|
||||
warn!("sets new set_drive {}-{} is none", i, j);
|
||||
set_drive.push(None);
|
||||
continue;
|
||||
}
|
||||
@@ -87,6 +101,7 @@ impl Sets {
|
||||
};
|
||||
|
||||
if local_disk.is_none() {
|
||||
warn!("sets new set_drive {}-{} local_disk is none", i, j);
|
||||
set_drive.push(None);
|
||||
continue;
|
||||
}
|
||||
@@ -96,28 +111,33 @@ impl Sets {
|
||||
disk = local_disk;
|
||||
}
|
||||
|
||||
if let Some(_disk_id) = disk.as_ref().unwrap().get_disk_id().await {
|
||||
if let Some(_disk_id) = disk.as_ref().unwrap().get_disk_id().await? {
|
||||
set_drive.push(disk);
|
||||
} else {
|
||||
warn!("sets new set_drive {}-{} get_disk_id is none", i, j);
|
||||
set_drive.push(None);
|
||||
}
|
||||
}
|
||||
|
||||
// warn!("sets new set_drive {:?}", &set_drive);
|
||||
|
||||
let set_disks = SetDisks {
|
||||
disks: set_drive,
|
||||
lockers: lockers[i].clone(),
|
||||
locker_owner: GLOBAL_Local_Node_Name.read().await.to_string(),
|
||||
ns_mutex: Arc::new(RwLock::new(NsLockMap::new(*GLOBAL_IsDistErasure.read().await))),
|
||||
disks: RwLock::new(set_drive),
|
||||
set_drive_count,
|
||||
parity_count: partiy_count,
|
||||
default_parity_count: partiy_count,
|
||||
set_index: i,
|
||||
pool_index: pool_idx,
|
||||
set_endpoints,
|
||||
format: fm.clone(),
|
||||
};
|
||||
|
||||
disk_set.push(set_disks);
|
||||
disk_set.push(Arc::new(set_disks));
|
||||
}
|
||||
|
||||
let sets = Self {
|
||||
let sets = Arc::new(Self {
|
||||
id: fm.id,
|
||||
// sets: todo!(),
|
||||
disk_set,
|
||||
@@ -129,15 +149,58 @@ impl Sets {
|
||||
set_count,
|
||||
set_drive_count,
|
||||
distribution_algo: fm.erasure.distribution_algo.clone(),
|
||||
};
|
||||
ctx: CancellationToken::new(),
|
||||
});
|
||||
|
||||
let asets = sets.clone();
|
||||
|
||||
tokio::spawn(async move { asets.monitor_and_connect_endpoints().await });
|
||||
|
||||
Ok(sets)
|
||||
}
|
||||
pub fn get_disks(&self, set_idx: usize) -> SetDisks {
|
||||
|
||||
pub async fn monitor_and_connect_endpoints(&self) {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
|
||||
info!("start monitor_and_connect_endpoints");
|
||||
|
||||
self.connect_disks().await;
|
||||
|
||||
// TODO: config interval
|
||||
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(15 * 3));
|
||||
let cloned_token = self.ctx.clone();
|
||||
loop {
|
||||
tokio::select! {
|
||||
_= interval.tick()=>{
|
||||
// debug!("tick...");
|
||||
self.connect_disks().await;
|
||||
|
||||
interval.reset();
|
||||
},
|
||||
|
||||
_ = cloned_token.cancelled() => {
|
||||
warn!("ctx cancelled");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
warn!("monitor_and_connect_endpoints exit");
|
||||
}
|
||||
|
||||
async fn connect_disks(&self) {
|
||||
// debug!("start connect_disks ...");
|
||||
for set in self.disk_set.iter() {
|
||||
set.connect_disks().await;
|
||||
}
|
||||
// debug!("done connect_disks ...");
|
||||
}
|
||||
|
||||
pub fn get_disks(&self, set_idx: usize) -> Arc<SetDisks> {
|
||||
self.disk_set[set_idx].clone()
|
||||
}
|
||||
|
||||
pub fn get_disks_by_key(&self, key: &str) -> SetDisks {
|
||||
pub fn get_disks_by_key(&self, key: &str) -> Arc<SetDisks> {
|
||||
self.get_disks(self.get_hashed_set_index(key))
|
||||
}
|
||||
|
||||
@@ -224,8 +287,7 @@ impl StorageAPI for Sets {
|
||||
let mut set_obj_map = HashMap::new();
|
||||
|
||||
// hash key
|
||||
let mut i = 0;
|
||||
for obj in objects.iter() {
|
||||
for (i, obj) in objects.iter().enumerate() {
|
||||
let idx = self.get_hashed_set_index(obj.object_name.as_str());
|
||||
|
||||
if !set_obj_map.contains_key(&idx) {
|
||||
@@ -237,34 +299,54 @@ impl StorageAPI for Sets {
|
||||
obj: obj.clone(),
|
||||
}],
|
||||
);
|
||||
} else {
|
||||
if let Some(val) = set_obj_map.get_mut(&idx) {
|
||||
val.push(DelObj {
|
||||
// set_idx: idx,
|
||||
orig_idx: i,
|
||||
obj: obj.clone(),
|
||||
});
|
||||
}
|
||||
} else if let Some(val) = set_obj_map.get_mut(&idx) {
|
||||
val.push(DelObj {
|
||||
// set_idx: idx,
|
||||
orig_idx: i,
|
||||
obj: obj.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// let semaphore = Arc::new(Semaphore::new(num_cpus::get()));
|
||||
// let mut jhs = Vec::with_capacity(semaphore.available_permits());
|
||||
|
||||
// for (k, v) in set_obj_map {
|
||||
// let disks = self.get_disks(k);
|
||||
// let semaphore = semaphore.clone();
|
||||
// let opts = opts.clone();
|
||||
// let bucket = bucket.to_string();
|
||||
|
||||
// let jh = tokio::spawn(async move {
|
||||
// let _permit = semaphore.acquire().await.unwrap();
|
||||
// let objs: Vec<ObjectToDelete> = v.iter().map(|v| v.obj.clone()).collect();
|
||||
// disks.delete_objects(&bucket, objs, opts).await
|
||||
// });
|
||||
// jhs.push(jh);
|
||||
// }
|
||||
|
||||
// let mut results = Vec::with_capacity(jhs.len());
|
||||
// for jh in jhs {
|
||||
// results.push(jh.await?.unwrap());
|
||||
// }
|
||||
|
||||
// for (dobjects, errs) in results {
|
||||
// del_objects.extend(dobjects);
|
||||
// del_errs.extend(errs);
|
||||
// }
|
||||
|
||||
// TODO: 并发
|
||||
for (k, v) in set_obj_map {
|
||||
let disks = self.get_disks(k);
|
||||
let objs: Vec<ObjectToDelete> = v.iter().map(|v| v.obj.clone()).collect();
|
||||
let (dobjects, errs) = disks.delete_objects(bucket, objs, opts.clone()).await?;
|
||||
|
||||
let mut i = 0;
|
||||
for err in errs {
|
||||
for (i, err) in errs.into_iter().enumerate() {
|
||||
let obj = v.get(i).unwrap();
|
||||
|
||||
del_errs[obj.orig_idx] = err;
|
||||
|
||||
del_objects[obj.orig_idx] = dobjects.get(i).unwrap().clone();
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,6 +376,13 @@ impl StorageAPI for Sets {
|
||||
async fn get_object_info(&self, bucket: &str, object: &str, opts: &ObjectOptions) -> Result<ObjectInfo> {
|
||||
self.get_disks_by_key(object).get_object_info(bucket, object, opts).await
|
||||
}
|
||||
|
||||
async fn put_object_info(&self, bucket: &str, object: &str, info: ObjectInfo, opts: &ObjectOptions) -> Result<()> {
|
||||
self.get_disks_by_key(object)
|
||||
.put_object_info(bucket, object, info, opts)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_object_reader(
|
||||
&self,
|
||||
bucket: &str,
|
||||
@@ -306,7 +395,7 @@ impl StorageAPI for Sets {
|
||||
.get_object_reader(bucket, object, range, h, opts)
|
||||
.await
|
||||
}
|
||||
async fn put_object(&self, bucket: &str, object: &str, data: PutObjReader, opts: &ObjectOptions) -> Result<()> {
|
||||
async fn put_object(&self, bucket: &str, object: &str, data: PutObjReader, opts: &ObjectOptions) -> Result<ObjectInfo> {
|
||||
self.get_disks_by_key(object).put_object(bucket, object, data, opts).await
|
||||
}
|
||||
|
||||
@@ -345,7 +434,7 @@ impl StorageAPI for Sets {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn delete_bucket(&self, _bucket: &str) -> Result<()> {
|
||||
async fn delete_bucket(&self, _bucket: &str, _opts: &DeleteBucketOptions) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user