Skip to content

Commit 13e163e

Browse files
feat(cpp): add std::future async interface to client and all services
1 parent 6fe7d9c commit 13e163e

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

templates/cpp/include/client.hpp.twig

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <iostream>
1010
#include <algorithm>
1111
#include <mutex>
12+
#include <future>
1213
#include <cctype>
1314
#include <cpr/cpr.h>
1415
#include <nlohmann/json.hpp>
@@ -160,6 +161,53 @@ public:
160161
throw Exception("Expected redirect (3xx) but received " + std::to_string(response.status_code), response.status_code, response.text);
161162
}
162163

164+
/**
165+
* @brief Asynchronous version of call<T>. Returns a std::future<T> immediately.
166+
* The underlying HTTP request runs on a new thread managed by the standard library.
167+
*/
168+
template <typename T>
169+
[[nodiscard]] std::future<T> callAsync(std::string_view method, std::string_view path,
170+
const std::map<std::string, std::string>& headers = {},
171+
const nlohmann::json& params = {}) const {
172+
// Capture config snapshot eagerly — safe even if Client is reconfigured after dispatch.
173+
auto config = getConfig();
174+
return std::async(std::launch::async, [this, method = std::string(method),
175+
path = std::string(path), headers, params]() {
176+
return call<T>(method, path, headers, params);
177+
});
178+
}
179+
180+
/**
181+
* @brief Asynchronous version of callBytes. Returns a std::future<std::vector<uint8_t>>.
182+
*/
183+
[[nodiscard]] std::future<std::vector<uint8_t>> callBytesAsync(
184+
std::string_view method, std::string_view path,
185+
const std::map<std::string, std::string>& headers = {},
186+
const nlohmann::json& params = {}) const {
187+
return std::async(std::launch::async, [this, method = std::string(method),
188+
path = std::string(path), headers, params]() {
189+
return callBytes(method, path, headers, params);
190+
});
191+
}
192+
193+
/**
194+
* @brief Asynchronous version of fileUpload<T>. Returns a std::future<T>.
195+
* Progress callbacks are still invoked on the worker thread.
196+
*/
197+
template <typename T>
198+
[[nodiscard]] std::future<T> fileUploadAsync(std::string_view method, std::string_view path,
199+
const std::string& fileKey,
200+
const InputFile& inputFile,
201+
const std::map<std::string, std::string>& headers = {},
202+
const nlohmann::json& params = {},
203+
const ProgressCallback& onProgress = nullptr) const {
204+
return std::async(std::launch::async, [this, method = std::string(method),
205+
path = std::string(path), fileKey, inputFile,
206+
headers, params, onProgress]() {
207+
return fileUpload<T>(method, path, fileKey, inputFile, headers, params, onProgress);
208+
});
209+
}
210+
163211
template <typename T>
164212
[[nodiscard]] T fileUpload(std::string_view method, std::string_view path,
165213
const std::string& fileKey,

templates/cpp/include/services/service.hpp.twig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string>
55
#include <vector>
66
#include <map>
7+
#include <future>
78
#include <nlohmann/json.hpp>
89
#include "../client.hpp"
910
#include "../exception.hpp"
@@ -122,6 +123,31 @@ public:
122123
{%- endif %}
123124
{%- endif %}
124125
}
126+
127+
/**
128+
* {{ method.title }} (async)
129+
*
130+
* Asynchronous companion — returns a std::future resolved on a background thread.
131+
* Call .get() on the returned future to block and retrieve the result.
132+
*
133+
{% for parameter in method.parameters.all %}
134+
* @param {{ parameter.type }} {{ parameter.name | caseCamel | overrideIdentifier }} {{ parameter.description }}
135+
{% endfor %}
136+
* @return std::future<{{ method | returnType(spec, 'appwrite') }}>
137+
*/
138+
std::future<{{ method | returnType(spec, 'appwrite') }}> {{ method.name | caseCamel | overrideIdentifier }}Async(
139+
{%- for parameter in method.parameters.all %}
140+
{{ parameter | propertyType(spec) }} {{ parameter.name | caseCamel | overrideIdentifier }}{% if not loop.last %}, {% endif %}
141+
{%- endfor %}
142+
) {
143+
return std::async(std::launch::async, [=, this]() -> {{ method | returnType(spec, 'appwrite') }} {
144+
return {{ method.name | caseCamel | overrideIdentifier }}(
145+
{%- for parameter in method.parameters.all %}
146+
{{ parameter.name | caseCamel | overrideIdentifier }}{% if not loop.last %}, {% endif %}
147+
{%- endfor %}
148+
);
149+
});
150+
}
125151
{% endfor %}
126152
};
127153

0 commit comments

Comments
 (0)