Skip to content

Commit 78513c6

Browse files
committed
Add a client_benchmark utility to compare with dynamic parse/serialize
1 parent d92d8f6 commit 78513c6

File tree

5 files changed

+505
-2
lines changed

5 files changed

+505
-2
lines changed

samples/CMakeLists.txt

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,30 @@ if(GRAPHQL_UPDATE_SAMPLES)
147147
WORKING_DIRECTORY client
148148
COMMENT "Generating SubscribeClient samples")
149149

150+
# client.benchmark.today.graphql
151+
add_custom_command(
152+
OUTPUT
153+
${CMAKE_CURRENT_BINARY_DIR}/client/BenchmarkClient.cpp
154+
${CMAKE_CURRENT_BINARY_DIR}/client/BenchmarkClient.h
155+
COMMAND clientgen --schema="${CMAKE_CURRENT_SOURCE_DIR}/schema.today.graphql" --request="${CMAKE_CURRENT_SOURCE_DIR}/client.benchmark.today.graphql" --prefix="Benchmark" --namespace="benchmark"
156+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
157+
BenchmarkClient.cpp
158+
BenchmarkClient.h
159+
${CMAKE_CURRENT_SOURCE_DIR}/client
160+
DEPENDS clientgen schema.today.graphql client.benchmark.today.graphql
161+
WORKING_DIRECTORY client
162+
COMMENT "Generating BenchmarkClient samples")
163+
150164
add_custom_target(update_client_samples ALL
151165
DEPENDS
152166
${CMAKE_CURRENT_BINARY_DIR}/client/QueryClient.cpp
153167
${CMAKE_CURRENT_BINARY_DIR}/client/QueryClient.h
154168
${CMAKE_CURRENT_BINARY_DIR}/client/MutateClient.cpp
155169
${CMAKE_CURRENT_BINARY_DIR}/client/MutateClient.h
156170
${CMAKE_CURRENT_BINARY_DIR}/client/SubscribeClient.cpp
157-
${CMAKE_CURRENT_BINARY_DIR}/client/SubscribeClient.h)
171+
${CMAKE_CURRENT_BINARY_DIR}/client/SubscribeClient.h
172+
${CMAKE_CURRENT_BINARY_DIR}/client/BenchmarkClient.cpp
173+
${CMAKE_CURRENT_BINARY_DIR}/client/BenchmarkClient.h)
158174
endif()
159175
endif()
160176

@@ -234,14 +250,16 @@ if(WIN32 AND BUILD_SHARED_LIBS)
234250
$<TARGET_FILE:graphqljson>
235251
$<TARGET_FILE:graphqlpeg>
236252
$<TARGET_FILE:graphqlresponse>
253+
$<TARGET_FILE:graphqlclient>
237254
${CMAKE_CURRENT_BINARY_DIR}
238255
COMMAND ${CMAKE_COMMAND} -E touch copied_sample_dlls
239256
DEPENDS
240257
graphqlservice
241258
graphqlintrospection
242259
graphqljson
243260
graphqlpeg
244-
graphqlresponse)
261+
graphqlresponse
262+
graphqlclient)
245263

246264
add_custom_target(copy_sample_dlls DEPENDS copied_sample_dlls)
247265

@@ -339,3 +357,20 @@ if(GRAPHQL_UPDATE_SAMPLES AND GRAPHQL_BUILD_CLIENTGEN)
339357
# wait for the sample update to complete
340358
add_dependencies(todayclient update_client_samples)
341359
endif()
360+
361+
# client_benchmark
362+
add_executable(client_benchmark
363+
${CMAKE_CURRENT_SOURCE_DIR}/client/BenchmarkClient.cpp
364+
client/benchmark.cpp)
365+
target_link_libraries(client_benchmark PRIVATE
366+
separategraphql
367+
todayclient
368+
graphqlclient)
369+
target_include_directories(client_benchmark PRIVATE
370+
${CMAKE_CURRENT_SOURCE_DIR}/../include
371+
${CMAKE_CURRENT_SOURCE_DIR}/../PEGTL/include
372+
${CMAKE_CURRENT_SOURCE_DIR}/client)
373+
374+
if(WIN32 AND BUILD_SHARED_LIBS)
375+
add_dependencies(client_benchmark copy_sample_dlls)
376+
endif()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
query {
5+
appointments {
6+
pageInfo {
7+
hasNextPage
8+
}
9+
edges {
10+
node {
11+
id
12+
when
13+
subject
14+
isNow
15+
}
16+
}
17+
}
18+
}

samples/client/BenchmarkClient.cpp

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
// WARNING! Do not edit this file manually, your changes will be overwritten.
5+
6+
#include "BenchmarkClient.h"
7+
8+
#include "graphqlservice/GraphQLClient.h"
9+
10+
#include <algorithm>
11+
#include <array>
12+
#include <stdexcept>
13+
#include <sstream>
14+
#include <string_view>
15+
16+
using namespace std::literals;
17+
18+
namespace graphql::client {
19+
20+
using namespace query::Query;
21+
22+
template <>
23+
Response::appointments_AppointmentConnection::pageInfo_PageInfo ModifiedResponse<Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(response::Value&& response)
24+
{
25+
Response::appointments_AppointmentConnection::pageInfo_PageInfo result;
26+
27+
if (response.type() == response::Type::Map)
28+
{
29+
auto members = response.release<response::MapType>();
30+
31+
for (auto& member : members)
32+
{
33+
if (member.first == R"js(hasNextPage)js"sv)
34+
{
35+
result.hasNextPage = ModifiedResponse<response::BooleanType>::parse(std::move(member.second));
36+
continue;
37+
}
38+
}
39+
}
40+
41+
return result;
42+
}
43+
44+
template <>
45+
Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment ModifiedResponse<Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse(response::Value&& response)
46+
{
47+
Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment result;
48+
49+
if (response.type() == response::Type::Map)
50+
{
51+
auto members = response.release<response::MapType>();
52+
53+
for (auto& member : members)
54+
{
55+
if (member.first == R"js(id)js"sv)
56+
{
57+
result.id = ModifiedResponse<response::IdType>::parse(std::move(member.second));
58+
continue;
59+
}
60+
if (member.first == R"js(when)js"sv)
61+
{
62+
result.when = ModifiedResponse<response::Value>::parse<TypeModifier::Nullable>(std::move(member.second));
63+
continue;
64+
}
65+
if (member.first == R"js(subject)js"sv)
66+
{
67+
result.subject = ModifiedResponse<response::StringType>::parse<TypeModifier::Nullable>(std::move(member.second));
68+
continue;
69+
}
70+
if (member.first == R"js(isNow)js"sv)
71+
{
72+
result.isNow = ModifiedResponse<response::BooleanType>::parse(std::move(member.second));
73+
continue;
74+
}
75+
}
76+
}
77+
78+
return result;
79+
}
80+
81+
template <>
82+
Response::appointments_AppointmentConnection::edges_AppointmentEdge ModifiedResponse<Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse(response::Value&& response)
83+
{
84+
Response::appointments_AppointmentConnection::edges_AppointmentEdge result;
85+
86+
if (response.type() == response::Type::Map)
87+
{
88+
auto members = response.release<response::MapType>();
89+
90+
for (auto& member : members)
91+
{
92+
if (member.first == R"js(node)js"sv)
93+
{
94+
result.node = ModifiedResponse<Response::appointments_AppointmentConnection::edges_AppointmentEdge::node_Appointment>::parse<TypeModifier::Nullable>(std::move(member.second));
95+
continue;
96+
}
97+
}
98+
}
99+
100+
return result;
101+
}
102+
103+
template <>
104+
Response::appointments_AppointmentConnection ModifiedResponse<Response::appointments_AppointmentConnection>::parse(response::Value&& response)
105+
{
106+
Response::appointments_AppointmentConnection result;
107+
108+
if (response.type() == response::Type::Map)
109+
{
110+
auto members = response.release<response::MapType>();
111+
112+
for (auto& member : members)
113+
{
114+
if (member.first == R"js(pageInfo)js"sv)
115+
{
116+
result.pageInfo = ModifiedResponse<Response::appointments_AppointmentConnection::pageInfo_PageInfo>::parse(std::move(member.second));
117+
continue;
118+
}
119+
if (member.first == R"js(edges)js"sv)
120+
{
121+
result.edges = ModifiedResponse<Response::appointments_AppointmentConnection::edges_AppointmentEdge>::parse<TypeModifier::Nullable, TypeModifier::List, TypeModifier::Nullable>(std::move(member.second));
122+
continue;
123+
}
124+
}
125+
}
126+
127+
return result;
128+
}
129+
130+
namespace query::Query {
131+
132+
const std::string& GetRequestText() noexcept
133+
{
134+
static const auto s_request = R"gql(
135+
# Copyright (c) Microsoft Corporation. All rights reserved.
136+
# Licensed under the MIT License.
137+
138+
query {
139+
appointments {
140+
pageInfo {
141+
hasNextPage
142+
}
143+
edges {
144+
node {
145+
id
146+
when
147+
subject
148+
isNow
149+
}
150+
}
151+
}
152+
}
153+
)gql"s;
154+
155+
return s_request;
156+
}
157+
158+
const peg::ast& GetRequestObject() noexcept
159+
{
160+
static const auto s_request = []() noexcept {
161+
auto ast = peg::parseString(GetRequestText());
162+
163+
// This has already been validated against the schema by clientgen.
164+
ast.validated = true;
165+
166+
return ast;
167+
}();
168+
169+
return s_request;
170+
}
171+
172+
Response parseResponse(response::Value&& response)
173+
{
174+
Response result;
175+
176+
if (response.type() == response::Type::Map)
177+
{
178+
auto members = response.release<response::MapType>();
179+
180+
for (auto& member : members)
181+
{
182+
if (member.first == R"js(appointments)js"sv)
183+
{
184+
result.appointments = ModifiedResponse<Response::appointments_AppointmentConnection>::parse(std::move(member.second));
185+
continue;
186+
}
187+
}
188+
}
189+
190+
return result;
191+
}
192+
193+
} // namespace query::Query
194+
} // namespace graphql::client

samples/client/BenchmarkClient.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
// WARNING! Do not edit this file manually, your changes will be overwritten.
5+
6+
#pragma once
7+
8+
#ifndef BENCHMARKCLIENT_H
9+
#define BENCHMARKCLIENT_H
10+
11+
#include "graphqlservice/GraphQLParse.h"
12+
#include "graphqlservice/GraphQLResponse.h"
13+
14+
#include "graphqlservice/internal/Version.h"
15+
16+
// Check if the library version is compatible with clientgen 3.6.0
17+
static_assert(graphql::internal::MajorVersion == 3, "regenerate with clientgen: major version mismatch");
18+
static_assert(graphql::internal::MinorVersion == 6, "regenerate with clientgen: minor version mismatch");
19+
20+
#include <optional>
21+
#include <string>
22+
#include <vector>
23+
24+
/// <summary>
25+
/// Operation: query (unnamed)
26+
/// </summary>
27+
/// <code class="language-graphql">
28+
/// # Copyright (c) Microsoft Corporation. All rights reserved.
29+
/// # Licensed under the MIT License.
30+
///
31+
/// query {
32+
/// appointments {
33+
/// pageInfo {
34+
/// hasNextPage
35+
/// }
36+
/// edges {
37+
/// node {
38+
/// id
39+
/// when
40+
/// subject
41+
/// isNow
42+
/// }
43+
/// }
44+
/// }
45+
/// }
46+
/// </code>
47+
namespace graphql::client::query::Query {
48+
49+
// Return the original text of the request document.
50+
const std::string& GetRequestText() noexcept;
51+
52+
// Return a pre-parsed, pre-validated request object.
53+
const peg::ast& GetRequestObject() noexcept;
54+
55+
struct Response
56+
{
57+
struct appointments_AppointmentConnection
58+
{
59+
struct pageInfo_PageInfo
60+
{
61+
response::BooleanType hasNextPage {};
62+
};
63+
64+
struct edges_AppointmentEdge
65+
{
66+
struct node_Appointment
67+
{
68+
response::IdType id {};
69+
std::optional<response::Value> when {};
70+
std::optional<response::StringType> subject {};
71+
response::BooleanType isNow {};
72+
};
73+
74+
std::optional<node_Appointment> node {};
75+
};
76+
77+
pageInfo_PageInfo pageInfo {};
78+
std::optional<std::vector<std::optional<edges_AppointmentEdge>>> edges {};
79+
};
80+
81+
appointments_AppointmentConnection appointments {};
82+
};
83+
84+
Response parseResponse(response::Value&& response);
85+
86+
} // namespace graphql::client::query::Query
87+
88+
#endif // BENCHMARKCLIENT_H

0 commit comments

Comments
 (0)