userver: userver/dist_lock/dist_locked_task.hpp Source File
Loading...
Searching...
No Matches
dist_locked_task.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/dist_lock/dist_locked_task.hpp
4/// @brief @copybrief dist_lock::DistLockedTask
5
6#include <chrono>
7#include <functional>
8#include <memory>
9#include <optional>
10#include <string>
11
12#include <userver/dist_lock/dist_lock_settings.hpp>
13#include <userver/dist_lock/dist_lock_strategy.hpp>
14#include <userver/engine/task/task_base.hpp>
15#include <userver/engine/task/task_processor_fwd.hpp>
16
17USERVER_NAMESPACE_BEGIN
18
19namespace dist_lock {
20namespace impl {
21
22class Locker;
23
24} // namespace impl
25
26// clang-format off
27
28/// @ingroup userver_concurrency
29///
30/// @brief A task that tries to acquire a distributed lock and runs user
31/// callback once while the lock is held.
32///
33/// When dist lock starts, the lock worker tries to take a lock in the
34/// loop. If succeeded, a task is launched that executes the user code.
35/// In the background, dist lock tries to extend the lock. In case of loss of
36/// the lock, the user task is canceled.
37///
38/// ## Example with retrying
39/// @snippet dist_lock/dist_lock_test.cpp Sample distributed locked task Retry
40/// ## Example without retrying
41/// @snippet dist_lock/dist_lock_test.cpp Sample distributed locked task SingleAttempt
42///
43/// @see @ref scripts/docs/en/userver/periodics.md
44/// @see AlwaysBusyDistLockStrategy
45
46// clang-format on
47
48class DistLockedTask final : public engine::TaskBase {
49public:
50 using WorkerFunc = std::function<void()>;
51
52 /// Default constructor.
53 /// Creates an invalid task.
54 DistLockedTask() = default;
55
56 DistLockedTask(DistLockedTask&&) = delete;
57 DistLockedTask& operator=(DistLockedTask&&) = delete;
58
59 DistLockedTask(const DistLockedTask&) = delete;
60 DistLockedTask& operator=(const DistLockedTask&&) = delete;
61
62 ~DistLockedTask();
63
64 /// Creates a DistLockedTask.
65 /// @param name name of the task
66 /// @param worker_func a callback that is started once we've acquired the lock
67 /// and is cancelled when the lock is lost.
68 /// @param settings distributed lock settings
69 /// @param strategy distributed locking strategy
70 /// @param mode distributed lock waiting mode
71 /// @note `worker_func` must honour task cancellation and stop ASAP when
72 /// it is cancelled, otherwise brain split is possible (IOW, two different
73 /// users do work assuming both of them hold the lock, which is not true).
75 std::string name,
76 WorkerFunc worker_func,
77 std::shared_ptr<DistLockStrategyBase> strategy,
78 const DistLockSettings& settings = {},
81 );
82
83 /// Creates a DistLockedTask to be run in a specific engine::TaskProcessor
85 engine::TaskProcessor& task_processor,
86 std::string name,
87 WorkerFunc worker_func,
88 std::shared_ptr<DistLockStrategyBase> strategy,
89 const DistLockSettings& settings = {},
92 );
93
94 /// Returns for how long the lock is held (if held at all). Returned value
95 /// may be less than the real duration.
96 std::optional<std::chrono::steady_clock::duration> GetLockedDuration() const;
97
98 void Get() noexcept(false);
99
100private:
101 DistLockedTask(engine::TaskProcessor&, std::shared_ptr<impl::Locker>, DistLockWaitingMode);
102
103 std::shared_ptr<impl::Locker> locker_ptr_;
104};
105
106} // namespace dist_lock
107
108USERVER_NAMESPACE_END