@@ -148,6 +148,87 @@ enum class ResolverContext
148
148
NotifyUnsubscribe,
149
149
};
150
150
151
+ // Resume coroutine execution on a worker thread.
152
+ struct await_worker_thread : coro::suspend_always
153
+ {
154
+ void await_suspend (coro::coroutine_handle<> h) const
155
+ {
156
+ std::thread (
157
+ [](coro::coroutine_handle<>&& h) noexcept {
158
+ h.resume ();
159
+ },
160
+ std::move (h))
161
+ .detach ();
162
+ }
163
+ };
164
+
165
+ // Type-erased awaitable, if you want finer grain control.
166
+ class await_async : public coro ::suspend_always
167
+ {
168
+ private:
169
+ struct Concept
170
+ {
171
+ virtual ~Concept () = default ;
172
+
173
+ virtual bool await_ready () const = 0;
174
+ virtual void await_suspend (coro::coroutine_handle<> h) const = 0;
175
+ };
176
+
177
+ template <class T >
178
+ struct Model : Concept
179
+ {
180
+ Model (std::shared_ptr<T>&& pimpl)
181
+ : _pimpl { std::move (pimpl) }
182
+ {
183
+ }
184
+
185
+ bool await_ready () const final
186
+ {
187
+ return _pimpl->await_ready ();
188
+ }
189
+
190
+ void await_suspend (coro::coroutine_handle<> h) const final
191
+ {
192
+ _pimpl->await_suspend (std::move (h));
193
+ }
194
+
195
+ private:
196
+ std::shared_ptr<T> _pimpl;
197
+ };
198
+
199
+ const std::shared_ptr<Concept> _pimpl;
200
+
201
+ public:
202
+ template <class T >
203
+ await_async (std::shared_ptr<T> pimpl)
204
+ : _pimpl { std::make_shared<Model<T>>(std::move (pimpl)) }
205
+ {
206
+ }
207
+
208
+ await_async (std::launch launch)
209
+ : _pimpl { ((launch & std::launch::async) == std::launch::async)
210
+ ? std::static_pointer_cast<Concept>(std::make_shared<Model<await_worker_thread>>(
211
+ std::make_shared<await_worker_thread>()))
212
+ : std::static_pointer_cast<Concept>(std::make_shared<Model<coro::suspend_never>>(
213
+ std::make_shared<coro::suspend_never>())) }
214
+ {
215
+ }
216
+
217
+ bool await_ready () const
218
+ {
219
+ return _pimpl->await_ready ();
220
+ }
221
+
222
+ void await_suspend (coro::coroutine_handle<> h) const
223
+ {
224
+ _pimpl->await_suspend (std::move (h));
225
+ }
226
+
227
+ constexpr void await_resume () const noexcept
228
+ {
229
+ }
230
+ };
231
+
151
232
// Pass a common bundle of parameters to all of the generated Object::getField accessors in a
152
233
// SelectionSet
153
234
struct SelectionSetParams
@@ -171,7 +252,7 @@ struct SelectionSetParams
171
252
std::optional<field_path> errorPath;
172
253
173
254
// Async launch policy for sub-field resolvers.
174
- const std::launch launch = std::launch::deferred;
255
+ const await_async launch { std::launch::deferred } ;
175
256
};
176
257
177
258
// Pass a common bundle of parameters to all of the generated Object::getField accessors.
@@ -557,24 +638,6 @@ class Object : public std::enable_shared_from_this<Object>
557
638
ResolverMap _resolvers;
558
639
};
559
640
560
- // Resume coroutine execution on a worker thread. This is used internally to implement the APIs
561
- // which can take std::launch::async as a parameter.
562
- class await_async
563
- {
564
- public:
565
- GRAPHQLSERVICE_EXPORT explicit await_async (std::launch launch) noexcept ;
566
-
567
- GRAPHQLSERVICE_EXPORT bool await_ready () const noexcept ;
568
- GRAPHQLSERVICE_EXPORT void await_suspend (coro::coroutine_handle<> h) const ;
569
-
570
- constexpr void await_resume () const noexcept
571
- {
572
- }
573
-
574
- private:
575
- const std::launch _launch;
576
- };
577
-
578
641
// Convert the result of a resolver function with chained type modifiers that add nullable or
579
642
// list wrappers. This is the inverse of ModifiedArgument for output types instead of input types.
580
643
template <typename Type>
@@ -622,7 +685,7 @@ struct ModifiedResult
622
685
static_assert (std::is_same_v<std::shared_ptr<Type>, typename ResultTraits<Type>::type>,
623
686
" this is the derived object type" );
624
687
625
- co_await await_async { params.launch } ;
688
+ co_await params.launch ;
626
689
627
690
auto awaitedResult = co_await ModifiedResult<Object>::convert (
628
691
std::static_pointer_cast<Object>(co_await result),
@@ -650,7 +713,7 @@ struct ModifiedResult
650
713
convert (
651
714
typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
652
715
{
653
- co_await await_async { params.launch } ;
716
+ co_await params.launch ;
654
717
655
718
auto awaitedResult = co_await std::move (result);
656
719
@@ -677,7 +740,7 @@ struct ModifiedResult
677
740
typename ResultTraits<Type, Modifier, Other...>::type>,
678
741
" this is the optional version" );
679
742
680
- co_await await_async { params.launch } ;
743
+ co_await params.launch ;
681
744
682
745
auto awaitedResult = co_await std::move (result);
683
746
@@ -700,7 +763,7 @@ struct ModifiedResult
700
763
std::vector<AwaitableResolver> children;
701
764
const auto parentPath = params.errorPath ;
702
765
703
- co_await await_async { params.launch } ;
766
+ co_await params.launch ;
704
767
705
768
auto awaitedResult = co_await std::move (result);
706
769
@@ -743,7 +806,7 @@ struct ModifiedResult
743
806
{
744
807
try
745
808
{
746
- co_await await_async { params.launch } ;
809
+ co_await params.launch ;
747
810
748
811
auto value = co_await std::move (child);
749
812
@@ -796,7 +859,7 @@ struct ModifiedResult
796
859
797
860
try
798
861
{
799
- co_await await_async { params.launch } ;
862
+ co_await params.launch ;
800
863
document.data = pendingResolver (co_await result, params);
801
864
}
802
865
catch (schema_exception& scx)
@@ -943,17 +1006,17 @@ class Request : public std::enable_shared_from_this<Request>
943
1006
944
1007
GRAPHQLSERVICE_EXPORT response::AwaitableValue resolve (std::shared_ptr<RequestState> state,
945
1008
peg::ast& query, std::string_view operationName, response::Value variables) const ;
946
- GRAPHQLSERVICE_EXPORT response::AwaitableValue resolve (std::launch launch,
1009
+ GRAPHQLSERVICE_EXPORT response::AwaitableValue resolve (await_async launch,
947
1010
std::shared_ptr<RequestState> state, peg::ast& query, std::string_view operationName,
948
1011
response::Value variables) const ;
949
1012
950
1013
GRAPHQLSERVICE_EXPORT SubscriptionKey subscribe (
951
1014
SubscriptionParams&& params, SubscriptionCallback&& callback);
952
1015
GRAPHQLSERVICE_EXPORT AwaitableSubscribe subscribe (
953
- std::launch launch, SubscriptionParams&& params, SubscriptionCallback&& callback);
1016
+ await_async launch, SubscriptionParams&& params, SubscriptionCallback&& callback);
954
1017
955
1018
GRAPHQLSERVICE_EXPORT void unsubscribe (SubscriptionKey key);
956
- GRAPHQLSERVICE_EXPORT AwaitableUnsubscribe unsubscribe (std::launch launch, SubscriptionKey key);
1019
+ GRAPHQLSERVICE_EXPORT AwaitableUnsubscribe unsubscribe (await_async launch, SubscriptionKey key);
957
1020
958
1021
GRAPHQLSERVICE_EXPORT void deliver (
959
1022
const SubscriptionName& name, const std::shared_ptr<Object>& subscriptionObject) const ;
@@ -970,17 +1033,17 @@ class Request : public std::enable_shared_from_this<Request>
970
1033
const SubscriptionFilterCallback& applyDirectives,
971
1034
std::shared_ptr<Object> subscriptionObject) const ;
972
1035
973
- GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (std::launch launch, const SubscriptionName& name,
1036
+ GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
974
1037
std::shared_ptr<Object> subscriptionObject) const ;
975
- GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (std::launch launch, const SubscriptionName& name,
1038
+ GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
976
1039
const SubscriptionArguments& arguments, std::shared_ptr<Object> subscriptionObject) const ;
977
- GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (std::launch launch, const SubscriptionName& name,
1040
+ GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
978
1041
const SubscriptionArguments& arguments, const SubscriptionArguments& directives,
979
1042
std::shared_ptr<Object> subscriptionObject) const ;
980
- GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (std::launch launch, const SubscriptionName& name,
1043
+ GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
981
1044
const SubscriptionFilterCallback& applyArguments,
982
1045
std::shared_ptr<Object> subscriptionObject) const ;
983
- GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (std::launch launch, const SubscriptionName& name,
1046
+ GRAPHQLSERVICE_EXPORT AwaitableDeliver deliver (await_async launch, const SubscriptionName& name,
984
1047
const SubscriptionFilterCallback& applyArguments,
985
1048
const SubscriptionFilterCallback& applyDirectives,
986
1049
std::shared_ptr<Object> subscriptionObject) const ;
0 commit comments