userver: userver/dist_lock/dist_locked_task.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 {
49 public:
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).
74 DistLockedTask(std::string name, WorkerFunc worker_func,
75 std::shared_ptr<DistLockStrategyBase> strategy,
76 const DistLockSettings& settings = {},
79
80 /// Creates a DistLockedTask to be run in a specific engine::TaskProcessor
81 DistLockedTask(engine::TaskProcessor& task_processor, std::string name,
82 WorkerFunc worker_func,
83 std::shared_ptr<DistLockStrategyBase> strategy,
84 const DistLockSettings& settings = {},
87
88 /// Returns for how long the lock is held (if held at all). Returned value
89 /// may be less than the real duration.
90 std::optional<std::chrono::steady_clock::duration> GetLockedDuration() const;
91
92 void Get() noexcept(false);
93
94 private:
95 DistLockedTask(engine::TaskProcessor&, std::shared_ptr<impl::Locker>,
97
98 std::shared_ptr<impl::Locker> locker_ptr_;
99};
100
101} // namespace dist_lock
102
103USERVER_NAMESPACE_END