common_procedure/store/poison_store.rs
1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::Arc;
16
17use async_trait::async_trait;
18
19use crate::error::Result;
20
21pub type PoisonStoreRef = Arc<dyn PoisonStore>;
22
23/// Poison store.
24///
25/// This trait is used to manage the state of operations on resources, particularly
26/// when an operation encounters an unrecoverable error, potentially leading to
27/// metadata inconsistency. In such cases, manual intervention is required to
28/// resolve the issue before any further operations can be performed on the resource.
29///
30/// ## Behavior:
31/// - **Insertion**: When an operation begins on a resource, a "poison" key is inserted
32/// into the state store to indicate the operation is in progress.
33/// - **Deletion**: If the operation completes successfully or
34/// other cases can ensure the resource is in a consistent state, the poison key is removed
35/// from the state store, indicating the resource is in a consistent state.
36/// - **Failure Handling**:
37/// - If the operation fails or other cases may lead to metadata inconsistency,
38/// the poison key remains in the state store.
39/// - The presence of this key indicates that the resource has encountered an
40/// unrecoverable error and the metadata may be inconsistent.
41/// - New operations on the same resource are rejected until the resource is
42/// manually recovered and the poison key is removed.
43#[async_trait]
44pub trait PoisonStore: Send + Sync {
45 /// Try to put the poison key.
46 ///
47 /// If the poison key already exists with a different value, the operation will fail.
48 async fn try_put_poison(&self, key: String, token: String) -> Result<()>;
49
50 /// Delete the poison key.
51 ///
52 /// If the poison key exists with a different value, the operation will fail.
53 async fn delete_poison(&self, key: String, token: String) -> Result<()>;
54
55 /// Get the poison key.
56 ///
57 /// If the poison key does not exist, the operation will return `None`.
58 async fn get_poison(&self, key: &str) -> Result<Option<String>>;
59}