Commit Graph

7 Commits

Author SHA1 Message Date
Nadav Har'El
f41dac2a3a alternator: avoid large contiguous allocation for request body
Alternator request sizes can be up to 16 MB, but the current implementation
had the Seastar HTTP server read the entire request as a contiguous string,
and then processed it. We can't avoid reading the entire request up-front -
we want to verify its integrity before doing any additional processing on it.
But there is no reason why the entire request needs to be stored in one big
*contiguous* allocation. This always a bad idea. We should use a non-
contiguous buffer, and that's the goal of this patch.

We use a new Seastar HTTPD feature where we can ask for an input stream,
instead of a string, for the request's body. We then begin the request
handling by reading lthe content of this stream into a
vector<temporary_buffer<char>> (which we alias "chunked_content"). We then
use this non-contiguous buffer to verify the request's signature and
if successful - parse the request JSON and finally execute it.

Beyond avoiding contiguous allocations, another benefit of this patch is
that while parsing a long request composed of chunks, we free each chunk
as soon as its parsing completed. This reduces the peak amount of memory
used by the query - we no longer need to store both unparsed and parsed
versions of the request at the same time.

Although we already had tests with requests of different lengths, most
of them were short enough to only have one chunk, and only a few had
2 or 3 chunks. So we also add a test which makes a much longer request
(a BatchWriteItem with large items), which in my experiment had 17 chunks.
The goal of this test is to verify that the new signature and JSON parsing
code which needs to cross chunk boundaries work as expected.

Fixes #7213.

Signed-off-by: Nadav Har'El <nyh@scylladb.com>
Message-Id: <20210309222525.1628234-1-nyh@scylladb.com>
2021-03-10 09:22:34 +01:00
Calle Wilund
699c4d2c7e rjson: Add templated get/set overloads and optional get<T>
To allow immediate json value conversion for types we
have TypeHelper<...>:s for.

Typed opt-get to get both automatic type conversion, _and_
find functionality in one call.
2020-07-15 08:10:23 +00:00
Calle Wilund
72ec525045 rjson: Add exception overloads
To avoid copying error message composing, as well as forcing
said code info rjson.cc.
Also helps caller to determine fault by catch type.
2020-07-15 08:10:23 +00:00
Piotr Sarna
1b37517aab rjson: move quote_json_string to rjson
This utility function is used for type serialization,
but it also has a dedicated unit test, so it needs to be globally
reachable.
2020-07-03 10:27:23 +02:00
Piotr Sarna
f568fe869f rjson: add non-throwing parsing
Returning a disengaged optional instead of throwing an error
can be useful when the input string is expected not to be a valid
JSON in certain cases.
2020-07-03 10:27:23 +02:00
Piotr Sarna
3fda9908f2 rjson: add from_string_map function
This legacy function is needed because the existing implementation
relies on being able to parse flat JSON documents to and from maps
of strings.
2020-07-03 10:27:23 +02:00
Piotr Sarna
4de23d256e alternator,utils: move rjson.hh to utils/
rjson is going to replace libjsoncpp, so it's moved from alternator
to the common utils/ directory.
2020-07-03 08:30:01 +02:00