Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Execution.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2024, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Spawn.hpp"
23#include "util/async/Concepts.hpp"
24#include "util/async/context/impl/Timer.hpp"
25
26#include <boost/asio/spawn.hpp>
27#include <boost/asio/strand.hpp>
28#include <boost/asio/thread_pool.hpp>
29
30namespace util::async::impl {
31
33 template <typename ContextType, SomeOutcome OutcomeType, typename FnType>
34 [[nodiscard]] static auto
35 dispatch(ContextType& ctx, OutcomeType&& outcome, FnType&& fn)
36 {
37 auto op = outcome.getOperation();
38
41 ctx.getExecutor(),
42 [outcome = std::forward<OutcomeType>(outcome),
43 fn = std::forward<FnType>(fn)](auto yield) mutable {
44 if constexpr (SomeStoppableOutcome<OutcomeType>) {
45 auto& stopSource = outcome.getStopSource();
46 std::invoke(
47 std::forward<decltype(fn)>(fn), outcome, stopSource, stopSource[yield]
48 );
49 } else {
50 std::invoke(std::forward<decltype(fn)>(fn), outcome);
51 }
52 }
53 );
54 } else {
55 boost::asio::post(
56 ctx.getExecutor(),
57 [outcome = std::forward<OutcomeType>(outcome),
58 fn = std::forward<FnType>(fn)]() mutable {
59 std::invoke(std::forward<decltype(fn)>(fn), outcome);
60 }
61 );
62 }
63
64 return op;
65 }
66
67 template <typename ContextType, typename FnType>
68 static void
69 post(ContextType& ctx, FnType&& fn)
70 {
71 boost::asio::post(ctx.getExecutor(), [fn = std::forward<FnType>(fn)]() mutable {
72 std::invoke(std::forward<decltype(fn)>(fn));
73 });
74 }
75};
76
78 template <typename ContextType, SomeOutcome OutcomeType, typename FnType>
79 [[nodiscard]] static auto
80 dispatch(ContextType& ctx, OutcomeType&& outcome, FnType&& fn)
81 {
82 auto op = outcome.getOperation();
83
84 boost::asio::post(
85 ctx.getExecutor(),
86 [outcome = std::forward<OutcomeType>(outcome),
87 fn = std::forward<FnType>(fn)]() mutable {
88 if constexpr (SomeStoppableOutcome<OutcomeType>) {
89 auto& stopSource = outcome.getStopSource();
90 std::invoke(
91 std::forward<decltype(fn)>(fn), outcome, stopSource, stopSource.getToken()
92 );
93 } else {
94 std::invoke(std::forward<decltype(fn)>(fn), outcome);
95 }
96 }
97 );
98
99 return op;
100 }
101
102 template <typename ContextType, typename FnType>
103 static void
104 post(ContextType& ctx, FnType&& fn)
105 {
106 boost::asio::post(ctx.getExecutor(), std::forward<FnType>(fn));
107 }
108};
109
111 template <typename ContextType, SomeOutcome OutcomeType, typename FnType>
112 [[nodiscard]] static auto
113 dispatch([[maybe_unused]] ContextType& ctx, OutcomeType outcome, FnType&& fn)
114 {
115 auto op = outcome.getOperation();
116
117 if constexpr (SomeStoppableOutcome<OutcomeType>) {
118 auto& stopSource = outcome.getStopSource();
119 std::invoke(std::forward<FnType>(fn), outcome, stopSource, stopSource.getToken());
120 } else {
121 std::invoke(std::forward<FnType>(fn), outcome);
122 }
123
124 return op;
125 }
126
127 template <typename ContextType, typename FnType>
128 static void
129 post([[maybe_unused]] ContextType& ctx, FnType&& fn)
130 {
131 std::invoke(std::forward<FnType>(fn));
132 }
133};
134
135} // namespace util::async::impl
Specifies the interface for an outcome (promise) that can be stopped.
Definition Concepts.hpp:170
void spawn(Ctx &&ctx, F &&func)
Spawns a coroutine using boost::asio::spawn.
Definition Spawn.hpp:72
Definition Execution.hpp:77
Definition Execution.hpp:32
Definition Execution.hpp:110