Skip to content

Commit

Permalink
[release/4.x] Cherry pick: Log and throw when oversized writer blows …
Browse files Browse the repository at this point in the history
…up (#5673) (#5677)
  • Loading branch information
CCF [bot] authored Sep 22, 2023
1 parent b803fe5 commit 289c2b7
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions src/ds/oversized.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
#include <fmt/format.h>
#include <unordered_map>

#define LOG_AND_THROW(ERROR_TYPE, ...) \
do \
{ \
const auto msg = fmt::format(__VA_ARGS__); \
LOG_FAIL_FMT("{}", msg); \
throw ERROR_TYPE(msg); \
} while (0)
namespace oversized
{
enum OversizedMessage : ringbuffer::Message
Expand Down Expand Up @@ -141,18 +148,24 @@ namespace oversized
fragment_progress({})
{
if (max_fragment_size >= max_total_size)
throw std::logic_error(fmt::format(
{
LOG_AND_THROW(
std::invalid_argument,
"Fragment sizes must be smaller than total max: {} >= {}",
max_fragment_size,
max_total_size));
max_total_size);
}

constexpr auto header_size = sizeof(InitialFragmentHeader);
if (max_fragment_size <= header_size)
throw std::logic_error(fmt::format(
{
LOG_AND_THROW(
std::invalid_argument,
"Fragment size must be large enough to contain the header for the "
"initial fragment, and some additional payload data: {} <= {}",
max_fragment_size,
header_size));
header_size);
}
}

virtual WriteMarker prepare(
Expand All @@ -164,7 +177,8 @@ namespace oversized
// Ensure this is not called out of order
if (fragment_progress.has_value())
{
throw std::logic_error("This Writer is already preparing a message");
LOG_AND_THROW(
std::logic_error, "This Writer is already preparing a message");
}

// Small enough to be handled directly by underlying writer
Expand All @@ -175,21 +189,23 @@ namespace oversized

if (total_size > max_total_size)
{
throw std::logic_error(fmt::format(
LOG_AND_THROW(
std::invalid_argument,
"Requested a write of {} bytes, max allowed is {}",
total_size,
max_total_size));
max_total_size);
}

// Need to split this message into multiple fragments

if (!wait)
{
throw std::logic_error(fmt::format(
LOG_AND_THROW(
std::invalid_argument,
"Requested write of {} bytes will be split into multiple fragments: "
"caller must wait for these to complete as fragment writes will be "
"blocking",
total_size));
total_size);
}

// Prepare space for the first fragment, getting an id for all related
Expand Down Expand Up @@ -227,7 +243,8 @@ namespace oversized
// to us
if (fragment_progress->remainder != 0)
{
throw std::logic_error(
LOG_AND_THROW(
std::logic_error,
"Attempting to finish an oversized message before the entire "
"requested payload has been written");
}
Expand Down Expand Up @@ -278,7 +295,8 @@ namespace oversized
if (!next.has_value())
{
// Intermediate fragment failed - this is unexpected
throw std::logic_error(
LOG_AND_THROW(
std::logic_error,
"Failed to create fragment for oversized message");

// If this path is hit it is likely because we have allowed oversized
Expand Down

0 comments on commit 289c2b7

Please sign in to comment.