rustfs_lock/
lib.rs

1#![allow(dead_code)]
2// Copyright 2024 RustFS Team
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use async_trait::async_trait;
17use lazy_static::lazy_static;
18use local_locker::LocalLocker;
19use lock_args::LockArgs;
20use remote_client::RemoteClient;
21use std::io::Result;
22use std::sync::Arc;
23use tokio::sync::RwLock;
24
25pub mod drwmutex;
26pub mod local_locker;
27pub mod lock_args;
28pub mod lrwmutex;
29pub mod namespace_lock;
30pub mod remote_client;
31
32lazy_static! {
33    pub static ref GLOBAL_LOCAL_SERVER: Arc<RwLock<LocalLocker>> = Arc::new(RwLock::new(LocalLocker::new()));
34}
35
36type LockClient = dyn Locker;
37
38#[async_trait]
39pub trait Locker {
40    async fn lock(&mut self, args: &LockArgs) -> Result<bool>;
41    async fn unlock(&mut self, args: &LockArgs) -> Result<bool>;
42    async fn rlock(&mut self, args: &LockArgs) -> Result<bool>;
43    async fn runlock(&mut self, args: &LockArgs) -> Result<bool>;
44    async fn refresh(&mut self, args: &LockArgs) -> Result<bool>;
45    async fn force_unlock(&mut self, args: &LockArgs) -> Result<bool>;
46    async fn close(&self);
47    async fn is_online(&self) -> bool;
48    async fn is_local(&self) -> bool;
49}
50
51#[derive(Debug, Clone)]
52pub enum LockApi {
53    Local,
54    Remote(RemoteClient),
55}
56
57#[async_trait]
58impl Locker for LockApi {
59    async fn lock(&mut self, args: &LockArgs) -> Result<bool> {
60        match self {
61            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.lock(args).await,
62            LockApi::Remote(r) => r.lock(args).await,
63        }
64    }
65
66    async fn unlock(&mut self, args: &LockArgs) -> Result<bool> {
67        match self {
68            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.unlock(args).await,
69            LockApi::Remote(r) => r.unlock(args).await,
70        }
71    }
72
73    async fn rlock(&mut self, args: &LockArgs) -> Result<bool> {
74        match self {
75            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.rlock(args).await,
76            LockApi::Remote(r) => r.rlock(args).await,
77        }
78    }
79
80    async fn runlock(&mut self, args: &LockArgs) -> Result<bool> {
81        match self {
82            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.runlock(args).await,
83            LockApi::Remote(r) => r.runlock(args).await,
84        }
85    }
86
87    async fn refresh(&mut self, args: &LockArgs) -> Result<bool> {
88        match self {
89            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.refresh(args).await,
90            LockApi::Remote(r) => r.refresh(args).await,
91        }
92    }
93
94    async fn force_unlock(&mut self, args: &LockArgs) -> Result<bool> {
95        match self {
96            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.force_unlock(args).await,
97            LockApi::Remote(r) => r.force_unlock(args).await,
98        }
99    }
100
101    async fn close(&self) {
102        match self {
103            LockApi::Local => GLOBAL_LOCAL_SERVER.read().await.close().await,
104            LockApi::Remote(r) => r.close().await,
105        }
106    }
107
108    async fn is_online(&self) -> bool {
109        match self {
110            LockApi::Local => GLOBAL_LOCAL_SERVER.read().await.is_online().await,
111            LockApi::Remote(r) => r.is_online().await,
112        }
113    }
114
115    async fn is_local(&self) -> bool {
116        match self {
117            LockApi::Local => GLOBAL_LOCAL_SERVER.write().await.is_local().await,
118            LockApi::Remote(r) => r.is_local().await,
119        }
120    }
121}
122
123pub fn new_lock_api(is_local: bool, url: Option<url::Url>) -> LockApi {
124    if is_local {
125        return LockApi::Local;
126    }
127
128    LockApi::Remote(RemoteClient::new(url.unwrap()))
129}