Skip to content

Commit

Permalink
[rd-cpp] Improve error handling for task results.
Browse files Browse the repository at this point in the history
  • Loading branch information
mirasrael committed Jan 15, 2024
1 parent 22eecd0 commit 3563bee
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 45 deletions.
1 change: 1 addition & 0 deletions rd-cpp/src/rd_core_cpp/src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ set(RD_CORE_CPP_SOURCES
#pch
${PCH_CPP_OPT}
util/export_api_helper.h
util/lifetime_util.h
)

if (RD_STATIC)
Expand Down
37 changes: 37 additions & 0 deletions rd-cpp/src/rd_core_cpp/src/main/util/lifetime_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef LIFETIME_UTIL_H
#define LIFETIME_UTIL_H

#include <memory>
#include "../lifetime/LifetimeDefinition.h"

namespace rd
{
namespace util
{
/// \brief Attaches lifetime to shared_ptr. Lifetime terminates when shared_ptr destructed.
/// \param original original pointer which will be used to make a new pointer with lifetime.
/// \param lifetime_definition Lifetime definition associated with returned shared_ptr.
/// \return New shared_ptr which owns lifetime_definition and terminates that lifetime when destroyed.
template <typename T>
static std::shared_ptr<T> attach_lifetime(std::shared_ptr<T> original, LifetimeDefinition lifetime_definition)
{
struct Deleter
{
std::shared_ptr<T> ptr;
LifetimeDefinition lifetime_definition;

explicit Deleter(LifetimeDefinition&& lifetime_definition, std::shared_ptr<T> ptr) : ptr(std::move(ptr)), lifetime_definition(std::move(lifetime_definition)) { }

void operator()(T*) const
{
}
};

auto raw_ptr = original.get();
auto deleter = Deleter(std::move(lifetime_definition), std::move(original));
return std::shared_ptr<T>(raw_ptr, std::move(deleter));
}
}
}

#endif //LIFETIME_UTIL_H
23 changes: 11 additions & 12 deletions rd-cpp/src/rd_framework_cpp/src/main/task/RdEndpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,41 +119,40 @@ class RdEndpoint : public virtual RdReactiveBase, public ISerializable
template <class Bindable = TRes, std::enable_if_t<util::is_bindable_v<Bindable>, bool> = true>
void handle_result(LifetimeDefinition result_lifetime_def, const RdId task_id, const TaskResult& result) const
{
try
if (result.is_succeeded())
{
if (result.is_succeeded())
try
{
auto result_lifetime = result_lifetime_def.lifetime;
auto wired_result = result_lifetime->make_attached<detail::RdEndpointWiredResult<WTRes>>(std::move(result_lifetime_def), result.get_value());
wired_result->identify(*get_protocol()->get_identity(), task_id);
wired_result->bind(result_lifetime, this, "EndpointWiredResult");
send_result(task_id, result);
}
else
catch (const std::exception& ex)
{
send_result(task_id, result);
result_lifetime_def.terminate();
spdlog::get("logSend")->error(ex.what());
send_result(task_id, typename TaskResult::Fault(ex));
}
}
catch (std::exception ex)
else
{
spdlog::get("logSend")->error(ex.what());
result_lifetime_def.terminate();
send_result(task_id, result);
}
}

template <class NonBindable = TRes, std::enable_if_t<!util::is_bindable_v<NonBindable>, bool> = true>
void handle_result(LifetimeDefinition result_lifetime_def, const RdId task_id, TaskResult result) const
void handle_result(LifetimeDefinition /*should_be_destroyed_on_complete*/, const RdId task_id, TaskResult result) const
{
try
{
send_result(task_id, result);
result_lifetime_def.terminate();
}
catch (std::exception ex)
catch (const std::exception& ex)
{
spdlog::get("logSend")->error(ex.what());
result_lifetime_def.terminate();
if (result.is_succeeded())
send_result(task_id, typename TaskResult::Fault(ex));
}
}

Expand Down
27 changes: 0 additions & 27 deletions rd-cpp/src/rd_framework_cpp/src/main/task/RdTaskResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,33 +119,6 @@ class RdTaskResult final : public ISerializable
v);
}

/// \brief Attaches lifetime to result value. Lifetime terminates when result value destructed.
/// \param parent Parent lifetime.
/// \throw mpark::bad_variant_access if result isn't available or not Success
template <class Wrapped = WT, std::enable_if_t<is_wrapper_v<Wrapped>, bool> = true>
Lifetime attach_nested_lifetime_to_value(const Lifetime& parent)
{
auto&& wrapper = get<Success>(v).value;

struct Deleter
{
std::shared_ptr<T> ptr;
LifetimeDefinition lifetime_definition;

explicit Deleter(LifetimeDefinition&& lifetime_definition, std::shared_ptr<T> ptr) : ptr(std::move(ptr)), lifetime_definition(std::move(lifetime_definition)) { }

void operator()(T*) const
{
}
};

auto deleter = Deleter(LifetimeDefinition(parent), std::move(wrapper));
auto ptr = deleter.ptr.get();
auto lifetime = deleter.lifetime_definition.lifetime;
wrapper = std::shared_ptr<T>(ptr, std::move(deleter));
return lifetime;
}

WT const& get_value() const
{
return visit(util::make_visitor([](Success const& value) -> WT const& { return value.value; },
Expand Down
19 changes: 13 additions & 6 deletions rd-cpp/src/rd_framework_cpp/src/main/task/WiredRdTaskImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "serialization/Polymorphic.h"
#include "RdTaskResult.h"
#include "util/framework_traits.h"
#include "util/lifetime_util.h"

namespace rd
{
Expand All @@ -26,23 +27,29 @@ class WiredRdTaskImpl : public RdReactiveBase
LifetimeImpl::counter_t termination_lifetime_id{};

template <class Bindable = T, std::enable_if_t<util::is_bindable_v<Bindable>, bool> = true>
void bind_result(TaskResult& task_result) const
TaskResult bind_result(TaskResult task_result) const
{
auto result_lifetime = task_result.attach_nested_lifetime_to_value(lifetime);
if (!task_result.is_succeeded())
return task_result;

auto lifetime_defintion = LifetimeDefinition(lifetime);
auto result_lifetime = lifetime_defintion.lifetime;
auto value = util::attach_lifetime(task_result.get_value(), std::move(lifetime_defintion));
result_lifetime->add_action([task_id = get_id(), cutpoint = cutpoint]
{
cutpoint->get_wire()->send(task_id, [](auto&)
{
// write nothing, just signal server to release result lifetime
});
});
task_result.get_value()->bind(result_lifetime, cutpoint, "CallResult");
value->bind(result_lifetime, cutpoint, "CallResult");
return typename TaskResult::Success(value);
}

template <class NonBindable = T, std::enable_if_t<!util::is_bindable_v<NonBindable>, bool> = true>
void bind_result(TaskResult&) const
TaskResult bind_result(TaskResult result) const
{
// do nothing for non-bindable value
return result;
}

public:
Expand Down Expand Up @@ -78,7 +85,7 @@ class WiredRdTaskImpl : public RdReactiveBase
}
else
{
bind_result(result);
result = bind_result(std::move(result));
this->result->set_if_empty(std::move(result));
}
});
Expand Down

0 comments on commit 3563bee

Please sign in to comment.