Code cleanup
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 53s
Automated Main Deploy Action / build-and-deploy-docs (push) Successful in 20s

This commit is contained in:
2025-11-02 02:34:48 -05:00
parent eb9533d3a3
commit eac6ee4773
32 changed files with 82 additions and 135 deletions

View File

@@ -68,7 +68,12 @@ constexpr std::uint8_t decodeHexCharacter( const char h )
constexpr std::uint8_t decodeHexCharacters( const char left, const char right )
{
return decodeHexCharacter( left ) << 4 | decodeHexCharacter( right );
const std::uint8_t left_char { static_cast< std::uint8_t >( decodeHexCharacter( left ) << 4 ) };
const std::uint8_t right_char { decodeHexCharacter( right ) };
const std::uint8_t result { static_cast< std::uint8_t >( left_char | right_char ) };
return result;
}
static_assert( 0xFF == decodeHexCharacters( 'F', 'F' ) );

View File

@@ -147,7 +147,6 @@ class IDHANClient
* @brief Creates a parent/child relationship between two tags
* @param parent_id
* @param child_id
* @param tag_domain_id
* @return
*/
QFuture< void > createParentRelationship( TagDomainID tag_domian_id, TagID parent_id, TagID child_id );

View File

@@ -6,8 +6,6 @@
#include <QJsonDocument>
#include <QJsonObject>
#include <ranges>
#include "IDHANClient.hpp"
#include "logging/logger.hpp"

View File

@@ -26,7 +26,7 @@ void updateMigrations( pqxx::nontransaction& tx, const std::string_view schema )
// attempt to get the most recent update id
if ( tableExists( tx, "idhan_info", schema ) )
{
auto ret { tx.exec( "SELECT last_migration_id FROM idhan_info ORDER BY last_migration_id DESC limit 1" ) };
const auto ret { tx.exec( "SELECT last_migration_id FROM idhan_info ORDER BY last_migration_id DESC limit 1" ) };
if ( ret.size() > 0 )
{

View File

@@ -28,7 +28,7 @@ std::vector< std::shared_ptr< IDHANModule > > getModules()
void gLoghandler(
[[maybe_unused]] const char* log_domain,
GLogLevelFlags log_level,
const GLogLevelFlags log_level,
const char* message,
[[maybe_unused]] gpointer user_data )
{

View File

@@ -12,49 +12,6 @@
namespace idhan::api
{
/**
* @brief Finds a valid cluster name, If the cluster name is already taken, then we'll append a unique identifier to the
* end of it
*/
drogon::Task< std::string > findValidClusterName( const std::string desired_name, DbClientPtr db )
{
const auto result {
co_await db->execSqlCoro( "SELECT cluster_name FROM file_clusters WHERE cluster_name = $1", desired_name )
};
log::info( "Desired name: {}", desired_name );
if ( result.empty() )
{
log::info( "Cluster name {} not in use, Trying it", desired_name );
co_return desired_name;
}
const auto mark_start { desired_name.find_first_of( ":" ) };
if ( mark_start == std::string::npos )
{
co_return co_await findValidClusterName( format_ns::format( "{}: 1", desired_name ), db );
}
const auto mark_number_str { desired_name.substr( mark_start + 1 ) };
try
{
const auto mark_number { std::stoull( mark_number_str ) };
log::info( "Got UID: {}", mark_number_str );
const auto filtered_name { desired_name.substr( 0, mark_start ) };
co_return co_await findValidClusterName( format_ns::format( "{}: {}", filtered_name, mark_number + 1 ), db );
}
catch ( std::invalid_argument& arg )
{
// NOOP
}
co_return co_await findValidClusterName( format_ns::format( "{}: 1", desired_name ), db );
}
ClusterAPI::ResponseTask ClusterAPI::add( drogon::HttpRequestPtr request )
{
auto db { drogon::app().getDbClient() };

View File

@@ -79,7 +79,7 @@ drogon::Task< drogon::HttpResponsePtr > RecordAPI::fetchInfo(
[[maybe_unused]] drogon::HttpRequestPtr request,
RecordID record_id )
{
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
Json::Value root {};
root[ "record_id" ] = record_id;
@@ -110,11 +110,9 @@ drogon::Task< drogon::HttpResponsePtr > RecordAPI::fetchInfo(
drogon::Task< drogon::HttpResponsePtr > RecordAPI::parseFile( drogon::HttpRequestPtr request, RecordID record_id )
{
{
auto db { drogon::app().getDbClient() };
const auto parse_result { co_await tryParseRecordMetadata( record_id, db ) };
if ( !parse_result ) co_return parse_result.error();
}
const auto db { drogon::app().getDbClient() };
const auto parse_result { co_await tryParseRecordMetadata( record_id, db ) };
if ( !parse_result ) co_return parse_result.error();
co_return co_await fetchInfo( request, record_id );
}

View File

@@ -88,7 +88,6 @@ drogon::Task< drogon::HttpResponsePtr > RecordAPI::fetchThumbnail( drogon::HttpR
std::size_t height { 256 };
std::size_t width { 256 };
const auto file_size { std::filesystem::file_size( record_path.value() ) };
std::vector< std::byte > data { co_await io_uring.readAll() };
const auto thumbnail_info {

View File

@@ -10,7 +10,7 @@ namespace idhan
void checkContentType(
const drogon::HttpRequestPtr& request,
const ResponseFunction& callback,
const std::vector< drogon::ContentType > expected )
const std::vector< drogon::ContentType >& expected )
{
for ( const auto& item : expected )
if ( request->contentType() == item ) return;

View File

@@ -12,6 +12,6 @@ namespace idhan
void checkContentType(
const drogon::HttpRequestPtr& request,
const ResponseFunction& callback,
const std::vector< drogon::ContentType > expected );
const std::vector< drogon::ContentType >& expected );
} // namespace idhan

View File

@@ -84,7 +84,7 @@ ResponseTask createRecordFromJson( const drogon::HttpRequestPtr req )
const Json::Value& json { *json_ptr };
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
// test if sha256 is a list or 1 item
const auto& sha256s { json[ "sha256" ] };
@@ -132,18 +132,15 @@ ResponseTask RecordAPI::createRecord( const drogon::HttpRequestPtr request )
// Here we are expecting that the data being shoved into the request is actually a file.
case drogon::CT_APPLICATION_OCTET_STREAM:
co_return co_await createRecordFromOctet( request );
break;
// In this case we have either a list of hashes, or a single hash
case drogon::CT_APPLICATION_JSON:
co_return co_await createRecordFromJson( request );
break;
default:
co_return createBadRequest( "Unknown content type" );
break;
}
#pragma GCC diagnostic pop
co_return createBadRequest( "Unexpected content type" );
FGL_UNREACHABLE();
}
} // namespace idhan::api

View File

@@ -79,8 +79,8 @@ drogon::Task< std::expected< TagID, drogon::HttpResponsePtr > > getIDFromPair( c
if ( tag_id ) co_return tag_id.value();
auto tag_namespace_is_str { std::holds_alternative< std::string >( tag_namespace ) };
auto tag_subtag_is_str { std::holds_alternative< std::string >( tag_subtag ) };
const auto tag_namespace_is_str { std::holds_alternative< std::string >( tag_namespace ) };
const auto tag_subtag_is_str { std::holds_alternative< std::string >( tag_subtag ) };
if ( tag_namespace_is_str && tag_subtag_is_str )
{
@@ -340,9 +340,9 @@ drogon::Task< drogon::HttpResponsePtr > RecordAPI::addMultipleTags( drogon::Http
for ( const auto& set_json : sets_json )
{
auto task = [ db ]( Json::Value set_json ) -> Task
auto task = [ db ]( const Json::Value set_json_current ) -> Task
{
const auto tags { co_await getTagPairs( set_json ) };
const auto tags { co_await getTagPairs( set_json_current ) };
if ( !tags ) co_return std::unexpected( tags.error() );

View File

@@ -15,7 +15,7 @@ drogon::Task< drogon::HttpResponsePtr > APIMaintenance::postgresqlStorageSunData
root[ "name" ] = "root";
root[ "children" ] = Json::Value( Json::arrayValue );
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
const auto table_list { co_await db->execSqlCoro(
"SELECT table_name, pg_relation_size(quote_ident(table_name)::text) AS size FROM information_schema.tables WHERE "

View File

@@ -11,7 +11,7 @@ drogon::Task< drogon::HttpResponsePtr > TagAPI::search(
[[maybe_unused]] drogon::HttpRequestPtr request,
const std::string tag_text )
{
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
const auto result { co_await db->execSqlCoro( "SELECT tag_id FROM tags WHERE tag_text = $1", tag_text ) };

View File

@@ -21,7 +21,7 @@ drogon::Task< drogon::HttpResponsePtr > TagAPI::getTagInfo(
NamespaceID namespace_id {};
SubtagID subtag_id {};
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
{
const auto result {

View File

@@ -169,6 +169,7 @@ class SearchBuilder
* @brief Constructs a query to be used. $1 is expected to be an array of tag_domain_ids
* @param return_ids
* @param return_hashes
* @param filter_domains
* @return
*/
std::string construct( bool return_ids = true, bool return_hashes = false, bool filter_domains = false );

View File

@@ -106,10 +106,8 @@ class SHA256
} // namespace idhan
namespace std
{
template <>
struct hash< idhan::SHA256 >
struct std::hash< idhan::SHA256 >
{
std::size_t operator()( const idhan::SHA256& sha ) const noexcept
{
@@ -122,4 +120,3 @@ struct hash< idhan::SHA256 >
return seed;
}
};
} // namespace std

View File

@@ -127,7 +127,7 @@ ExpectedTask< void > TagSearch::removeSiblings()
{
std::vector< TagID > to_remove {};
for ( auto& id : m_ids )
for ( const auto& id : m_ids )
{
const auto siblings { co_await findSiblings( id ) };

View File

@@ -3,9 +3,7 @@
//
#pragma once
#include "api/helpers/pgEscape.hpp"
#include "crypto/SHA256.hpp"
#include "logging/format_ns.hpp"
std::vector< std::byte > createPgBinaryArray( const std::vector< idhan::SHA256 >& data );
std::vector< std::byte > createPgBinaryArray( const std::vector< std::string >& strings );
@@ -21,8 +19,8 @@ inline SqlBinder::self& SqlBinder::operator<< < std::vector< idhan::SHA256 > >(
{
++parametersNumber_;
auto binary_data = std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::SHA256 > >( param ) ) );
const auto binary_data { std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::SHA256 > >( param ) ) ) };
objs_.push_back( binary_data );
parameters_.push_back( reinterpret_cast< const char* >( binary_data->data() ) );
@@ -50,8 +48,8 @@ inline SqlBinder::self& SqlBinder::operator<< < std::vector< std::string > >( st
///*
++parametersNumber_;
auto binary_data = std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< std::string > >( param ) ) );
const auto binary_data { std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< std::string > >( param ) ) ) };
objs_.push_back( binary_data );
parameters_.push_back( reinterpret_cast< const char* >( binary_data->data() ) );
@@ -69,8 +67,8 @@ inline SqlBinder::self& SqlBinder::operator<< < std::vector< idhan::SmallInt > >
{
++parametersNumber_;
auto binary_data = std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::SmallInt > >( param ) ) );
const auto binary_data { std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::SmallInt > >( param ) ) ) };
objs_.push_back( binary_data );
parameters_.push_back( reinterpret_cast< const char* >( binary_data->data() ) );
@@ -85,8 +83,8 @@ inline SqlBinder::self& SqlBinder::operator<< < std::vector< idhan::Int > >( std
{
++parametersNumber_;
auto binary_data = std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::Int > >( param ) ) );
const auto binary_data { std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::Int > >( param ) ) ) };
objs_.push_back( binary_data );
parameters_.push_back( reinterpret_cast< const char* >( binary_data->data() ) );
@@ -101,8 +99,8 @@ inline SqlBinder::self& SqlBinder::operator<< < std::vector< idhan::BigInt > >(
{
++parametersNumber_;
auto binary_data = std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::BigInt > >( param ) ) );
const auto binary_data { std::make_shared< std::vector< std::byte > >(
createPgBinaryArray( std::forward< std::vector< idhan::BigInt > >( param ) ) ) };
objs_.push_back( binary_data );
parameters_.push_back( reinterpret_cast< const char* >( binary_data->data() ) );

View File

@@ -242,7 +242,7 @@ drogon::Task< std::expected< void, drogon::HttpResponsePtr > > ClusterManager::s
ExpectedTask< std::filesystem::path > ClusterManager::getClusterPath( const ClusterID cluster_id )
{
std::lock_guard lock { m_mutex };
auto itter = m_folders.find( cluster_id );
const auto itter { m_folders.find( cluster_id ) };
if ( itter == m_folders.end() )
co_return std::unexpected( createBadRequest( "Invalid cluster id {}", cluster_id ) );

View File

@@ -12,6 +12,11 @@
namespace idhan
{
bool WriteAwaiter::await_ready() noexcept
{
return false;
}
void WriteAwaiter::await_suspend( const std::coroutine_handle<> h )
{
m_event_loop = trantor::EventLoop::getEventLoopOfCurrentThread();
@@ -19,8 +24,8 @@ void WriteAwaiter::await_suspend( const std::coroutine_handle<> h )
std::lock_guard lock { m_uring->mtx };
unsigned tail = *m_uring->m_submission_ring.tail;
unsigned index = tail & *m_uring->m_submission_ring.mask;
unsigned tail { *m_uring->m_submission_ring.tail };
const unsigned index { tail & *m_uring->m_submission_ring.mask };
m_sqe.user_data = reinterpret_cast< decltype( m_sqe.user_data ) >( new IOUringUserData( this ) );
m_uring->m_submission_ring.entries[ index ] = m_sqe;
@@ -32,16 +37,15 @@ void WriteAwaiter::await_suspend( const std::coroutine_handle<> h )
m_uring->notifySubmit( 1 );
}
void WriteAwaiter::await_resume()
void WriteAwaiter::await_resume() const
{
if ( m_exception ) std::rethrow_exception( m_exception );
return;
}
WriteAwaiter::WriteAwaiter( IOUring* uring, io_uring_sqe sqe ) : m_uring( uring ), m_sqe( sqe )
{}
void WriteAwaiter::complete( int result )
void WriteAwaiter::complete( const int result )
{
if ( result < 0 )
{
@@ -57,9 +61,6 @@ void WriteAwaiter::complete( int result )
}
}
WriteAwaiter::~WriteAwaiter()
{
log::debug( "~WriteAwaiter()" );
}
WriteAwaiter::~WriteAwaiter() = default;
} // namespace idhan

View File

@@ -23,11 +23,11 @@ struct [[nodiscard]] WriteAwaiter
struct promise_type;
using handle_type = std::coroutine_handle< promise_type >;
bool await_ready() const noexcept { return false; }
static bool await_ready() noexcept;
void await_suspend( const std::coroutine_handle<> h );
void await_suspend( std::coroutine_handle<> h );
void await_resume();
void await_resume() const;
std::exception_ptr m_exception { nullptr };
std::coroutine_handle<> m_cont {};

View File

@@ -11,6 +11,7 @@ namespace idhan::filesystem
/**
*
* @param record_id Record of which to get a filepath for
* @param db
* @return
*/
ExpectedTask< std::filesystem::path > getFilepath( RecordID record_id, DbClientPtr db );
@@ -27,6 +28,7 @@ ExpectedTask< std::filesystem::path > getTheoreticalFilePath(
/**
* @brief Checks that a file exists in its respective cluster
* @param record_id
* @param db
* @return
*/
ExpectedTask< bool > checkFileExists( RecordID record_id, drogon::orm::DbClientPtr db );

View File

@@ -318,7 +318,7 @@ drogon::Task< drogon::HttpResponsePtr > HydrusAPI::file( const drogon::HttpReque
if ( hash )
{
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
const auto sha256 { SHA256::fromHex( hash.value() ) };
if ( !sha256 ) co_return sha256.error();
@@ -343,14 +343,14 @@ drogon::Task< drogon::HttpResponsePtr > HydrusAPI::file( const drogon::HttpReque
drogon::Task< drogon::HttpResponsePtr > HydrusAPI::thumbnail( drogon::HttpRequestPtr request )
{
auto file_id { request->getOptionalParameter< RecordID >( "file_id" ) };
const auto file_id { request->getOptionalParameter< RecordID >( "file_id" ) };
const auto hash { request->getOptionalParameter< std::string >( "hash" ) };
RecordID record_id { file_id.value_or( 0 ) };
if ( hash )
{
auto db { drogon::app().getDbClient() };
const auto db { drogon::app().getDbClient() };
const auto sha256 { SHA256::fromHex( hash.value() ) };
if ( const auto record_id_e { co_await api::helpers::findRecord( *sha256, db ) } )

View File

@@ -2,6 +2,8 @@
// Created by kj16609 on 11/2/24.
//
#pragma once
namespace idhan::hyapi
{

View File

@@ -42,12 +42,12 @@ drogon::Task<> setFileInfo( const RecordID record_id, const FileInfo info, const
}
drogon::Task< std::expected< FileInfo, drogon::HttpResponsePtr > > gatherFileInfo(
FileIOUring io,
FileIOUring io_uring,
const DbClientPtr db )
{
FileInfo info {};
info.size = io.size();
const auto mime_string { co_await mime::getMimeDatabase()->scan( io ) };
info.size = io_uring.size();
const auto mime_string { co_await mime::getMimeDatabase()->scan( io_uring ) };
if ( !mime_string )
{
@@ -62,7 +62,7 @@ drogon::Task< std::expected< FileInfo, drogon::HttpResponsePtr > > gatherFileInf
if ( mime_search.empty() )
{
info.mime_id = constants::INVALID_MIME_ID;
info.extension = io.path().extension();
info.extension = io_uring.path().extension();
// ensure that it doesn't start with `.`
if ( info.extension.starts_with( '.' ) ) info.extension = info.extension.substr( 1 );
}

View File

@@ -36,8 +36,8 @@ class MimeIdentifier
[[nodiscard]] MimeScore priority() const { return m_priority; }
MimeIdentifier() = delete;
MimeIdentifier( const Json::Value& json );
MimeIdentifier( const std::filesystem::path& path );
explicit MimeIdentifier( const Json::Value& json );
explicit MimeIdentifier( const std::filesystem::path& path );
};
Json::Value jsonFromFile( const std::filesystem::path& path );

View File

@@ -54,8 +54,6 @@ drogon::Task< bool > MimeMatchSearch::match( Cursor& cursor ) const
// log::debug( "Searching for {}", spdlog::to_hex( match_view ) );
}
const auto start_pos { cursor.pos() };
const auto pos_limit { m_limit == NO_LIMIT ? NO_LIMIT : cursor.pos() + m_limit };
do
{

View File

@@ -98,7 +98,7 @@ void ModuleLoader::loadModules()
log::info( "Getting modules from shared lib" );
using VoidFunc = void* (*)();
auto getModulesFunc { reinterpret_cast< VoidFunc >( dlsym( holder->handle(), "getModulesFunc" ) ) };
const auto getModulesFunc { reinterpret_cast< VoidFunc >( dlsym( holder->handle(), "getModulesFunc" ) ) };
if ( !getModulesFunc )
{
log::error( "Failed to get getModulesFunc: {}", dlerror() );
@@ -106,7 +106,7 @@ void ModuleLoader::loadModules()
}
using GetModulesFunc = std::vector< std::shared_ptr< IDHANModule > > ( * )();
auto getModules { reinterpret_cast< GetModulesFunc >( getModulesFunc() ) };
const auto getModules { reinterpret_cast< GetModulesFunc >( getModulesFunc() ) };
if ( !getModules )
{
@@ -142,6 +142,7 @@ void ModuleLoader::loadModules()
}
std::vector< std::shared_ptr< ThumbnailerModuleI > > ModuleLoader::getThumbnailerFor( const std::string_view mime )
const
{
std::vector< std::shared_ptr< ThumbnailerModuleI > > ret {};
@@ -160,7 +161,7 @@ std::vector< std::shared_ptr< ThumbnailerModuleI > > ModuleLoader::getThumbnaile
return ret;
}
std::vector< std::shared_ptr< MetadataModuleI > > ModuleLoader::getParserFor( const std::string_view mime )
std::vector< std::shared_ptr< MetadataModuleI > > ModuleLoader::getParserFor( const std::string_view mime ) const
{
std::vector< std::shared_ptr< MetadataModuleI > > ret {};

View File

@@ -28,8 +28,8 @@ class ModuleLoader
void loadModules();
void unloadModules();
std::vector< std::shared_ptr< ThumbnailerModuleI > > getThumbnailerFor( std::string_view mime );
std::vector< std::shared_ptr< MetadataModuleI > > getParserFor( std::string_view mime );
std::vector< std::shared_ptr< ThumbnailerModuleI > > getThumbnailerFor( std::string_view mime ) const;
std::vector< std::shared_ptr< MetadataModuleI > > getParserFor( std::string_view mime ) const;
};
} // namespace idhan::modules

View File

@@ -33,9 +33,7 @@ drogon::Task< std::expected< TagID, IDHANError > > createTag(
if ( !namespace_id ) co_return std::unexpected( namespace_id.error() );
if ( !subtag_id ) co_return std::unexpected( subtag_id.error() );
const auto search_result { co_await findTag( *namespace_id, *subtag_id, db ) };
if ( search_result ) co_return *search_result;
if ( const auto search_result { co_await findTag( *namespace_id, *subtag_id, db ) } ) co_return *search_result;
const auto insert_result { co_await db->execSqlCoro(
"INSERT INTO tags (namespace_id, subtag_id) VALUES ($1, $2) RETURNING tag_id", *namespace_id, *subtag_id ) };

View File

@@ -44,13 +44,13 @@ struct ImmedientTask
{
ImmedientTask< T > get_return_object() { return ImmedientTask< T > { handle_type::from_promise( *this ) }; }
std::suspend_always initial_suspend() { return {}; }
static std::suspend_always initial_suspend() { return {}; }
void return_value( const T& v ) { value = v; }
void return_value( T&& v ) { value = std::move( v ); }
auto final_suspend() noexcept { return drogon::final_awaiter {}; }
static auto final_suspend() noexcept { return drogon::final_awaiter {}; }
void unhandled_exception() { exception_ = std::current_exception(); }
@@ -68,10 +68,10 @@ struct ImmedientTask
return value.value();
}
void setContinuation( std::coroutine_handle<> handle ) { continuation_ = handle; }
void setContinuation( const std::coroutine_handle<> handle ) { continuation_ = handle; }
std::optional< T > value;
std::exception_ptr exception_;
std::optional< T > value {};
std::exception_ptr exception_ {};
std::coroutine_handle<> continuation_ { std::noop_coroutine() };
};
@@ -86,15 +86,11 @@ struct [[nodiscard]] ImmedientTask< void >
struct promise_type;
using handle_type = std::coroutine_handle< promise_type >;
ImmedientTask( handle_type handle ) : coro_( handle ) {}
ImmedientTask( const handle_type handle ) : coro_( handle ) {}
ImmedientTask( const ImmedientTask& ) = delete;
ImmedientTask( ImmedientTask&& other ) noexcept
{
coro_ = other.coro_;
other.coro_ = nullptr;
}
ImmedientTask( ImmedientTask&& other ) noexcept : coro_( other.coro_ ) { other.coro_ = nullptr; }
~ImmedientTask()
{
@@ -117,22 +113,22 @@ struct [[nodiscard]] ImmedientTask< void >
{
ImmedientTask<> get_return_object() { return ImmedientTask<> { handle_type::from_promise( *this ) }; }
std::suspend_always initial_suspend() { return {}; }
static std::suspend_always initial_suspend() { return {}; }
void return_void() {}
auto final_suspend() noexcept { return drogon::final_awaiter {}; }
static auto final_suspend() noexcept { return drogon::final_awaiter {}; }
void unhandled_exception() { exception_ = std::current_exception(); }
void result()
void result() const
{
if ( exception_ != nullptr ) std::rethrow_exception( exception_ );
}
void setContinuation( std::coroutine_handle<> handle ) { continuation_ = handle; }
void setContinuation( const std::coroutine_handle<> handle ) { continuation_ = handle; }
std::exception_ptr exception_;
std::exception_ptr exception_ {};
std::coroutine_handle<> continuation_ { std::noop_coroutine() };
};