Skip to content

Commit 697efa9

Browse files
committed
Consolidate TodayMock services and protect async loaders with mutex
1 parent 99fbc63 commit 697efa9

File tree

8 files changed

+325
-533
lines changed

8 files changed

+325
-533
lines changed

samples/client/benchmark.cpp

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,55 +16,6 @@ using namespace graphql;
1616

1717
using namespace std::literals;
1818

19-
namespace {
20-
21-
response::IdType binAppointmentId;
22-
response::IdType binTaskId;
23-
response::IdType binFolderId;
24-
25-
} // namespace
26-
27-
std::shared_ptr<today::Operations> buildService()
28-
{
29-
std::string fakeAppointmentId("fakeAppointmentId");
30-
binAppointmentId.resize(fakeAppointmentId.size());
31-
std::copy(fakeAppointmentId.cbegin(), fakeAppointmentId.cend(), binAppointmentId.begin());
32-
33-
std::string fakeTaskId("fakeTaskId");
34-
binTaskId.resize(fakeTaskId.size());
35-
std::copy(fakeTaskId.cbegin(), fakeTaskId.cend(), binTaskId.begin());
36-
37-
std::string fakeFolderId("fakeFolderId");
38-
binFolderId.resize(fakeFolderId.size());
39-
std::copy(fakeFolderId.cbegin(), fakeFolderId.cend(), binFolderId.begin());
40-
41-
auto query = std::make_shared<today::Query>(
42-
[]() -> std::vector<std::shared_ptr<today::Appointment>> {
43-
return { std::make_shared<today::Appointment>(std::move(binAppointmentId),
44-
"tomorrow",
45-
"Lunch?",
46-
false) };
47-
},
48-
[]() -> std::vector<std::shared_ptr<today::Task>> {
49-
return { std::make_shared<today::Task>(std::move(binTaskId), "Don't forget", true) };
50-
},
51-
[]() -> std::vector<std::shared_ptr<today::Folder>> {
52-
return { std::make_shared<today::Folder>(std::move(binFolderId), "\"Fake\" Inbox", 3) };
53-
});
54-
auto mutation = std::make_shared<today::Mutation>(
55-
[](today::CompleteTaskInput&& input) -> std::shared_ptr<today::CompleteTaskPayload> {
56-
return std::make_shared<today::CompleteTaskPayload>(
57-
std::make_shared<today::Task>(std::move(input.id),
58-
"Mutated Task!",
59-
*(input.isComplete)),
60-
std::move(input.clientMutationId));
61-
});
62-
auto subscription = std::make_shared<today::Subscription>();
63-
auto service = std::make_shared<today::Operations>(query, mutation, subscription);
64-
65-
return service;
66-
}
67-
6819
void outputOverview(
6920
size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept
7021
{
@@ -126,7 +77,8 @@ int main(int argc, char** argv)
12677

12778
std::cout << "Iterations: " << iterations << std::endl;
12879

129-
auto service = buildService();
80+
const auto mockService = today::mock_service();
81+
const auto& service = mockService->service;
13082
std::vector<std::chrono::steady_clock::duration> durationResolve(iterations);
13183
std::vector<std::chrono::steady_clock::duration> durationParseServiceResponse(iterations);
13284
std::vector<std::chrono::steady_clock::duration> durationParseResponse(iterations);

samples/today/TodayMock.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,97 @@
1515
#include <chrono>
1616
#include <future>
1717
#include <iostream>
18+
#include <mutex>
1819

1920
namespace graphql::today {
2021

22+
const response::IdType& getFakeAppointmentId() noexcept
23+
{
24+
static const auto s_fakeId = []() noexcept {
25+
std::string fakeIdString("fakeAppointmentId");
26+
response::IdType result(fakeIdString.size());
27+
28+
std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin());
29+
30+
return result;
31+
}();
32+
33+
return s_fakeId;
34+
}
35+
36+
const response::IdType& getFakeTaskId() noexcept
37+
{
38+
static const auto s_fakeId = []() noexcept {
39+
std::string fakeIdString("fakeTaskId");
40+
response::IdType result(fakeIdString.size());
41+
42+
std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin());
43+
44+
return result;
45+
}();
46+
47+
return s_fakeId;
48+
}
49+
50+
const response::IdType& getFakeFolderId() noexcept
51+
{
52+
static const auto s_fakeId = []() noexcept {
53+
std::string fakeIdString("fakeFolderId");
54+
response::IdType result(fakeIdString.size());
55+
56+
std::copy(fakeIdString.cbegin(), fakeIdString.cend(), result.begin());
57+
58+
return result;
59+
}();
60+
61+
return s_fakeId;
62+
}
63+
64+
std::unique_ptr<TodayMockService> mock_service() noexcept
65+
{
66+
auto result = std::make_unique<TodayMockService>();
67+
68+
auto query = std::make_shared<Query>(
69+
[mockService = result.get()]() -> std::vector<std::shared_ptr<Appointment>> {
70+
++mockService->getAppointmentsCount;
71+
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
72+
"tomorrow",
73+
"Lunch?",
74+
false) };
75+
},
76+
[mockService = result.get()]() -> std::vector<std::shared_ptr<Task>> {
77+
++mockService->getTasksCount;
78+
return {
79+
std::make_shared<Task>(response::IdType(getFakeTaskId()), "Don't forget", true)
80+
};
81+
},
82+
[mockService = result.get()]() -> std::vector<std::shared_ptr<Folder>> {
83+
++mockService->getUnreadCountsCount;
84+
return {
85+
std::make_shared<Folder>(response::IdType(getFakeFolderId()), "\"Fake\" Inbox", 3)
86+
};
87+
});
88+
auto mutation = std::make_shared<Mutation>(
89+
[](CompleteTaskInput&& input) -> std::shared_ptr<CompleteTaskPayload> {
90+
return std::make_shared<CompleteTaskPayload>(
91+
std::make_shared<Task>(std::move(input.id), "Mutated Task!", *(input.isComplete)),
92+
std::move(input.clientMutationId));
93+
});
94+
auto subscription = std::make_shared<NextAppointmentChange>(
95+
[](const std::shared_ptr<service::RequestState>&) -> std::shared_ptr<Appointment> {
96+
return { std::make_shared<Appointment>(response::IdType(getFakeAppointmentId()),
97+
"tomorrow",
98+
"Lunch?",
99+
true) };
100+
});
101+
102+
result->service = std::make_shared<Operations>(std::move(query),
103+
std::move(mutation),
104+
std::move(subscription));
105+
106+
return result;
107+
}
108+
21109
Appointment::Appointment(
22110
response::IdType&& id, std::string&& when, std::string&& subject, bool isNow)
23111
: _id(std::move(id))
@@ -51,6 +139,9 @@ Query::Query(appointmentsLoader&& getAppointments, tasksLoader&& getTasks,
51139

52140
void Query::loadAppointments(const std::shared_ptr<service::RequestState>& state)
53141
{
142+
static std::mutex s_loaderMutex {};
143+
std::lock_guard lock { s_loaderMutex };
144+
54145
if (_getAppointments)
55146
{
56147
if (state)
@@ -84,6 +175,9 @@ std::shared_ptr<Appointment> Query::findAppointment(
84175

85176
void Query::loadTasks(const std::shared_ptr<service::RequestState>& state)
86177
{
178+
static std::mutex s_loaderMutex {};
179+
std::lock_guard lock { s_loaderMutex };
180+
87181
if (_getTasks)
88182
{
89183
if (state)
@@ -117,6 +211,9 @@ std::shared_ptr<Task> Query::findTask(
117211

118212
void Query::loadUnreadCounts(const std::shared_ptr<service::RequestState>& state)
119213
{
214+
static std::mutex s_loaderMutex {};
215+
std::lock_guard lock { s_loaderMutex };
216+
120217
if (_getUnreadCounts)
121218
{
122219
if (state)
@@ -496,6 +593,10 @@ double Mutation::applySetFloat(double valueArg) noexcept
496593
return valueArg;
497594
}
498595

596+
size_t NextAppointmentChange::_notifySubscribeCount = 0;
597+
size_t NextAppointmentChange::_subscriptionCount = 0;
598+
size_t NextAppointmentChange::_notifyUnsubscribeCount = 0;
599+
499600
std::stack<CapturedParams> NestedType::_capturedParams;
500601

501602
NestedType::NestedType(service::FieldParams&& params, int depth)

samples/today/TodayMock.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@
2626

2727
namespace graphql::today {
2828

29+
// These IDs are hard-coded in every test which uses TodayMock.
30+
const response::IdType& getFakeAppointmentId() noexcept;
31+
const response::IdType& getFakeTaskId() noexcept;
32+
const response::IdType& getFakeFolderId() noexcept;
33+
34+
struct TodayMockService
35+
{
36+
std::shared_ptr<Operations> service {};
37+
size_t getAppointmentsCount {};
38+
size_t getTasksCount {};
39+
size_t getUnreadCountsCount {};
40+
};
41+
42+
std::unique_ptr<TodayMockService> mock_service() noexcept;
43+
2944
struct RequestState : service::RequestState
3045
{
3146
RequestState(size_t id)

samples/today/benchmark.cpp

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,55 +17,6 @@ using namespace graphql;
1717

1818
using namespace std::literals;
1919

20-
namespace {
21-
22-
response::IdType binAppointmentId;
23-
response::IdType binTaskId;
24-
response::IdType binFolderId;
25-
26-
} // namespace
27-
28-
std::shared_ptr<today::Operations> buildService()
29-
{
30-
std::string fakeAppointmentId("fakeAppointmentId");
31-
binAppointmentId.resize(fakeAppointmentId.size());
32-
std::copy(fakeAppointmentId.cbegin(), fakeAppointmentId.cend(), binAppointmentId.begin());
33-
34-
std::string fakeTaskId("fakeTaskId");
35-
binTaskId.resize(fakeTaskId.size());
36-
std::copy(fakeTaskId.cbegin(), fakeTaskId.cend(), binTaskId.begin());
37-
38-
std::string fakeFolderId("fakeFolderId");
39-
binFolderId.resize(fakeFolderId.size());
40-
std::copy(fakeFolderId.cbegin(), fakeFolderId.cend(), binFolderId.begin());
41-
42-
auto query = std::make_shared<today::Query>(
43-
[]() -> std::vector<std::shared_ptr<today::Appointment>> {
44-
return { std::make_shared<today::Appointment>(std::move(binAppointmentId),
45-
"tomorrow",
46-
"Lunch?",
47-
false) };
48-
},
49-
[]() -> std::vector<std::shared_ptr<today::Task>> {
50-
return { std::make_shared<today::Task>(std::move(binTaskId), "Don't forget", true) };
51-
},
52-
[]() -> std::vector<std::shared_ptr<today::Folder>> {
53-
return { std::make_shared<today::Folder>(std::move(binFolderId), "\"Fake\" Inbox", 3) };
54-
});
55-
auto mutation = std::make_shared<today::Mutation>(
56-
[](today::CompleteTaskInput&& input) -> std::shared_ptr<today::CompleteTaskPayload> {
57-
return std::make_shared<today::CompleteTaskPayload>(
58-
std::make_shared<today::Task>(std::move(input.id),
59-
"Mutated Task!",
60-
*(input.isComplete)),
61-
std::move(input.clientMutationId));
62-
});
63-
auto subscription = std::make_shared<today::Subscription>();
64-
auto service = std::make_shared<today::Operations>(query, mutation, subscription);
65-
66-
return service;
67-
}
68-
6920
void outputOverview(
7021
size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept
7122
{
@@ -127,7 +78,8 @@ int main(int argc, char** argv)
12778

12879
std::cout << "Iterations: " << iterations << std::endl;
12980

130-
auto service = buildService();
81+
const auto mockService = today::mock_service();
82+
const auto& service = mockService->service;
13183
std::vector<std::chrono::steady_clock::duration> durationParse(iterations);
13284
std::vector<std::chrono::steady_clock::duration> durationValidate(iterations);
13385
std::vector<std::chrono::steady_clock::duration> durationResolve(iterations);

samples/today/sample.cpp

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,48 +14,8 @@ using namespace graphql;
1414

1515
int main(int argc, char** argv)
1616
{
17-
response::IdType binAppointmentId;
18-
response::IdType binTaskId;
19-
response::IdType binFolderId;
20-
21-
std::string fakeAppointmentId("fakeAppointmentId");
22-
binAppointmentId.resize(fakeAppointmentId.size());
23-
std::copy(fakeAppointmentId.cbegin(), fakeAppointmentId.cend(), binAppointmentId.begin());
24-
25-
std::string fakeTaskId("fakeTaskId");
26-
binTaskId.resize(fakeTaskId.size());
27-
std::copy(fakeTaskId.cbegin(), fakeTaskId.cend(), binTaskId.begin());
28-
29-
std::string fakeFolderId("fakeFolderId");
30-
binFolderId.resize(fakeFolderId.size());
31-
std::copy(fakeFolderId.cbegin(), fakeFolderId.cend(), binFolderId.begin());
32-
33-
auto query = std::make_shared<today::Query>(
34-
[&binAppointmentId]() -> std::vector<std::shared_ptr<today::Appointment>> {
35-
std::cout << "Called getAppointments..." << std::endl;
36-
return { std::make_shared<today::Appointment>(std::move(binAppointmentId),
37-
"tomorrow",
38-
"Lunch?",
39-
false) };
40-
},
41-
[&binTaskId]() -> std::vector<std::shared_ptr<today::Task>> {
42-
std::cout << "Called getTasks..." << std::endl;
43-
return { std::make_shared<today::Task>(std::move(binTaskId), "Don't forget", true) };
44-
},
45-
[&binFolderId]() -> std::vector<std::shared_ptr<today::Folder>> {
46-
std::cout << "Called getUnreadCounts..." << std::endl;
47-
return { std::make_shared<today::Folder>(std::move(binFolderId), "\"Fake\" Inbox", 3) };
48-
});
49-
auto mutation = std::make_shared<today::Mutation>(
50-
[](today::CompleteTaskInput&& input) -> std::shared_ptr<today::CompleteTaskPayload> {
51-
return std::make_shared<today::CompleteTaskPayload>(
52-
std::make_shared<today::Task>(std::move(input.id),
53-
"Mutated Task!",
54-
*(input.isComplete)),
55-
std::move(input.clientMutationId));
56-
});
57-
auto subscription = std::make_shared<today::Subscription>();
58-
auto service = std::make_shared<today::Operations>(query, mutation, subscription);
17+
const auto mockService = today::mock_service();
18+
const auto& service = mockService->service;
5919

6020
std::cout << "Created the service..." << std::endl;
6121

@@ -84,8 +44,7 @@ int main(int argc, char** argv)
8444

8545
std::cout << "Executing query..." << std::endl;
8646

87-
std::cout << response::toJSON(
88-
service->resolve({ ast, ((argc > 2) ? argv[2] : "") }).get())
47+
std::cout << response::toJSON(service->resolve({ ast, ((argc > 2) ? argv[2] : "") }).get())
8948
<< std::endl;
9049
}
9150
catch (const std::runtime_error& ex)

0 commit comments

Comments
 (0)