Lightweight 0.20260617.0
Loading...
Searching...
No Matches
Backend.hpp
1// SPDX-License-Identifier: Apache-2.0
2#pragma once
3
4#include "Async.hpp"
5#include "Executor.hpp"
6#include "StrandExecutor.hpp"
7
8#include <stop_token>
9#include <utility>
10
11namespace Lightweight::Async
12{
13
14/// Per-connection asynchronous execution backend.
15///
16/// A backend owns (or references) the execution context used to run a connection's blocking
17/// ODBC work and to resume the awaiting coroutine. Currently the only implementation is
18/// @ref ThreadOffloadBackend (portable; offloads to a worker thread). A native event backend
19/// (Windows + SQL Server) is planned behind this same interface.
20///
21/// The backend is selected once per connection (see @c SqlConnection::EnableAsync) and used by
22/// all of that connection's async methods.
24{
25 public:
26 IAsyncBackend() = default;
27 IAsyncBackend(IAsyncBackend const&) = delete;
28 IAsyncBackend& operator=(IAsyncBackend const&) = delete;
29 IAsyncBackend(IAsyncBackend&&) = delete;
30 IAsyncBackend& operator=(IAsyncBackend&&) = delete;
31 virtual ~IAsyncBackend() = default;
32
33 /// The serializing executor for this connection; blocking work is offloaded here so the
34 /// connection's ODBC handle is only ever touched by one thread at a time.
35 [[nodiscard]] virtual StrandExecutor& Strand() noexcept = 0;
36
37 /// The scheduler used to resume coroutines after a blocking step completes (typically the
38 /// application's run loop).
39 [[nodiscard]] virtual IResumeScheduler& ResumeScheduler() noexcept = 0;
40};
41
42/// Runs a whole synchronous operation on @p backend's strand, resuming on its scheduler.
43///
44/// This is the coarse-grained workhorse used by the high-level async methods: the entire
45/// synchronous body (parameter binding, the ODBC call, and post-processing) runs as one
46/// closure on the connection's strand — never split across threads — and the coroutine
47/// resumes on the app thread with the result.
48///
49/// @tparam F A callable invocable with no arguments.
50/// @param backend The connection's async backend.
51/// @param fn The synchronous operation to run (consumed).
52/// @param token Optional cancellation token (a default-constructed @c std::stop_token is non-cancellable).
53/// @return A Task producing @p fn's result.
54template <typename F>
55[[nodiscard]] Task<detail::OffloadResult<F>> RunAsync(IAsyncBackend& backend, F fn, std::stop_token token = {})
56{
57 return Async(backend.Strand(), backend.ResumeScheduler(), std::move(fn), std::move(token));
58}
59
60} // namespace Lightweight::Async
virtual IResumeScheduler & ResumeScheduler() noexcept=0
virtual StrandExecutor & Strand() noexcept=0