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/// @ingroup userver_concurrency
27///
28/// @brief A task that tries to acquire a distributed lock and runs user
29/// callback once while the lock is held.
30///
31/// When dist lock starts, the lock worker tries to take a lock in the
32/// loop. If succeeded, a task is launched that executes the user code.
33/// In the background, dist lock tries to extend the lock. In case of loss of
34/// the lock, the user task is canceled.
35///
36/// ## Example with retrying
37/// @snippet dist_lock/dist_lock_test.cpp Sample distributed locked task Retry
38/// ## Example without retrying
39/// @snippet dist_lock/dist_lock_test.cpp Sample distributed locked task SingleAttempt
40///
41/// @see @ref scripts/docs/en/userver/periodics.md
42/// @see AlwaysBusyDistLockStrategy
43class DistLockedTask final : public engine::TaskBase {
44public:
45 using WorkerFunc = std::function<void()>;
46
47 /// Default constructor.
48 /// Creates an invalid task.
49 DistLockedTask() = default;
50
51 DistLockedTask(DistLockedTask&&) = delete;
52 DistLockedTask& operator=(DistLockedTask&&) = delete;
53
54 DistLockedTask(const DistLockedTask&) = delete;
55 DistLockedTask& operator=(const DistLockedTask&&) = delete;
56
57 ~DistLockedTask();
58
59 /// Creates a DistLockedTask.
60 /// @param name name of the task
61 /// @param worker_func a callback that is started once we've acquired the lock
62 /// and is cancelled when the lock is lost.
63 /// @param settings distributed lock settings
64 /// @param strategy distributed locking strategy
65 /// @param mode distributed lock waiting mode
66 /// @param retry_mode run task continuously or once (needed mainly for tests)
67 /// @note `worker_func` must honour task cancellation and stop ASAP when
68 /// it is cancelled, otherwise brain split is possible (IOW, two different
69 /// users do work assuming both of them hold the lock, which is not true).
71 std::string name,
72 WorkerFunc worker_func,
73 std::shared_ptr<DistLockStrategyBase> strategy,
74 const DistLockSettings& settings = {},
77 );
78
79 /// Creates a DistLockedTask to be run in a specific engine::TaskProcessor
81 engine::TaskProcessor& task_processor,
82 std::string name,
83 WorkerFunc worker_func,
84 std::shared_ptr<DistLockStrategyBase> strategy,
85 const DistLockSettings& settings = {},
88 );
89
90 /// Returns for how long the lock is held (if held at all). Returned value
91 /// may be less than the real duration.
92 std::optional<std::chrono::steady_clock::duration> GetLockedDuration() const;
93
94 void Get() noexcept(false);
95
96private:
97 DistLockedTask(engine::TaskProcessor&, std::shared_ptr<impl::Locker>, DistLockWaitingMode);
98
99 std::shared_ptr<impl::Locker> locker_ptr_;
100};
101
102} // namespace dist_lock
103
104USERVER_NAMESPACE_END