blob: 0547fbe40154330b079cb8ca27c4ccf632941dfd (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include <vespa/vespalib/stllike/hash_set.h>
namespace storage::distributor {
/**
* In the face of concurrent cluster state changes, cluster topology reconfigurations etc.,
* it's possible for there to be pending mutating operations to nodes that the distributor
* no longer should keep track of. Such operations must therefore be _cancelled_, either
* fully or partially. A CancelScope represents the granularity at which an operation should
* be cancelled.
*
* In the case of one or more nodes becoming unavailable, `fully_cancelled()` will be false
* and `node_is_cancelled(x)` will return whether node `x` is explicitly cancelled.
*
* In the case of ownership transfers, `fully_cancelled()` will be true since the distributor
* should no longer have any knowledge of the bucket. `node_is_cancelled(x)` is always
* implicitly true for all values of `x` for full cancellations.
*/
class CancelScope {
public:
using CancelledNodeSet = vespalib::hash_set<uint16_t>;
private:
CancelledNodeSet _cancelled_nodes;
bool _fully_cancelled;
struct fully_cancelled_ctor_tag {};
explicit CancelScope(fully_cancelled_ctor_tag) noexcept;
explicit CancelScope(CancelledNodeSet nodes) noexcept;
public:
CancelScope();
~CancelScope();
CancelScope(const CancelScope&);
CancelScope& operator=(const CancelScope&);
CancelScope(CancelScope&&) noexcept;
CancelScope& operator=(CancelScope&&) noexcept;
void add_cancelled_node(uint16_t node);
void merge(const CancelScope& other);
[[nodiscard]] bool fully_cancelled() const noexcept { return _fully_cancelled; }
[[nodiscard]] bool is_cancelled() const noexcept {
return (_fully_cancelled || !_cancelled_nodes.empty());
}
[[nodiscard]] bool node_is_cancelled(uint16_t node) const noexcept {
return (fully_cancelled() || _cancelled_nodes.contains(node));
}
[[nodiscard]] const CancelledNodeSet& cancelled_nodes() const noexcept {
return _cancelled_nodes;
}
static CancelScope of_fully_cancelled() noexcept;
static CancelScope of_node_subset(CancelledNodeSet nodes) noexcept;
};
}
|