NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
host_loop.h
Go to the documentation of this file.
1
24#pragma once
25
26#include <neograph/api.h>
27#include <runtime/host.h>
28
29#include <asio/any_io_executor.hpp>
30#include <asio/awaitable.hpp>
31#include <asio/co_spawn.hpp>
32#include <asio/execution_context.hpp>
33#include <asio/io_context.hpp>
34#include <asio/prefer.hpp>
35#include <asio/query.hpp>
36#include <asio/require.hpp>
37
38#include <chrono>
39#include <cstddef>
40#include <exception>
41#include <functional>
42#include <memory>
43#include <type_traits>
44#include <utility>
45
46namespace neograph::async {
47
48namespace detail {
49class HostLoopCore;
51NEOGRAPH_API void host_loop_wake(HostLoopCore* core) noexcept;
52
56template <typename Executor>
58public:
59 PumpedExecutor(Executor executor, HostLoopCore* core) noexcept
60 : executor_(std::move(executor)), core_(core) {}
61
62 template <typename Function>
63 void execute(Function&& function) const {
64 executor_.execute(std::forward<Function>(function));
65 host_loop_wake(core_);
66 }
67
68 template <typename Property>
69 auto query(const Property& property) const
70 noexcept(noexcept(asio::query(std::declval<const Executor&>(), property)))
71 -> decltype(asio::query(std::declval<const Executor&>(), property)) {
72 return asio::query(executor_, property);
73 }
74
75 template <typename Property>
76 requires asio::can_require<const Executor&, const Property&>::value
77 auto require(const Property& property) const
79 return {asio::require(executor_, property), core_};
80 }
81
82 template <typename Property>
83 requires asio::can_prefer<const Executor&, const Property&>::value
84 auto prefer(const Property& property) const
86 return {asio::prefer(executor_, property), core_};
87 }
88
89 friend bool operator==(const PumpedExecutor& left, const PumpedExecutor& right) noexcept {
90 return left.core_ == right.core_ && left.executor_ == right.executor_;
91 }
92 friend bool operator!=(const PumpedExecutor& left, const PumpedExecutor& right) noexcept {
93 return !(left == right);
94 }
95
96private:
97 Executor executor_;
98 HostLoopCore* core_;
99};
100} // namespace detail
101
102struct HostLoopOptions {
105 std::size_t turn_handlers = 256;
108 std::function<void(std::exception_ptr)> on_error;
109};
110
111class NEOGRAPH_API HostLoop {
112public:
113 using Options = HostLoopOptions;
114
118 explicit HostLoop(std::shared_ptr<sp::runtime::Executor> host, Options options = {});
120 ~HostLoop();
121 HostLoop(const HostLoop&) = delete;
122 HostLoop& operator=(const HostLoop&) = delete;
123
125 asio::any_io_executor executor();
126
129 template <typename T, typename Done>
130 void spawn(asio::awaitable<T> work, Done done) {
131 asio::co_spawn(executor(), std::move(work), std::move(done));
132 wake();
133 }
134
136 void wake() noexcept;
138 void wake_at(sp::runtime::SteadyTime at) noexcept;
140 void forget_at(sp::runtime::SteadyTime at) noexcept;
141
143 bool idle() const noexcept;
144
145private:
146 std::shared_ptr<detail::HostLoopCore> core_;
147};
148
154NEOGRAPH_API void note_deadline(const asio::any_io_executor& executor,
155 std::chrono::steady_clock::time_point at) noexcept;
156
159NEOGRAPH_API void forget_deadline(const asio::any_io_executor& executor,
160 std::chrono::steady_clock::time_point at) noexcept;
161
164NEOGRAPH_API bool is_host_pumped(const asio::any_io_executor& executor) noexcept;
165
168NEOGRAPH_API bool in_host_turn() noexcept;
169
170} // namespace neograph::async
NEOGRAPH_API export/import macro for shared-library builds.
The io_context's executor, plus a turn of the loop whenever work is executed on it.
Definition host_loop.h:57
NEOGRAPH_API void host_loop_wake(HostLoopCore *core) noexcept
Schedules a turn of the loop. Does nothing once the loop is closed.