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 {
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