mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-20 19:42:17 +00:00
init bucketmetadata_sys
This commit is contained in:
@@ -2,6 +2,7 @@ use super::{
|
||||
encryption::BucketSSEConfig, event, lifecycle::lifecycle::Lifecycle, objectlock, policy::bucket_policy::BucketPolicy,
|
||||
quota::BucketQuota, replication, tags::Tags, target::BucketTargets, versioning::Versioning,
|
||||
};
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder, LittleEndian};
|
||||
use rmp_serde::Serializer as rmpSerializer;
|
||||
use serde::Serializer;
|
||||
@@ -10,7 +11,7 @@ use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::str::FromStr;
|
||||
use time::OffsetDateTime;
|
||||
use tracing::error;
|
||||
use tracing::{error, warn};
|
||||
|
||||
use crate::bucket::tags;
|
||||
use crate::config;
|
||||
@@ -172,7 +173,19 @@ impl BucketMetadata {
|
||||
return Err(Error::msg("read_bucket_metadata: data invalid"));
|
||||
}
|
||||
|
||||
// TODO: check version
|
||||
let format = LittleEndian::read_u16(&buf[0..2]);
|
||||
let version = LittleEndian::read_u16(&buf[2..4]);
|
||||
|
||||
match format {
|
||||
BUCKET_METADATA_FORMAT => {}
|
||||
_ => return Err(Error::msg("read_bucket_metadata: format invalid")),
|
||||
}
|
||||
|
||||
match version {
|
||||
BUCKET_METADATA_VERSION => {}
|
||||
_ => return Err(Error::msg("read_bucket_metadata: version invalid")),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -252,6 +265,7 @@ impl BucketMetadata {
|
||||
|
||||
fn parse_all_configs(&mut self, _api: &ECStore) -> Result<()> {
|
||||
if !self.tagging_config_xml.is_empty() {
|
||||
warn!("self.tagging_config_xml {:?}", &self.tagging_config_xml);
|
||||
self.tagging_config = Some(tags::Tags::unmarshal(&self.tagging_config_xml)?);
|
||||
}
|
||||
|
||||
@@ -267,6 +281,7 @@ pub async fn load_bucket_metadata_parse(api: &ECStore, bucket: &str, parse: bool
|
||||
let mut bm = match read_bucket_metadata(api, bucket).await {
|
||||
Ok(res) => res,
|
||||
Err(err) => {
|
||||
warn!("load_bucket_metadata_parse err {:?}", &err);
|
||||
if !config::error::is_not_found(&err) {
|
||||
return Err(err);
|
||||
}
|
||||
@@ -299,7 +314,9 @@ async fn read_bucket_metadata(api: &ECStore, bucket: &str) -> Result<BucketMetad
|
||||
|
||||
BucketMetadata::check_header(&data)?;
|
||||
|
||||
BucketMetadata::unmarshal(&data[4..])
|
||||
let bm = BucketMetadata::unmarshal(&data[4..])?;
|
||||
|
||||
Ok(bm)
|
||||
}
|
||||
|
||||
fn _deserialize_from_str<'de, S, D>(deserializer: D) -> core::result::Result<S, D::Error>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::bucket::error::BucketMetadataError;
|
||||
@@ -7,21 +8,26 @@ use crate::config;
|
||||
use crate::config::error::ConfigError;
|
||||
use crate::disk::error::DiskError;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::global::{is_dist_erasure, is_erasure, new_object_layer_fn};
|
||||
use crate::global::{is_dist_erasure, is_erasure, new_object_layer_fn, GLOBAL_Endpoints};
|
||||
use crate::store::ECStore;
|
||||
use futures::future::join_all;
|
||||
use lazy_static::lazy_static;
|
||||
use time::OffsetDateTime;
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
use super::metadata::{load_bucket_metadata, BucketMetadata};
|
||||
use super::tags;
|
||||
|
||||
lazy_static! {
|
||||
static ref GLOBAL_BucketMetadataSys: Arc<BucketMetadataSys> = Arc::new(BucketMetadataSys::new());
|
||||
static ref GLOBAL_BucketMetadataSys: Arc<RwLock<BucketMetadataSys>> = Arc::new(RwLock::new(BucketMetadataSys::new()));
|
||||
}
|
||||
|
||||
pub fn get_bucket_metadata_sys() -> Arc<BucketMetadataSys> {
|
||||
pub async fn init_bucket_metadata_sys(api: ECStore, buckets: Vec<String>) {
|
||||
let mut sys = GLOBAL_BucketMetadataSys.write().await;
|
||||
sys.init(api, buckets).await
|
||||
}
|
||||
pub async fn get_bucket_metadata_sys() -> Arc<RwLock<BucketMetadataSys>> {
|
||||
GLOBAL_BucketMetadataSys.clone()
|
||||
}
|
||||
|
||||
@@ -37,46 +43,77 @@ impl BucketMetadataSys {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub async fn init(&mut self, api: Option<ECStore>, buckets: Vec<&str>) -> Result<()> {
|
||||
if api.is_none() {
|
||||
return Err(Error::msg("errServerNotInitialized"));
|
||||
}
|
||||
self.api = api;
|
||||
pub async fn init(&mut self, api: ECStore, buckets: Vec<String>) {
|
||||
// if api.is_none() {
|
||||
// return Err(Error::msg("errServerNotInitialized"));
|
||||
// }
|
||||
self.api = Some(api);
|
||||
|
||||
let _ = self.init_internal(buckets).await;
|
||||
}
|
||||
async fn init_internal(&self, buckets: Vec<String>) -> Result<()> {
|
||||
let count = {
|
||||
let endpoints = GLOBAL_Endpoints.read().await;
|
||||
endpoints.es_count() * 10
|
||||
};
|
||||
|
||||
let mut failed_buckets: HashSet<String> = HashSet::new();
|
||||
let mut buckets = buckets.as_slice();
|
||||
|
||||
loop {
|
||||
if buckets.len() < count {
|
||||
self.concurrent_load(buckets, &mut failed_buckets).await;
|
||||
break;
|
||||
}
|
||||
|
||||
self.concurrent_load(&buckets[..count], &mut failed_buckets).await;
|
||||
|
||||
buckets = &buckets[count..]
|
||||
}
|
||||
|
||||
let mut initialized = self.initialized.write().await;
|
||||
*initialized = true;
|
||||
|
||||
if is_dist_erasure().await {
|
||||
// TODO: refresh_buckets_metadata_loop
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn init_internal(&self, buckets: Vec<&str>) -> Result<()> {
|
||||
if self.api.is_none() {
|
||||
return Err(Error::msg("errServerNotInitialized"));
|
||||
}
|
||||
let mut futures = Vec::new();
|
||||
let mut errs = Vec::new();
|
||||
let mut ress = Vec::new();
|
||||
|
||||
for &bucket in buckets.iter() {
|
||||
futures.push(load_bucket_metadata(self.api.as_ref().unwrap(), bucket));
|
||||
async fn concurrent_load(&self, buckets: &[String], failed_buckets: &mut HashSet<String>) {
|
||||
let mut futures = Vec::new();
|
||||
|
||||
for bucket in buckets.iter() {
|
||||
futures.push(load_bucket_metadata(self.api.as_ref().unwrap(), bucket.as_str()));
|
||||
}
|
||||
|
||||
let results = join_all(futures).await;
|
||||
|
||||
let mut idx = 0;
|
||||
|
||||
let mut mp = self.metadata_map.write().await;
|
||||
|
||||
for res in results {
|
||||
match res {
|
||||
Ok(entrys) => {
|
||||
ress.push(Some(entrys));
|
||||
errs.push(None);
|
||||
Ok(res) => {
|
||||
if let Some(bucket) = buckets.get(idx) {
|
||||
mp.insert(bucket.clone(), res);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
ress.push(None);
|
||||
errs.push(Some(e));
|
||||
error!("Unable to load bucket metadata, will be retried: {:?}", e);
|
||||
if let Some(bucket) = buckets.get(idx) {
|
||||
failed_buckets.insert(bucket.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn concurrent_load(&self, buckets: Vec<&str>) -> Result<Vec<&str>> {
|
||||
async fn refresh_buckets_metadata_loop(&self, failed_buckets: &HashSet<String>) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -105,7 +142,7 @@ impl BucketMetadataSys {
|
||||
map.clear();
|
||||
}
|
||||
|
||||
pub async fn update(&mut self, bucket: &str, config_file: &str, data: Vec<u8>) -> Result<(OffsetDateTime)> {
|
||||
pub async fn update(&mut self, bucket: &str, config_file: &str, data: Vec<u8>) -> Result<OffsetDateTime> {
|
||||
self.update_and_parse(bucket, config_file, data, true).await
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ mod quota;
|
||||
mod replication;
|
||||
mod tags;
|
||||
mod target;
|
||||
mod versioning;
|
||||
pub mod utils;
|
||||
mod versioning;
|
||||
|
||||
pub use metadata_sys::get_bucket_metadata_sys;
|
||||
pub use metadata_sys::{get_bucket_metadata_sys, init_bucket_metadata_sys};
|
||||
|
||||
Reference in New Issue
Block a user