executor/server: Add routine to make stream object return

Simply retains result object and sets json::json_return_type to
streaming callback.
This commit is contained in:
Calle Wilund
2021-12-01 12:13:28 +00:00
parent e2d7225df8
commit 4a8a7ef8b4
2 changed files with 35 additions and 0 deletions

View File

@@ -84,6 +84,31 @@ std::string make_jsonable::to_json() const {
return rjson::print(_value);
}
json::json_return_type make_streamed(rjson::value&& value) {
// CMH. json::json_return_type uses std::function, not noncopyable_function.
// Need to make a copyable version of value. Gah.
auto rs = make_shared<rjson::value>(std::move(value));
std::function<future<>(output_stream<char>&&)> func = [rs](output_stream<char>&& os) mutable -> future<> {
// move objects to coroutine frame.
auto los = std::move(os);
auto lrs = std::move(rs);
try {
co_await rjson::print(*lrs, los);
co_await los.flush();
co_await los.close();
} catch (...) {
// at this point, we cannot really do anything. HTTP headers and return code are
// already written, and quite potentially a portion of the content data.
// just log + rethrow. It is probably better the HTTP server closes connection
// abruptly or something...
elogger.error("Unhandled exception in data streaming: {}", std::current_exception());
throw;
}
co_return;
};
return func;
}
json_string::json_string(std::string&& value)
: _value(std::move(value))
{}

View File

@@ -73,6 +73,16 @@ public:
explicit make_jsonable(rjson::value&& value);
std::string to_json() const override;
};
/**
* Make return type for serializing the object "streamed",
* i.e. direct to HTTP output stream. Note: only useful for
* (very) large objects as there are overhead issues with this
* as well, but for massive lists of return objects this can
* help avoid large allocations/many re-allocs
*/
json::json_return_type make_streamed(rjson::value&&);
struct json_string : public json::jsonable {
std::string _value;
public: