userver: userver/storages/mongo/dist_lock_component_base.hpp Source File
Loading...
Searching...
No Matches
dist_lock_component_base.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/mongo/dist_lock_component_base.hpp
4/// @brief @copybrief storages::mongo::DistLockComponentBase
5
6#include <userver/components/component_base.hpp>
7#include <userver/dist_lock/dist_locked_worker.hpp>
8#include <userver/storages/mongo/collection.hpp>
9#include <userver/storages/mongo/dist_lock_strategy.hpp>
10#include <userver/utils/statistics/entry.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace storages::mongo {
15
16/// @ingroup userver_components userver_base_classes
17///
18/// @brief Base class for mongo-based distlock worker components
19///
20/// A component that implements a distlock with lock in Mongo. Inherit from
21/// DistLockComponentBase and implement DoWork(). Lock options are configured in static config.
22///
23/// Mongo might not perform well on a high load, so you might want to use
24/// postgres-based distlock storages::postgres::DistLockComponentBase instead.
25/// @see storages::postgres::DistLockComponentBase
26///
27/// ## Cancellation checks
28/// Functions engine::current_task::ShouldCancel(),
29/// engine::InterruptibleSleepFor(), engine::InterruptibleSleepUntil() and
30/// engine::current_task::CancellationPoint() check for task cancellation.
31/// Overridden DistLockComponentBase::DoWork must use the above functions to
32/// honour task cancellation and stop ASAP when it is cancelled.
33///
34/// ## Static configuration example:
35///
36/// ```yaml
37/// example-distlock:
38/// lockname: master
39/// mongo-timeout: 1s
40/// lock-ttl: 10s
41/// ```
42///
43/// ## Static options of storages::mongo::DistLockComponentBase :
44/// @include{doc} scripts/docs/en/components_schema/mongo/src/storages/mongo/dist_lock_component_base.md
45///
46/// Options inherited from @ref components::ComponentBase :
47/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
48///
49/// @see @ref scripts/docs/en/userver/periodics.md
51public:
52 DistLockComponentBase(
53 const components::ComponentConfig&,
54 const components::ComponentContext&,
55 storages::mongo::Collection
56 );
57
58 ~DistLockComponentBase() override;
59
60 dist_lock::DistLockedWorker& GetWorker();
61
62 /// @note In testsuite always returns `true`, because there is only one host.
63 bool OwnsLock() const noexcept;
64
65 static yaml_config::Schema GetStaticConfigSchema();
66
67protected:
68 /// Override this function with anything that must be done under the mongo
69 /// lock.
70 ///
71 /// ## Example implementation
72 ///
73 /// @code
74 /// void MyDistLockComponent::DoWork()
75 /// {
76 /// while (!engine::ShouldCancel())
77 /// {
78 /// // Start a new trace_id
79 /// auto span = tracing::Span::MakeRootSpan("my-dist-lock");
80 ///
81 /// // If Foo() or other function in DoWork() throws an exception,
82 /// // DoWork() will be restarted in `restart-delay` seconds.
83 /// Foo();
84 ///
85 /// // Check for cancellation after cpu-intensive Foo().
86 /// // You must check for cancellation at least every `lock-ttl`
87 /// // seconds to have time to notice lock prolongation failure.
88 /// if (engine::ShouldCancel()) break;
89 ///
90 /// Bar();
91 /// }
92 /// }
93 /// @endcode
94 ///
95 /// @note `DoWork` must honour task cancellation and stop ASAP when
96 /// it is cancelled, otherwise brain split is possible (IOW, two different
97 /// users do work assuming both of them hold the lock, which is not true).
98 virtual void DoWork() = 0;
99
100 /// Override this function to provide custom testsuite handler.
101 virtual void DoWorkTestsuite() { DoWork(); }
102
103 /// Must be called in constructor
104 void Start();
105
106 /// Must be called in destructor
107 void Stop();
108
109private:
110 std::unique_ptr<dist_lock::DistLockedWorker> worker_;
111 bool testsuite_enabled_{false};
112
113 // Subscriptions must be the last fields.
114 utils::statistics::Entry statistics_holder_;
115};
116
117} // namespace storages::mongo
118
119USERVER_NAMESPACE_END