From 73c8fba2c06ee99bd8f81fe976ec814987e77690 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Tue, 12 Jul 2022 12:27:27 +0200 Subject: [PATCH 01/25] Rename lib/types.h to lib/admire_types.h --- src/lib/CMakeLists.txt | 2 +- src/lib/admire.h | 4 ++-- src/lib/{types.h => admire_types.h} | 11 ++++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) rename src/lib/{types.h => admire_types.h} (98%) diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 4ef754f0..2d1b6c5e 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -35,7 +35,7 @@ set_property(TARGET api_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) add_library(adm_iosched SHARED) target_sources(adm_iosched - PUBLIC admire.h types.h admire.hpp + PUBLIC admire.h admire_types.h admire.hpp PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c) target_include_directories(adm_iosched PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/lib/admire.h b/src/lib/admire.h index fa431602..9a67b449 100644 --- a/src/lib/admire.h +++ b/src/lib/admire.h @@ -28,7 +28,7 @@ #include #include #include -#include "types.h" +#include "admire_types.h" #ifdef __cplusplus extern "C" { @@ -44,7 +44,7 @@ extern "C" { /* Public type definitions and type-related functions */ /******************************************************************************/ -// See types.h +// See admire_types.h /******************************************************************************/ diff --git a/src/lib/types.h b/src/lib/admire_types.h similarity index 98% rename from src/lib/types.h rename to src/lib/admire_types.h index 4ff80dc8..f04e2384 100644 --- a/src/lib/types.h +++ b/src/lib/admire_types.h @@ -22,8 +22,13 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#ifndef SCORD_TYPES_H -#define SCORD_TYPES_H +#ifndef SCORD_ADMIRE_TYPES_H +#define SCORD_ADMIRE_TYPES_H + +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -495,4 +500,4 @@ ADM_data_operation_destroy(ADM_data_operation_t op); } // extern "C" #endif -#endif // SCORD_TYPES_H +#endif // SCORD_ADMIRE_TYPES_H -- GitLab From 91570eefe043645352a19e34cae05b959a5a0686 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Tue, 12 Jul 2022 19:29:41 +0200 Subject: [PATCH 02/25] Allow clients to register RPCs without providing handlers --- src/common/network/engine.hpp | 1 + src/lib/admire.cpp | 96 ++++++++++++++++------------------- src/lib/detail/impl.cpp | 96 ++++++++++++++++------------------- 3 files changed, 91 insertions(+), 102 deletions(-) diff --git a/src/common/network/engine.hpp b/src/common/network/engine.hpp index 19e4fb70..c241f8a1 100644 --- a/src/common/network/engine.hpp +++ b/src/common/network/engine.hpp @@ -58,6 +58,7 @@ namespace detail { } \ } +#define _handler_for___null NULL struct margo_context { diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 6c42295b..f159a172 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -52,124 +52,118 @@ init_logger() { void rpc_registration_cb(scord::network::rpc_client* client) { - REGISTER_RPC(client, "ADM_ping", void, void, ADM_ping, false); + REGISTER_RPC(client, "ADM_ping", void, void, NULL, false); REGISTER_RPC(client, "ADM_register_job", ADM_register_job_in_t, - ADM_register_job_out_t, ADM_register_job, true); + ADM_register_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_job", ADM_update_job_in_t, - ADM_update_job_out_t, ADM_update_job, true); + ADM_update_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_remove_job", ADM_remove_job_in_t, - ADM_remove_job_out_t, ADM_remove_job, true); + ADM_remove_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_register_adhoc_storage", ADM_register_adhoc_storage_in_t, - ADM_register_adhoc_storage_out_t, ADM_register_adhoc_storage, - true); + ADM_register_adhoc_storage_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_adhoc_storage", ADM_update_adhoc_storage_in_t, ADM_update_adhoc_storage_out_t, - ADM_update_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_remove_adhoc_storage", ADM_remove_adhoc_storage_in_t, ADM_remove_adhoc_storage_out_t, - ADM_remove_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_deploy_adhoc_storage", ADM_deploy_adhoc_storage_in_t, ADM_deploy_adhoc_storage_out_t, - ADM_deploy_adhoc_storage, true); + NULL, true); - REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, - ADM_input, true); + REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, - ADM_output, true); + REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, - ADM_inout, true); + REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, NULL, + true); REGISTER_RPC(client, "ADM_adhoc_context", ADM_adhoc_context_in_t, - ADM_adhoc_context_out_t, ADM_adhoc_context, true); + ADM_adhoc_context_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_context_id", ADM_adhoc_context_id_in_t, - ADM_adhoc_context_id_out_t, ADM_adhoc_context_id, true); + ADM_adhoc_context_id_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_nodes", ADM_adhoc_nodes_in_t, - ADM_adhoc_nodes_out_t, ADM_adhoc_nodes, true); + ADM_adhoc_nodes_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_walltime", ADM_adhoc_walltime_in_t, - ADM_adhoc_walltime_out_t, ADM_adhoc_walltime, true); + ADM_adhoc_walltime_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_access", ADM_adhoc_access_in_t, - ADM_adhoc_access_out_t, ADM_adhoc_access, true); + ADM_adhoc_access_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_distribution", ADM_adhoc_distribution_in_t, - ADM_adhoc_distribution_out_t, ADM_adhoc_distribution, true); + ADM_adhoc_distribution_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_background_flush", ADM_adhoc_background_flush_in_t, - ADM_adhoc_background_flush_out_t, ADM_adhoc_background_flush, - true); + ADM_adhoc_background_flush_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_situ_ops", ADM_in_situ_ops_in_t, - ADM_in_situ_ops_out_t, ADM_in_situ_ops, true); + ADM_in_situ_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_transit_ops", ADM_in_transit_ops_in_t, - ADM_in_transit_ops_out_t, ADM_in_transit_ops, true); + ADM_in_transit_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_transfer_dataset", ADM_transfer_dataset_in_t, - ADM_transfer_dataset_out_t, ADM_transfer_dataset, true); + ADM_transfer_dataset_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_dataset_information", ADM_set_dataset_information_in_t, - ADM_set_dataset_information_out_t, ADM_set_dataset_information, - true); + ADM_set_dataset_information_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_io_resources", ADM_set_io_resources_in_t, - ADM_set_io_resources_out_t, ADM_set_io_resources, true); + ADM_set_io_resources_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_transfer_priority", ADM_get_transfer_priority_in_t, - ADM_get_transfer_priority_out_t, ADM_get_transfer_priority, true); + REGISTER_RPC(client, "ADM_get_transfer_priority", + ADM_get_transfer_priority_in_t, + ADM_get_transfer_priority_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_set_transfer_priority", ADM_set_transfer_priority_in_t, - ADM_set_transfer_priority_out_t, ADM_set_transfer_priority, true); + REGISTER_RPC(client, "ADM_set_transfer_priority", + ADM_set_transfer_priority_in_t, + ADM_set_transfer_priority_out_t, NULL, true); REGISTER_RPC(client, "ADM_cancel_transfer", ADM_cancel_transfer_in_t, - ADM_cancel_transfer_out_t, ADM_cancel_transfer, true); + ADM_cancel_transfer_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_pending_transfers", ADM_get_pending_transfers_in_t, - ADM_get_pending_transfers_out_t, ADM_get_pending_transfers, true); + REGISTER_RPC(client, "ADM_get_pending_transfers", + ADM_get_pending_transfers_in_t, + ADM_get_pending_transfers_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_qos_constraints", ADM_set_qos_constraints_in_t, ADM_set_qos_constraints_out_t, - ADM_set_qos_constraints, true); + NULL, true); REGISTER_RPC(client, "ADM_get_qos_constraints", ADM_get_qos_constraints_in_t, ADM_get_qos_constraints_out_t, - ADM_get_qos_constraints, true); + NULL, true); - REGISTER_RPC( - client, "ADM_define_data_operation", ADM_define_data_operation_in_t, - ADM_define_data_operation_out_t, ADM_define_data_operation, true); + REGISTER_RPC(client, "ADM_define_data_operation", + ADM_define_data_operation_in_t, + ADM_define_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_connect_data_operation", ADM_connect_data_operation_in_t, - ADM_connect_data_operation_out_t, ADM_connect_data_operation, - true); + ADM_connect_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_finalize_data_operation", ADM_finalize_data_operation_in_t, - ADM_finalize_data_operation_out_t, ADM_finalize_data_operation, - true); + ADM_finalize_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_link_transfer_to_data_operation", ADM_link_transfer_to_data_operation_in_t, - ADM_link_transfer_to_data_operation_out_t, - ADM_link_transfer_to_data_operation, true); + ADM_link_transfer_to_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_get_statistics", ADM_get_statistics_in_t, - ADM_get_statistics_out_t, ADM_get_statistics, true); + ADM_get_statistics_out_t, NULL, true); } } // namespace diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 4b286642..5d768380 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -30,124 +30,118 @@ void rpc_registration_cb(scord::network::rpc_client* client) { - REGISTER_RPC(client, "ADM_ping", void, void, ADM_ping, false); + REGISTER_RPC(client, "ADM_ping", void, void, NULL, false); REGISTER_RPC(client, "ADM_register_job", ADM_register_job_in_t, - ADM_register_job_out_t, ADM_register_job, true); + ADM_register_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_job", ADM_update_job_in_t, - ADM_update_job_out_t, ADM_update_job, true); + ADM_update_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_remove_job", ADM_remove_job_in_t, - ADM_remove_job_out_t, ADM_remove_job, true); + ADM_remove_job_out_t, NULL, true); REGISTER_RPC(client, "ADM_register_adhoc_storage", ADM_register_adhoc_storage_in_t, - ADM_register_adhoc_storage_out_t, ADM_register_adhoc_storage, - true); + ADM_register_adhoc_storage_out_t, NULL, true); REGISTER_RPC(client, "ADM_update_adhoc_storage", ADM_update_adhoc_storage_in_t, ADM_update_adhoc_storage_out_t, - ADM_update_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_remove_adhoc_storage", ADM_remove_adhoc_storage_in_t, ADM_remove_adhoc_storage_out_t, - ADM_remove_adhoc_storage, true); + NULL, true); REGISTER_RPC(client, "ADM_deploy_adhoc_storage", ADM_deploy_adhoc_storage_in_t, ADM_deploy_adhoc_storage_out_t, - ADM_deploy_adhoc_storage, true); + NULL, true); - REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, - ADM_input, true); + REGISTER_RPC(client, "ADM_input", ADM_input_in_t, ADM_input_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, - ADM_output, true); + REGISTER_RPC(client, "ADM_output", ADM_output_in_t, ADM_output_out_t, NULL, + true); - REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, - ADM_inout, true); + REGISTER_RPC(client, "ADM_inout", ADM_inout_in_t, ADM_inout_out_t, NULL, + true); REGISTER_RPC(client, "ADM_adhoc_context", ADM_adhoc_context_in_t, - ADM_adhoc_context_out_t, ADM_adhoc_context, true); + ADM_adhoc_context_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_context_id", ADM_adhoc_context_id_in_t, - ADM_adhoc_context_id_out_t, ADM_adhoc_context_id, true); + ADM_adhoc_context_id_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_nodes", ADM_adhoc_nodes_in_t, - ADM_adhoc_nodes_out_t, ADM_adhoc_nodes, true); + ADM_adhoc_nodes_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_walltime", ADM_adhoc_walltime_in_t, - ADM_adhoc_walltime_out_t, ADM_adhoc_walltime, true); + ADM_adhoc_walltime_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_access", ADM_adhoc_access_in_t, - ADM_adhoc_access_out_t, ADM_adhoc_access, true); + ADM_adhoc_access_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_distribution", ADM_adhoc_distribution_in_t, - ADM_adhoc_distribution_out_t, ADM_adhoc_distribution, true); + ADM_adhoc_distribution_out_t, NULL, true); REGISTER_RPC(client, "ADM_adhoc_background_flush", ADM_adhoc_background_flush_in_t, - ADM_adhoc_background_flush_out_t, ADM_adhoc_background_flush, - true); + ADM_adhoc_background_flush_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_situ_ops", ADM_in_situ_ops_in_t, - ADM_in_situ_ops_out_t, ADM_in_situ_ops, true); + ADM_in_situ_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_in_transit_ops", ADM_in_transit_ops_in_t, - ADM_in_transit_ops_out_t, ADM_in_transit_ops, true); + ADM_in_transit_ops_out_t, NULL, true); REGISTER_RPC(client, "ADM_transfer_dataset", ADM_transfer_dataset_in_t, - ADM_transfer_dataset_out_t, ADM_transfer_dataset, true); + ADM_transfer_dataset_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_dataset_information", ADM_set_dataset_information_in_t, - ADM_set_dataset_information_out_t, ADM_set_dataset_information, - true); + ADM_set_dataset_information_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_io_resources", ADM_set_io_resources_in_t, - ADM_set_io_resources_out_t, ADM_set_io_resources, true); + ADM_set_io_resources_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_transfer_priority", ADM_get_transfer_priority_in_t, - ADM_get_transfer_priority_out_t, ADM_get_transfer_priority, true); + REGISTER_RPC(client, "ADM_get_transfer_priority", + ADM_get_transfer_priority_in_t, + ADM_get_transfer_priority_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_set_transfer_priority", ADM_set_transfer_priority_in_t, - ADM_set_transfer_priority_out_t, ADM_set_transfer_priority, true); + REGISTER_RPC(client, "ADM_set_transfer_priority", + ADM_set_transfer_priority_in_t, + ADM_set_transfer_priority_out_t, NULL, true); REGISTER_RPC(client, "ADM_cancel_transfer", ADM_cancel_transfer_in_t, - ADM_cancel_transfer_out_t, ADM_cancel_transfer, true); + ADM_cancel_transfer_out_t, NULL, true); - REGISTER_RPC( - client, "ADM_get_pending_transfers", ADM_get_pending_transfers_in_t, - ADM_get_pending_transfers_out_t, ADM_get_pending_transfers, true); + REGISTER_RPC(client, "ADM_get_pending_transfers", + ADM_get_pending_transfers_in_t, + ADM_get_pending_transfers_out_t, NULL, true); REGISTER_RPC(client, "ADM_set_qos_constraints", ADM_set_qos_constraints_in_t, ADM_set_qos_constraints_out_t, - ADM_set_qos_constraints, true); + NULL, true); REGISTER_RPC(client, "ADM_get_qos_constraints", ADM_get_qos_constraints_in_t, ADM_get_qos_constraints_out_t, - ADM_get_qos_constraints, true); + NULL, true); - REGISTER_RPC( - client, "ADM_define_data_operation", ADM_define_data_operation_in_t, - ADM_define_data_operation_out_t, ADM_define_data_operation, true); + REGISTER_RPC(client, "ADM_define_data_operation", + ADM_define_data_operation_in_t, + ADM_define_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_connect_data_operation", ADM_connect_data_operation_in_t, - ADM_connect_data_operation_out_t, ADM_connect_data_operation, - true); + ADM_connect_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_finalize_data_operation", ADM_finalize_data_operation_in_t, - ADM_finalize_data_operation_out_t, ADM_finalize_data_operation, - true); + ADM_finalize_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_link_transfer_to_data_operation", ADM_link_transfer_to_data_operation_in_t, - ADM_link_transfer_to_data_operation_out_t, - ADM_link_transfer_to_data_operation, true); + ADM_link_transfer_to_data_operation_out_t, NULL, true); REGISTER_RPC(client, "ADM_get_statistics", ADM_get_statistics_in_t, - ADM_get_statistics_out_t, ADM_get_statistics, true); + ADM_get_statistics_out_t, NULL, true); } namespace admire::detail { -- GitLab From 49b7a3c8bf04b1d7a52dd13fb103438dfc0f6fcc Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Tue, 12 Jul 2022 19:26:41 +0200 Subject: [PATCH 03/25] Separate RPC type definitions from RPC handlers --- src/common/CMakeLists.txt | 6 + src/common/network/CMakeLists.txt | 2 + .../network/proto}/CMakeLists.txt | 18 +- .../network/proto/rpc_types.c} | 8 +- .../network/proto/rpc_types.h} | 276 ++++++++++++------ src/lib/CMakeLists.txt | 11 +- src/lib/admire.cpp | 2 +- src/lib/c_wrapper.cpp | 86 +----- src/lib/detail/impl.cpp | 2 +- src/scord-ctl/CMakeLists.txt | 9 +- .../rpc_handlers.cpp} | 3 +- .../{rpcs/private.hpp => rpc_handlers.hpp} | 14 +- src/scord-ctl/rpcs/CMakeLists.txt | 31 -- src/scord-ctl/rpcs/private.cpp | 41 --- src/scord-ctl/scord-ctl.cpp | 4 +- src/scord/CMakeLists.txt | 34 +-- .../public.cpp => scord/rpc_handlers.cpp} | 106 ++++--- src/scord/rpc_handlers.hpp | 159 ++++++++++ src/scord/scord.cpp | 4 +- 19 files changed, 466 insertions(+), 350 deletions(-) rename src/{scord/rpcs => common/network/proto}/CMakeLists.txt (82%) rename src/{scord/rpcs/private.hpp => common/network/proto/rpc_types.c} (87%) rename src/{lib/rpcs/public.hpp => common/network/proto/rpc_types.h} (67%) rename src/{scord/rpcs/private.cpp => scord-ctl/rpc_handlers.cpp} (95%) rename src/scord-ctl/{rpcs/private.hpp => rpc_handlers.hpp} (86%) delete mode 100644 src/scord-ctl/rpcs/CMakeLists.txt delete mode 100644 src/scord-ctl/rpcs/private.cpp rename src/{lib/rpcs/public.cpp => scord/rpc_handlers.cpp} (96%) create mode 100644 src/scord/rpc_handlers.hpp diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f3fbb8b2..65d9daea 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -44,3 +44,9 @@ add_library(common::network::engine ALIAS _network_engine) target_include_directories(_rpc_server INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::rpc_server ALIAS _rpc_server) + + +target_include_directories(_rpc_types INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}) +add_library(common::network::rpc_types ALIAS _rpc_types) + diff --git a/src/common/network/CMakeLists.txt b/src/common/network/CMakeLists.txt index 5aa5930d..63049547 100644 --- a/src/common/network/CMakeLists.txt +++ b/src/common/network/CMakeLists.txt @@ -43,3 +43,5 @@ target_sources( ) target_link_libraries(_rpc_server PUBLIC common::config _network_engine) + +add_subdirectory(proto) diff --git a/src/scord/rpcs/CMakeLists.txt b/src/common/network/proto/CMakeLists.txt similarity index 82% rename from src/scord/rpcs/CMakeLists.txt rename to src/common/network/proto/CMakeLists.txt index 38b0acf5..cbe8f47b 100644 --- a/src/scord/rpcs/CMakeLists.txt +++ b/src/common/network/proto/CMakeLists.txt @@ -22,10 +22,16 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -add_library(scord_ctl_private_rpcs STATIC) -target_sources(scord_ctl_private_rpcs - PRIVATE private.cpp private.hpp) +add_library(_rpc_types STATIC) + +set_property(TARGET _rpc_types PROPERTY POSITION_INDEPENDENT_CODE ON) + +target_include_directories(_rpc_types PUBLIC ${CMAKE_SOURCE_DIR}/src/lib) +target_sources( + _rpc_types + PRIVATE rpc_types.h rpc_types.c ${CMAKE_SOURCE_DIR}/src/lib/admire.h + ${CMAKE_SOURCE_DIR}/src/lib/admire_types.h +) + +target_link_libraries(_rpc_types PRIVATE Mercury::Mercury Margo::Margo) -target_include_directories(scord_ctl_private_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(scord_ctl_private_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET scord_ctl_private_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/scord/rpcs/private.hpp b/src/common/network/proto/rpc_types.c similarity index 87% rename from src/scord/rpcs/private.hpp rename to src/common/network/proto/rpc_types.c index 3af7df82..1dcea7b9 100644 --- a/src/scord/rpcs/private.hpp +++ b/src/common/network/proto/rpc_types.c @@ -22,11 +22,5 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#ifndef SCORD_RPCS_PRIVATE_HPP -#define SCORD_RPCS_PRIVATE_HPP +#include "rpc_types.h" -#include - -DECLARE_MARGO_RPC_HANDLER(ADM_ping); - -#endif // SCORD_RPCS_PRIVATE_HPP diff --git a/src/lib/rpcs/public.hpp b/src/common/network/proto/rpc_types.h similarity index 67% rename from src/lib/rpcs/public.hpp rename to src/common/network/proto/rpc_types.h index 5e03eef0..cc6614b9 100644 --- a/src/lib/rpcs/public.hpp +++ b/src/common/network/proto/rpc_types.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain * * This software was partially supported by the EuroHPC-funded project ADMIRE * (Project ID: 956748, https://www.admire-eurohpc.eu). @@ -22,100 +22,253 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -// clang-format off -#ifndef SCORD_RPCS_PUBLIC_HPP -#define SCORD_RPCS_PUBLIC_HPP +#ifndef SCORD_PROTO_TYPES_HPP +#define SCORD_PROTO_TYPES_HPP -#include -#include +#include #include #include -#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * N.B. MERCURY_GEN_STRUCT_PROC requires a `typedef` as its first argument, but + * admire_types.h also requires types to be defined as `struct T`s. Defining RPC + * types as `typedef struct T { ... } T;` solves both problems + */ + +typedef struct adm_node { + const char* n_hostname; +} adm_node; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_node, + ((hg_const_string_t) (n_hostname)) +); +// clang-format on + +typedef struct adm_dataset { + const char* d_id; +} adm_dataset; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_dataset, + ((hg_const_string_t) (d_id)) +); +// clang-format on + +typedef struct adm_job { + uint64_t j_id; +} adm_job; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_job, + ((hg_uint64_t) (j_id)) +); +// clang-format on + +struct adm_qos_entity { + ADM_qos_scope_t e_scope; + union { + ADM_node_t e_node; + ADM_job_t e_job; + ADM_dataset_t e_dataset; + ADM_transfer_t e_transfer; + }; +}; + +// TODO: union decoder + +struct adm_qos_limit { + ADM_qos_entity_t l_entity; + ADM_qos_class_t l_class; + uint64_t l_value; +}; + +#if 0 +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_qos_limit, + ((adm_qos_entity) (l_entity)) + ((int) (l_class)) + ((hg_uint64_t) (l_value)) +); +// clang-format on +#endif + +typedef struct adm_transfer { + // TODO: undefined for now + int32_t placeholder; +} adm_transfer; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_transfer, + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_dataset_info { + // TODO: undefined for now + int32_t placeholder; +} adm_dataset_info; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_dataset_info, + ((hg_int32_t) (placeholder)) +); +// clang-format on + +// TODO: union decoder +struct adm_storage { + const char* s_id; + ADM_storage_type_t s_type; + union { + ADM_adhoc_context_t s_adhoc_ctx; + ADM_pfs_context_t s_pfs_ctx; + }; +}; + +typedef struct adm_storage_resources { + // TODO: undefined for now + int32_t placeholder; +} adm_storage_resources; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_storage_resources, + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_data_operation { + // TODO: undefined for now + int32_t placeholder; +} adm_data_operation; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_data_operation, + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_adhoc_context { + /** The adhoc storage system execution mode */ + ADM_adhoc_mode_t c_mode; + /** The adhoc storage system access type */ + ADM_adhoc_access_t c_access; + /** The number of nodes for the adhoc storage system */ + uint32_t c_nodes; + /** The adhoc storage system walltime */ + uint32_t c_walltime; + /** Whether the adhoc storage system should flush data in the background */ + bool c_should_bg_flush; +} adm_adhoc_context; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_adhoc_context, + ((hg_int32_t) (c_mode)) + ((hg_int32_t) (c_access)) + ((hg_uint32_t) (c_nodes)) + ((hg_uint32_t) (c_walltime)) + ((hg_bool_t) (c_should_bg_flush)) +) +// clang-format on + +typedef struct adm_pfs_context { + /** The PFS mount point */ + const char* c_mount; +} adm_pfs_context; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_pfs_context, + ((hg_const_string_t) (c_mount)) +); +// clang-format on + +/** The I/O requirements for a job */ +typedef struct adm_job_requirements { + /** An array of input datasets */ + ADM_dataset_t* r_inputs; + /** The number of datasets in r_inputs */ + size_t r_num_inputs; + /** A list of output datasets */ + ADM_dataset_t* r_outputs; + /** The number of datasets in r_outputs */ + size_t r_num_outputs; + /** An optional definition for a specific adhoc storage instance */ + ADM_adhoc_context_t r_adhoc_ctx; +} adm_job_requirements; -// FIXME: cannot be in a namespace due to Margo limitations -// namespace scord::network::rpc { +// TODO: MERCURY_GEN_STRUCT_PROC -/// ADM_ping -DECLARE_MARGO_RPC_HANDLER(ADM_ping); /// ADM_register_job MERCURY_GEN_PROC(ADM_register_job_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_register_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_job); - /// ADM_update_job MERCURY_GEN_PROC(ADM_update_job_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_job); - /// ADM_remove_job MERCURY_GEN_PROC(ADM_remove_job_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_job_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_job); - /// ADM_register_adhoc_storage MERCURY_GEN_PROC(ADM_register_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_register_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); - /// ADM_update_adhoc_storage MERCURY_GEN_PROC(ADM_update_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); - /// ADM_remove_adhoc_storage MERCURY_GEN_PROC(ADM_remove_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); - /// ADM_deploy_adhoc_storage MERCURY_GEN_PROC(ADM_deploy_adhoc_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_deploy_adhoc_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); - /// ADM_register_pfs_storage MERCURY_GEN_PROC(ADM_register_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_register_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); - /// ADM_update_pfs_storage MERCURY_GEN_PROC(ADM_update_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_update_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); - /// ADM_remove_pfs_storage MERCURY_GEN_PROC(ADM_remove_pfs_storage_in_t, ((int32_t) (reqs))) MERCURY_GEN_PROC(ADM_remove_pfs_storage_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); - /// ADM_input MERCURY_GEN_PROC(ADM_input_in_t, ((hg_const_string_t) (origin))((hg_const_string_t) (target))) MERCURY_GEN_PROC(ADM_input_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_input); - /// ADM_output MERCURY_GEN_PROC(ADM_output_in_t, @@ -123,8 +276,6 @@ MERCURY_GEN_PROC(ADM_output_in_t, MERCURY_GEN_PROC(ADM_output_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_output); - /// ADM_inout MERCURY_GEN_PROC(ADM_inout_in_t, @@ -132,8 +283,6 @@ MERCURY_GEN_PROC(ADM_inout_in_t, MERCURY_GEN_PROC(ADM_inout_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_inout); - /// ADM_adhoc_context MERCURY_GEN_PROC(ADM_adhoc_context_in_t, ((hg_const_string_t) (context))) @@ -141,32 +290,24 @@ MERCURY_GEN_PROC(ADM_adhoc_context_in_t, ((hg_const_string_t) (context))) MERCURY_GEN_PROC(ADM_adhoc_context_out_t, ((int32_t) (ret))((int32_t) (adhoc_context))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context); - /// ADM_adhoc_context_id MERCURY_GEN_PROC(ADM_adhoc_context_id_in_t, ((int32_t) (context_id))) MERCURY_GEN_PROC(ADM_adhoc_context_id_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context_id); - /// ADM_adhoc_nodes MERCURY_GEN_PROC(ADM_adhoc_nodes_in_t, ((int32_t) (nodes))) MERCURY_GEN_PROC(ADM_adhoc_nodes_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) - /// ADM_adhoc_walltime MERCURY_GEN_PROC(ADM_adhoc_walltime_in_t, ((int32_t) (walltime))) MERCURY_GEN_PROC(ADM_adhoc_walltime_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_walltime); - /// ADM_adhoc_access @@ -174,8 +315,6 @@ MERCURY_GEN_PROC(ADM_adhoc_access_in_t, ((hg_const_string_t) (access))) MERCURY_GEN_PROC(ADM_adhoc_access_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_access); - /// ADM_adhoc_distribution MERCURY_GEN_PROC(ADM_adhoc_distribution_in_t, @@ -183,32 +322,24 @@ MERCURY_GEN_PROC(ADM_adhoc_distribution_in_t, MERCURY_GEN_PROC(ADM_adhoc_distribution_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_distribution); - /// ADM_adhoc_background_flush MERCURY_GEN_PROC(ADM_adhoc_background_flush_in_t, ((hg_bool_t) (b_flush))) MERCURY_GEN_PROC(ADM_adhoc_background_flush_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush); - /// ADM_in_situ_ops MERCURY_GEN_PROC(ADM_in_situ_ops_in_t, ((hg_const_string_t) (in_situ))) MERCURY_GEN_PROC(ADM_in_situ_ops_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_in_situ_ops); - /// ADM_in_transit_ops MERCURY_GEN_PROC(ADM_in_transit_ops_in_t, ((hg_const_string_t) (in_transit))) MERCURY_GEN_PROC(ADM_in_transit_ops_out_t, ((int32_t) (ret))) -DECLARE_MARGO_RPC_HANDLER(ADM_in_transit_ops); - /// ADM_transfer_dataset @@ -221,8 +352,6 @@ MERCURY_GEN_PROC( MERCURY_GEN_PROC(ADM_transfer_dataset_out_t, ((int32_t) (ret))((hg_const_string_t) (transfer_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_transfer_dataset); - /// ADM_set_dataset_information MERCURY_GEN_PROC(ADM_set_dataset_information_in_t, @@ -232,8 +361,6 @@ MERCURY_GEN_PROC(ADM_set_dataset_information_in_t, MERCURY_GEN_PROC(ADM_set_dataset_information_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_dataset_information); - /// ADM_set_io_resources MERCURY_GEN_PROC(ADM_set_io_resources_in_t, @@ -243,8 +370,6 @@ MERCURY_GEN_PROC(ADM_set_io_resources_in_t, MERCURY_GEN_PROC(ADM_set_io_resources_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_io_resources); - /// ADM_get_transfer_priority MERCURY_GEN_PROC(ADM_get_transfer_priority_in_t, ((int32_t) (transfer_id))) @@ -252,8 +377,6 @@ MERCURY_GEN_PROC(ADM_get_transfer_priority_in_t, ((int32_t) (transfer_id))) MERCURY_GEN_PROC(ADM_get_transfer_priority_out_t, ((int32_t) (ret))((int32_t) (priority))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_transfer_priority); - /// ADM_set_transfer_priority MERCURY_GEN_PROC(ADM_set_transfer_priority_in_t, @@ -262,8 +385,6 @@ MERCURY_GEN_PROC(ADM_set_transfer_priority_in_t, MERCURY_GEN_PROC(ADM_set_transfer_priority_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_transfer_priority); - /// ADM_cancel_transfer MERCURY_GEN_PROC(ADM_cancel_transfer_in_t, ((int32_t) (transfer_id))) @@ -271,8 +392,6 @@ MERCURY_GEN_PROC(ADM_cancel_transfer_in_t, ((int32_t) (transfer_id))) MERCURY_GEN_PROC(ADM_cancel_transfer_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_cancel_transfer); - /// ADM_get_pending_transfers MERCURY_GEN_PROC(ADM_get_pending_transfers_in_t, ((hg_const_string_t) (value))) @@ -280,8 +399,6 @@ MERCURY_GEN_PROC(ADM_get_pending_transfers_in_t, ((hg_const_string_t) (value))) MERCURY_GEN_PROC(ADM_get_pending_transfers_out_t, ((int32_t) (ret))((hg_const_string_t) (pending_transfers))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_pending_transfers); - /// ADM_set_qos_constraints MERCURY_GEN_PROC( @@ -292,8 +409,6 @@ MERCURY_GEN_PROC( MERCURY_GEN_PROC(ADM_set_qos_constraints_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_set_qos_constraints); - /// ADM_get_qos_constraints MERCURY_GEN_PROC(ADM_get_qos_constraints_in_t, @@ -302,8 +417,6 @@ MERCURY_GEN_PROC(ADM_get_qos_constraints_in_t, MERCURY_GEN_PROC(ADM_get_qos_constraints_out_t, ((int32_t) (ret))((hg_const_string_t) (list))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_qos_constraints); - /// ADM_define_data_operation MERCURY_GEN_PROC(ADM_define_data_operation_in_t, @@ -313,8 +426,6 @@ MERCURY_GEN_PROC(ADM_define_data_operation_in_t, MERCURY_GEN_PROC(ADM_define_data_operation_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_define_data_operation); - /// ADM_connect_data_operation MERCURY_GEN_PROC(ADM_connect_data_operation_in_t, @@ -326,8 +437,6 @@ MERCURY_GEN_PROC(ADM_connect_data_operation_out_t, ((int32_t) (ret))((hg_const_string_t) (data))( (hg_const_string_t) (operation_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_connect_data_operation); - /// ADM_finalize_data_operation MERCURY_GEN_PROC(ADM_finalize_data_operation_in_t, ((int32_t) (operation_id))) @@ -336,8 +445,6 @@ MERCURY_GEN_PROC(ADM_finalize_data_operation_out_t, ((int32_t) (ret))((int32_t) (status))) -DECLARE_MARGO_RPC_HANDLER(ADM_finalize_data_operation); - /// ADM_link_transfer_to_data_operation MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_in_t, @@ -348,8 +455,6 @@ MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_in_t, MERCURY_GEN_PROC(ADM_link_transfer_to_data_operation_out_t, ((int32_t) (ret))((hg_const_string_t) (operation_handle))) -DECLARE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation); - /// ADM_get_statistics MERCURY_GEN_PROC(ADM_get_statistics_in_t, @@ -358,10 +463,9 @@ MERCURY_GEN_PROC(ADM_get_statistics_in_t, MERCURY_GEN_PROC(ADM_get_statistics_out_t, ((int32_t) (ret))((hg_const_string_t) (job_statistics))) -DECLARE_MARGO_RPC_HANDLER(ADM_get_statistics); +#ifdef __cplusplus +}; // extern "C" +#endif // __cplusplus -//} // namespace scord::network::rpc - -#endif // SCORD_RPCS_PUBLIC_HPP -// clang-format on +#endif // SCORD_PROTO_TYPES_HPP diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2d1b6c5e..76825c6b 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -22,15 +22,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -# target for the public rpcs defined by the API that need to be shared by scord -add_library(api_rpcs STATIC) -target_sources(api_rpcs - PRIVATE rpcs/public.cpp rpcs/public.hpp) - -target_include_directories(api_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/rpcs) -target_link_libraries(api_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET api_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) - # the client library implementing the actual API add_library(adm_iosched SHARED) @@ -40,7 +31,7 @@ target_sources(adm_iosched target_include_directories(adm_iosched PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(adm_iosched PRIVATE common::network::engine api_rpcs PUBLIC +target_link_libraries(adm_iosched PRIVATE common::network::engine common::network::rpc_types PUBLIC tl::expected) install( diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index f159a172..f771f98b 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -24,8 +24,8 @@ #include #include +#include #include -#include "rpcs/public.hpp" #include "detail/impl.hpp" diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 6cf1747f..2d0be37a 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "detail/impl.hpp" @@ -37,91 +38,6 @@ struct adm_server { const char* s_address; }; -struct adm_node { - const char* n_hostname; -}; - -struct adm_dataset { - const char* d_id; -}; - -struct adm_job { - uint64_t j_id; -}; - -struct adm_qos_entity { - ADM_qos_scope_t e_scope; - union { - ADM_node_t e_node; - ADM_job_t e_job; - ADM_dataset_t e_dataset; - ADM_transfer_t e_transfer; - }; -}; - -struct adm_qos_limit { - ADM_qos_entity_t l_entity; - ADM_qos_class_t l_class; - uint64_t l_value; -}; - -struct adm_transfer { - // TODO: empty for now -}; - -struct adm_dataset_info { - // TODO: empty for now -}; - -struct adm_storage { - const char* s_id; - ADM_storage_type_t s_type; - union { - ADM_adhoc_context_t s_adhoc_ctx; - ADM_pfs_context_t s_pfs_ctx; - }; -}; - -struct adm_storage_resources { - // TODO: empty for now -}; - -struct adm_data_operation { - // TODO: empty for now -}; - -struct adm_adhoc_context { - /** The adhoc storage system execution mode */ - ADM_adhoc_mode_t c_mode; - /** The adhoc storage system access type */ - ADM_adhoc_access_t c_access; - /** The number of nodes for the adhoc storage system */ - uint32_t c_nodes; - /** The adhoc storage system walltime */ - uint32_t c_walltime; - /** Whether the adhoc storage system should flush data in the background */ - bool c_should_bg_flush; -}; - -struct adm_pfs_context { - /** The PFS mount point */ - const char* c_mount; -}; - -/** The I/O requirements for a job */ -struct adm_job_requirements { - /** An array of input datasets */ - ADM_dataset_t* r_inputs; - /** The number of datasets in r_inputs */ - size_t r_num_inputs; - /** A list of output datasets */ - ADM_dataset_t* r_outputs; - /** The number of datasets in r_outputs */ - size_t r_num_outputs; - /** An optional definition for a specific adhoc storage instance */ - ADM_adhoc_context_t r_adhoc_ctx; -}; - ADM_server_t ADM_server_create(const char* protocol, const char* address) { diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 5d768380..b6af16d3 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -24,7 +24,7 @@ #include #include -#include "rpcs/public.hpp" +#include #include "impl.hpp" void diff --git a/src/scord-ctl/CMakeLists.txt b/src/scord-ctl/CMakeLists.txt index 26ea4e21..76cd26aa 100644 --- a/src/scord-ctl/CMakeLists.txt +++ b/src/scord-ctl/CMakeLists.txt @@ -22,11 +22,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -# import rpc definitions for scord-ctl -add_subdirectory(rpcs) - # scord-ctl daemon -add_executable(scord-ctl scord-ctl.cpp) +add_executable(scord-ctl) + +target_sources(scord-ctl PRIVATE scord-ctl.cpp rpc_handlers.hpp rpc_handlers.cpp) target_include_directories( scord-ctl @@ -36,7 +35,7 @@ target_include_directories( target_link_libraries( scord-ctl PRIVATE common::config common::logger common::network::rpc_server - scord_ctl_private_rpcs fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus + common::network::rpc_types fmt::fmt Boost::program_options ) install(TARGETS scord DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/scord/rpcs/private.cpp b/src/scord-ctl/rpc_handlers.cpp similarity index 95% rename from src/scord/rpcs/private.cpp rename to src/scord-ctl/rpc_handlers.cpp index d472d44e..71115a4a 100644 --- a/src/scord/rpcs/private.cpp +++ b/src/scord-ctl/rpc_handlers.cpp @@ -23,7 +23,8 @@ *****************************************************************************/ #include -#include "private.hpp" +#include +#include "rpc_handlers.hpp" static void ADM_ping(hg_handle_t h) { diff --git a/src/scord-ctl/rpcs/private.hpp b/src/scord-ctl/rpc_handlers.hpp similarity index 86% rename from src/scord-ctl/rpcs/private.hpp rename to src/scord-ctl/rpc_handlers.hpp index 6429eade..633befa2 100644 --- a/src/scord-ctl/rpcs/private.hpp +++ b/src/scord-ctl/rpc_handlers.hpp @@ -22,11 +22,19 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#ifndef SCORD_CTL_RPCS_PRIVATE_HPP -#define SCORD_CTL_RPCS_PRIVATE_HPP +#ifndef SCORD_CTL_RPC_HANDLERS_HPP +#define SCORD_CTL_RPC_HANDLERS_HPP #include +#ifdef __cplusplus +extern "C" { +#endif + DECLARE_MARGO_RPC_HANDLER(ADM_ping); -#endif // SCORD_CTL_RPCS_PRIVATE_HPP +#ifdef __cplusplus +}; +#endif + +#endif // SCORD_CTL_RPC_HANDLERS_HPP diff --git a/src/scord-ctl/rpcs/CMakeLists.txt b/src/scord-ctl/rpcs/CMakeLists.txt deleted file mode 100644 index ae011dd9..00000000 --- a/src/scord-ctl/rpcs/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -################################################################################ -# Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain # -# # -# This software was partially supported by the EuroHPC-funded project ADMIRE # -# (Project ID: 956748, https://www.admire-eurohpc.eu). # -# # -# This file is part of scord. # -# # -# scord is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# scord is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with scord. If not, see . # -# # -# SPDX-License-Identifier: GPL-3.0-or-later # -################################################################################ - -add_library(scord_private_rpcs STATIC) -target_sources(scord_private_rpcs - PRIVATE private.cpp private.hpp) - -target_include_directories(scord_private_rpcs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(scord_private_rpcs PUBLIC common::logger Margo::Margo) -set_property(TARGET scord_private_rpcs PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/src/scord-ctl/rpcs/private.cpp b/src/scord-ctl/rpcs/private.cpp deleted file mode 100644 index d472d44e..00000000 --- a/src/scord-ctl/rpcs/private.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain - * - * This software was partially supported by the EuroHPC-funded project ADMIRE - * (Project ID: 956748, https://www.admire-eurohpc.eu). - * - * This file is part of scord. - * - * scord is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * scord is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with scord. If not, see . - * - * SPDX-License-Identifier: GPL-3.0-or-later - *****************************************************************************/ - -#include -#include "private.hpp" - -static void -ADM_ping(hg_handle_t h) { - - hg_return_t ret; - - [[maybe_unused]] margo_instance_id mid = margo_hg_handle_get_instance(h); - - LOGGER_INFO("PING(noargs)"); - - ret = margo_destroy(h); - assert(ret == HG_SUCCESS); -} - -DEFINE_MARGO_RPC_HANDLER(ADM_ping); diff --git a/src/scord-ctl/scord-ctl.cpp b/src/scord-ctl/scord-ctl.cpp index b99caff9..bd83e9bb 100644 --- a/src/scord-ctl/scord-ctl.cpp +++ b/src/scord-ctl/scord-ctl.cpp @@ -33,9 +33,9 @@ #include #include +#include #include -#include -#include "rpcs/private.hpp" +#include "rpc_handlers.hpp" namespace fs = std::filesystem; namespace bpo = boost::program_options; diff --git a/src/scord/CMakeLists.txt b/src/scord/CMakeLists.txt index aad2746c..be566b3d 100644 --- a/src/scord/CMakeLists.txt +++ b/src/scord/CMakeLists.txt @@ -22,35 +22,10 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ -################################################################################ -# Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain # -# # -# This software was partially supported by the EuroHPC-funded project ADMIRE # -# (Project ID: 956748, https://www.admire-eurohpc.eu). # -# # -# This file is part of scord. # -# # -# scord is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# scord is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with scord. If not, see . # -# # -# SPDX-License-Identifier: GPL-3.0-or-later # -################################################################################ - -# import rpc definitions for scord -add_subdirectory(rpcs) - # scord daemon -add_executable(scord scord.cpp) +add_executable(scord) + +target_sources(scord PRIVATE scord.cpp rpc_handlers.hpp rpc_handlers.cpp) target_include_directories( scord @@ -63,8 +38,7 @@ target_link_libraries( PRIVATE common::config common::logger common::network::rpc_server - api_rpcs - scord_private_rpcs + common::network::rpc_types fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus diff --git a/src/lib/rpcs/public.cpp b/src/scord/rpc_handlers.cpp similarity index 96% rename from src/lib/rpcs/public.cpp rename to src/scord/rpc_handlers.cpp index e10b6587..fa3daf8f 100644 --- a/src/lib/rpcs/public.cpp +++ b/src/scord/rpc_handlers.cpp @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain * * This software was partially supported by the EuroHPC-funded project ADMIRE * (Project ID: 956748, https://www.admire-eurohpc.eu). @@ -22,12 +22,14 @@ * SPDX-License-Identifier: GPL-3.0-or-later *****************************************************************************/ -#include "public.hpp" +#include +#include +#include "rpc_handlers.hpp" static void ADM_ping(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; [[maybe_unused]] margo_instance_id mid = margo_hg_handle_get_instance(h); @@ -42,7 +44,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_ping); static void ADM_register_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_job_in_t in; ADM_register_job_out_t out; @@ -74,7 +76,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_job); static void ADM_update_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_job_in_t in; ADM_update_job_out_t out; @@ -106,7 +108,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_job); static void ADM_remove_job(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_job_in_t in; ADM_remove_job_out_t out; @@ -137,7 +139,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_job); static void ADM_register_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_adhoc_storage_in_t in; ADM_register_adhoc_storage_out_t out; @@ -168,7 +170,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); static void ADM_update_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_adhoc_storage_in_t in; ADM_update_adhoc_storage_out_t out; @@ -199,7 +201,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); static void ADM_remove_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_adhoc_storage_in_t in; ADM_remove_adhoc_storage_out_t out; @@ -230,7 +232,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); static void ADM_deploy_adhoc_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_deploy_adhoc_storage_in_t in; ADM_deploy_adhoc_storage_out_t out; @@ -261,7 +263,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); static void ADM_register_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_register_pfs_storage_in_t in; ADM_register_pfs_storage_out_t out; @@ -292,7 +294,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); static void ADM_update_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_update_pfs_storage_in_t in; ADM_update_pfs_storage_out_t out; @@ -323,7 +325,7 @@ DEFINE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); static void ADM_remove_pfs_storage(hg_handle_t h) { - hg_return_t ret; + [[maybe_unused]] hg_return_t ret; ADM_remove_pfs_storage_in_t in; ADM_remove_pfs_storage_out_t out; @@ -363,7 +365,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); */ static void ADM_input(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_input_in_t in; ADM_input_out_t out; @@ -408,7 +411,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_input) */ static void ADM_output(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_output_in_t in; ADM_output_out_t out; @@ -453,7 +457,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_output) */ static void ADM_inout(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_inout_in_t in; ADM_inout_out_t out; @@ -507,7 +512,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_inout) */ static void ADM_adhoc_context(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_context_in_t in; ADM_adhoc_context_out_t out; @@ -561,7 +567,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_context) */ static void ADM_adhoc_context_id(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_context_id_in_t in; ADM_adhoc_context_id_out_t out; @@ -606,7 +613,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_context_id) */ static void ADM_adhoc_nodes(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_nodes_in_t in; ADM_adhoc_nodes_out_t out; @@ -654,7 +662,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) */ static void ADM_adhoc_walltime(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_walltime_in_t in; ADM_adhoc_walltime_out_t out; @@ -697,7 +706,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_walltime) */ static void ADM_adhoc_access(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_access_in_t in; ADM_adhoc_access_out_t out; @@ -750,7 +760,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_access) */ static void ADM_adhoc_distribution(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_distribution_in_t in; ADM_adhoc_distribution_out_t out; @@ -793,7 +804,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_distribution) */ static void ADM_adhoc_background_flush(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_adhoc_background_flush_in_t in; ADM_adhoc_background_flush_out_t out; @@ -827,7 +839,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush) */ static void ADM_in_situ_ops(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_in_situ_ops_in_t in; ADM_in_situ_ops_out_t out; @@ -868,7 +881,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_in_situ_ops) */ static void ADM_in_transit_ops(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_in_transit_ops_in_t in; ADM_in_transit_ops_out_t out; @@ -925,7 +939,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_in_transit_ops) */ static void ADM_transfer_dataset(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_transfer_dataset_in_t in; ADM_transfer_dataset_out_t out; @@ -984,7 +999,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_transfer_dataset) */ static void ADM_set_dataset_information(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_dataset_information_in_t in; ADM_set_dataset_information_out_t out; @@ -1039,7 +1055,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_dataset_information) */ static void ADM_set_io_resources(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_io_resources_in_t in; ADM_set_io_resources_out_t out; @@ -1090,7 +1107,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_io_resources) */ static void ADM_get_transfer_priority(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_transfer_priority_in_t in; ADM_get_transfer_priority_out_t out; @@ -1138,7 +1156,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_transfer_priority) */ static void ADM_set_transfer_priority(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_transfer_priority_in_t in; ADM_set_transfer_priority_out_t out; @@ -1185,7 +1204,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_transfer_priority) */ static void ADM_cancel_transfer(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_cancel_transfer_in_t in; ADM_cancel_transfer_out_t out; @@ -1229,7 +1249,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_cancel_transfer) */ static void ADM_get_pending_transfers(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_pending_transfers_in_t in; ADM_get_pending_transfers_out_t out; @@ -1272,7 +1293,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_pending_transfers) */ static void ADM_set_qos_constraints(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_set_qos_constraints_in_t in; ADM_set_qos_constraints_out_t out; @@ -1336,7 +1358,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_set_qos_constraints) */ static void ADM_get_qos_constraints(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_qos_constraints_in_t in; ADM_get_qos_constraints_out_t out; @@ -1398,7 +1421,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_get_qos_constraints) */ static void ADM_define_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_define_data_operation_in_t in; ADM_define_data_operation_out_t out; @@ -1461,7 +1485,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_define_data_operation) */ static void ADM_connect_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_connect_data_operation_in_t in; ADM_connect_data_operation_out_t out; @@ -1520,7 +1545,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_connect_data_operation) */ static void ADM_finalize_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_finalize_data_operation_in_t in; ADM_finalize_data_operation_out_t out; @@ -1576,7 +1602,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_finalize_data_operation) */ static void ADM_link_transfer_to_data_operation(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_link_transfer_to_data_operation_in_t in; ADM_link_transfer_to_data_operation_out_t out; @@ -1638,7 +1665,8 @@ DEFINE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation) */ static void ADM_get_statistics(hg_handle_t h) { - hg_return_t ret; + + [[maybe_unused]] hg_return_t ret; ADM_get_statistics_in_t in; ADM_get_statistics_out_t out; diff --git a/src/scord/rpc_handlers.hpp b/src/scord/rpc_handlers.hpp new file mode 100644 index 00000000..ee63174e --- /dev/null +++ b/src/scord/rpc_handlers.hpp @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright 2021, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +// clang-format off +#ifndef SCORD_RPC_HANDLERS_HPP +#define SCORD_RPC_HANDLERS_HPP + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// FIXME: cannot be in a namespace due to Margo limitations +// namespace scord::network::rpc { + +/// ADM_ping +DECLARE_MARGO_RPC_HANDLER(ADM_ping); + +/// ADM_register_job +DECLARE_MARGO_RPC_HANDLER(ADM_register_job); + +/// ADM_update_job +DECLARE_MARGO_RPC_HANDLER(ADM_update_job); + +/// ADM_remove_job +DECLARE_MARGO_RPC_HANDLER(ADM_remove_job); + +/// ADM_register_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_register_adhoc_storage); + +/// ADM_update_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_update_adhoc_storage); + +/// ADM_remove_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_remove_adhoc_storage); + +/// ADM_deploy_adhoc_storage +DECLARE_MARGO_RPC_HANDLER(ADM_deploy_adhoc_storage); + +/// ADM_register_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_register_pfs_storage); + +/// ADM_update_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_update_pfs_storage); + +/// ADM_remove_pfs_storage +DECLARE_MARGO_RPC_HANDLER(ADM_remove_pfs_storage); + +/// ADM_input +DECLARE_MARGO_RPC_HANDLER(ADM_input); + +/// ADM_output +DECLARE_MARGO_RPC_HANDLER(ADM_output); + +/// ADM_inout +DECLARE_MARGO_RPC_HANDLER(ADM_inout); + +/// ADM_adhoc_context +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context); + +/// ADM_adhoc_context_id +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_context_id); + +/// ADM_adhoc_nodes +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_nodes) + +/// ADM_adhoc_walltime +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_walltime); + + +/// ADM_adhoc_access +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_access); + +/// ADM_adhoc_distribution +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_distribution); + +/// ADM_adhoc_background_flush +DECLARE_MARGO_RPC_HANDLER(ADM_adhoc_background_flush); + +/// ADM_in_situ_ops +DECLARE_MARGO_RPC_HANDLER(ADM_in_situ_ops); + +/// ADM_in_transit_ops +DECLARE_MARGO_RPC_HANDLER(ADM_in_transit_ops); + + +/// ADM_transfer_dataset +DECLARE_MARGO_RPC_HANDLER(ADM_transfer_dataset); + +/// ADM_set_dataset_information +DECLARE_MARGO_RPC_HANDLER(ADM_set_dataset_information); + +/// ADM_set_io_resources +DECLARE_MARGO_RPC_HANDLER(ADM_set_io_resources); + +/// ADM_get_transfer_priority +DECLARE_MARGO_RPC_HANDLER(ADM_get_transfer_priority); + +/// ADM_set_transfer_priority +DECLARE_MARGO_RPC_HANDLER(ADM_set_transfer_priority); + +/// ADM_cancel_transfer +DECLARE_MARGO_RPC_HANDLER(ADM_cancel_transfer); + +/// ADM_get_pending_transfers +DECLARE_MARGO_RPC_HANDLER(ADM_get_pending_transfers); + +/// ADM_set_qos_constraints +DECLARE_MARGO_RPC_HANDLER(ADM_set_qos_constraints); + +/// ADM_get_qos_constraints +DECLARE_MARGO_RPC_HANDLER(ADM_get_qos_constraints); + +/// ADM_define_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_define_data_operation); + +/// ADM_connect_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_connect_data_operation); + +/// ADM_finalize_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_finalize_data_operation); + +/// ADM_link_transfer_to_data_operation +DECLARE_MARGO_RPC_HANDLER(ADM_link_transfer_to_data_operation); + +/// ADM_get_statistics +DECLARE_MARGO_RPC_HANDLER(ADM_get_statistics); + + +//} // namespace scord::network::rpc + +#ifdef __cplusplus +}; +#endif + +#endif // SCORD_RPC_HANDLERS_HPP +// clang-format on diff --git a/src/scord/scord.cpp b/src/scord/scord.cpp index 1d07fd50..d5b60932 100644 --- a/src/scord/scord.cpp +++ b/src/scord/scord.cpp @@ -33,9 +33,9 @@ #include #include +#include #include -#include -#include "rpcs/private.hpp" +#include "rpc_handlers.hpp" namespace fs = std::filesystem; namespace bpo = boost::program_options; -- GitLab From 528c6ab18f0c22eff2b28b249ab7781c79cacbf3 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Wed, 13 Jul 2022 06:41:19 +0200 Subject: [PATCH 04/25] Add ADM_dataset_list_t and related functions --- src/common/network/proto/rpc_types.c | 69 +++++++++++ src/common/network/proto/rpc_types.h | 32 +++-- src/lib/admire_types.h | 26 ++++ src/lib/c_wrapper.cpp | 174 ++++++++++++++++++++++++--- 4 files changed, 276 insertions(+), 25 deletions(-) diff --git a/src/common/network/proto/rpc_types.c b/src/common/network/proto/rpc_types.c index 1dcea7b9..dc10fad1 100644 --- a/src/common/network/proto/rpc_types.c +++ b/src/common/network/proto/rpc_types.c @@ -24,3 +24,72 @@ #include "rpc_types.h" +hg_return_t +hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { + hg_return_t ret = HG_SUCCESS; + ADM_dataset_list_t* list = (ADM_dataset_list_t*) data; + ADM_dataset_list_t tmp = NULL; + + hg_size_t length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + tmp = *list; + // write the length of the list + length = tmp->l_length; + ret = hg_proc_hg_size_t(proc, &tmp->l_length); + + if(ret != HG_SUCCESS) { + break; + } + + // write the list + for(size_t i = 0; i < length; ++i) { + ret = hg_proc_adm_dataset(proc, &tmp->l_datasets[i]); + + if(ret != HG_SUCCESS) { + break; + } + } + break; + + case HG_DECODE: { + + // find out the length of the list + ret = hg_proc_hg_size_t(proc, &length); + + if(ret != HG_SUCCESS) { + break; + } + + // loop and create list elements + tmp = (ADM_dataset_list_t) calloc(1, sizeof(struct adm_dataset_list)); + tmp->l_length = length; + tmp->l_datasets = + (adm_dataset*) calloc(length, sizeof(adm_dataset)); + + for(size_t i = 0; i < length; ++i) { + ret = hg_proc_adm_dataset(proc, &tmp->l_datasets[i]); + + if(ret != HG_SUCCESS) { + break; + } + } + + // return the newly-created list + *list = tmp; + + break; + } + + case HG_FREE: + tmp = *list; + free(tmp->l_datasets); + free(tmp); + ret = HG_SUCCESS; + break; + } + + return ret; +} diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index cc6614b9..c1b77f81 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -196,21 +196,35 @@ MERCURY_GEN_STRUCT_PROC( ); // clang-format on +struct adm_dataset_list { + /** An array of datasets */ + adm_dataset* l_datasets; + /** The length of the array */ + size_t l_length; +}; + +hg_return_t +hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data); + + /** The I/O requirements for a job */ typedef struct adm_job_requirements { /** An array of input datasets */ - ADM_dataset_t* r_inputs; - /** The number of datasets in r_inputs */ - size_t r_num_inputs; - /** A list of output datasets */ - ADM_dataset_t* r_outputs; - /** The number of datasets in r_outputs */ - size_t r_num_outputs; + ADM_dataset_list_t r_inputs; + /** An array of output datasets */ + ADM_dataset_list_t r_outputs; /** An optional definition for a specific adhoc storage instance */ - ADM_adhoc_context_t r_adhoc_ctx; + adm_adhoc_context* r_adhoc_ctx; } adm_job_requirements; -// TODO: MERCURY_GEN_STRUCT_PROC +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_job_requirements, + ((ADM_dataset_list_t) (r_inputs)) + ((ADM_dataset_list_t) (r_outputs)) + ((adm_adhoc_context) (r_adhoc_ctx)) +); +// clang-format on /// ADM_register_job diff --git a/src/lib/admire_types.h b/src/lib/admire_types.h index f04e2384..13b43bfe 100644 --- a/src/lib/admire_types.h +++ b/src/lib/admire_types.h @@ -88,6 +88,9 @@ typedef struct adm_dataset* ADM_dataset_t; /** Information about a dataset */ typedef struct adm_dataset_info* ADM_dataset_info_t; +/** A list of datasets */ +typedef struct adm_dataset_list* ADM_dataset_list_t; + /* ----------------------------------------------------- */ /* Storage tiers */ @@ -319,6 +322,29 @@ ADM_dataset_info_create(); ADM_return_t ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info); +/** + * Create a dataset list from an array of ADM_DATASETs and its + * length. + * + * @remark Dataset lists need to be freed by calling ADM_dataset_list_destroy(). + * + * @param[in] datasets The array of datasets. + * @param[in] len The length of the array. + * @return A valid ADM_dataset_list_t if successful or NULL in case of + * failure. + */ +ADM_dataset_list_t +ADM_dataset_list_create(ADM_dataset_t datasets[], size_t len); + +/** + * Destroy a dataset list created by ADM_dataset_list_create(). + * + * @param[in] list A valid ADM_dataset_list_t + * @return ADM_SUCCESS or corresponding ADM error code + */ +ADM_return_t +ADM_dataset_list_destroy(ADM_dataset_list_t list); + /* ----------------------------------------------------- */ /* Storage tiers */ diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 2d0be37a..ad792c63 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -103,18 +103,42 @@ ADM_dataset_t ADM_dataset_create(const char* id) { struct adm_dataset* adm_dataset = - (struct adm_dataset*) malloc(sizeof(struct adm_dataset)); + (struct adm_dataset*) calloc(1, sizeof(struct adm_dataset)); if(!adm_dataset) { LOGGER_ERROR("Could not allocate ADM_dataset_t") return NULL; } - adm_dataset->d_id = id; + if(id) { + size_t n = strlen(id); + adm_dataset->d_id = (const char*) calloc(n + 1, sizeof(char)); + strncpy((char*) adm_dataset->d_id, id, n); + } return adm_dataset; } +ADM_dataset_t +ADM_dataset_copy(ADM_dataset_t dst, const ADM_dataset_t src) { + + if(!src || !dst) { + return NULL; + } + + // copy all primitive types + *dst = *src; + + // duplicate copy any pointer types + if(src->d_id) { + size_t n = strlen(src->d_id); + dst->d_id = (const char*) calloc(n + 1, sizeof(char)); + strncpy((char*) dst->d_id, src->d_id, n); + } + + return dst; +} + ADM_return_t ADM_dataset_destroy(ADM_dataset_t dataset) { ADM_return_t ret = ADM_SUCCESS; @@ -124,6 +148,10 @@ ADM_dataset_destroy(ADM_dataset_t dataset) { return ADM_EBADARGS; } + if(dataset->d_id) { + free((void*) dataset->d_id); + } + free(dataset); return ret; } @@ -233,6 +261,74 @@ ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info) { return ret; } +ADM_dataset_list_t +ADM_dataset_list_create(ADM_dataset_t datasets[], size_t length) { + + ADM_dataset_list_t p = (ADM_dataset_list_t) malloc(sizeof(*p)); + + if(!p) { + LOGGER_ERROR("Could not allocate ADM_dataset_list_t") + return NULL; + } + + const char* error_msg = NULL; + + p->l_length = length; + p->l_datasets = (struct adm_dataset*) calloc(length, sizeof(adm_dataset)); + + if(!p->l_datasets) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + } + + for(size_t i = 0; i < length; ++i) { + if(!ADM_dataset_copy(&p->l_datasets[i], datasets[i])) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + }; + + fprintf(stderr, "o: %s -> %s\n", datasets[i]->d_id, + p->l_datasets[i].d_id); + } + + return p; + +cleanup_on_error: + if(p->l_datasets) { + free(p->l_datasets); + } + free(p); + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + return NULL; +} + +ADM_return_t +ADM_dataset_list_destroy(ADM_dataset_list_t list) { + ADM_return_t ret = ADM_SUCCESS; + + if(!list) { + LOGGER_ERROR("Invalid ADM_pfs_context_t") + return ADM_EBADARGS; + } + + // We cannot call ADM_dataset_destroy here because adm_datasets + // are stored as a consecutive array in memory. Thus, we free + // the dataset ids themselves and then the array. + if(list->l_datasets) { + for(size_t i = 0; i < list->l_length; ++i) { + free((void*) list->l_datasets[i].d_id); + } + free(list->l_datasets); + } + + free(list); + return ret; +} + ADM_storage_t ADM_storage_create(const char* id, ADM_storage_type_t type, void* ctx) { @@ -426,24 +522,62 @@ ADM_job_requirements_create(ADM_dataset_t inputs[], size_t inputs_len, return NULL; } - adm_job_reqs->r_inputs = inputs; - adm_job_reqs->r_num_inputs = inputs_len; - adm_job_reqs->r_outputs = outputs; - adm_job_reqs->r_num_outputs = outputs_len; - adm_job_reqs->r_adhoc_ctx = NULL; + ADM_dataset_list_t inputs_list = NULL; + ADM_dataset_list_t outputs_list = NULL; + const char* error_msg = NULL; - if(storage) { - if(storage->s_type != ADM_STORAGE_GEKKOFS && - storage->s_type != ADM_STORAGE_DATACLAY && - storage->s_type != ADM_STORAGE_EXPAND && - storage->s_type != ADM_STORAGE_HERCULES) { - LOGGER_ERROR("Invalid adhoc_storage") - return NULL; - } - adm_job_reqs->r_adhoc_ctx = storage->s_adhoc_ctx; + inputs_list = ADM_dataset_list_create(inputs, inputs_len); + + if(!inputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; } + outputs_list = ADM_dataset_list_create(outputs, outputs_len); + + if(!outputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; + } + + adm_job_reqs->r_inputs = inputs_list; + adm_job_reqs->r_outputs = outputs_list; + + if(!storage) { + adm_job_reqs->r_adhoc_ctx = NULL; + return adm_job_reqs; + } + + if(storage->s_type != ADM_STORAGE_GEKKOFS && + storage->s_type != ADM_STORAGE_DATACLAY && + storage->s_type != ADM_STORAGE_EXPAND && + storage->s_type != ADM_STORAGE_HERCULES) { + error_msg = "Invalid adhoc_storage argument"; + goto cleanup_on_error; + } + adm_job_reqs->r_adhoc_ctx = storage->s_adhoc_ctx; + return adm_job_reqs; + +cleanup_on_error: + + if(outputs_list) { + ADM_dataset_list_destroy(outputs_list); + } + + if(inputs_list) { + ADM_dataset_list_destroy(inputs_list); + } + + if(adm_job_reqs) { + ADM_job_requirements_destroy(adm_job_reqs); + } + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + return NULL; } ADM_return_t @@ -455,6 +589,14 @@ ADM_job_requirements_destroy(ADM_job_requirements_t reqs) { return ADM_EBADARGS; } + if(reqs->r_inputs) { + ADM_dataset_list_destroy(reqs->r_inputs); + } + + if(reqs->r_outputs) { + ADM_dataset_list_destroy(reqs->r_outputs); + } + free(reqs); return ret; } -- GitLab From d998f21d0402ed4ad4cf0694fba2c3fe52bdca83 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Wed, 13 Jul 2022 11:06:14 +0200 Subject: [PATCH 05/25] Redefine ADM_register_job_in_t --- src/common/network/proto/rpc_types.h | 2 +- src/lib/detail/impl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index c1b77f81..099dcf95 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -228,7 +228,7 @@ MERCURY_GEN_STRUCT_PROC( /// ADM_register_job -MERCURY_GEN_PROC(ADM_register_job_in_t, ((int32_t) (reqs))) +MERCURY_GEN_PROC(ADM_register_job_in_t, ((adm_job_requirements) (reqs))) MERCURY_GEN_PROC(ADM_register_job_out_t, ((int32_t) (ret))) diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index b6af16d3..816fe549 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -171,7 +171,7 @@ register_job(const admire::server& srv, ADM_job_requirements_t reqs) { LOGGER_INFO("ADM_register_job(...)"); - ADM_register_job_in_t in{}; + ADM_register_job_in_t in{*reqs}; ADM_register_job_out_t out; endp.call("ADM_register_job", &in, &out); -- GitLab From 363be4c12b378f10c3a4e67e97391a14a998173a Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 14 Jul 2022 17:52:18 +0200 Subject: [PATCH 06/25] Add encoding functions for ADM_adhoc_context_t --- src/common/network/proto/rpc_types.c | 74 +++++++++++++++++++++++++++- src/common/network/proto/rpc_types.h | 4 +- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/common/network/proto/rpc_types.c b/src/common/network/proto/rpc_types.c index dc10fad1..50f91b60 100644 --- a/src/common/network/proto/rpc_types.c +++ b/src/common/network/proto/rpc_types.c @@ -64,7 +64,8 @@ hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { } // loop and create list elements - tmp = (ADM_dataset_list_t) calloc(1, sizeof(struct adm_dataset_list)); + tmp = (ADM_dataset_list_t) calloc(1, + sizeof(struct adm_dataset_list)); tmp->l_length = length; tmp->l_datasets = (adm_dataset*) calloc(length, sizeof(adm_dataset)); @@ -93,3 +94,74 @@ hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { return ret; } + +hg_return_t +hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_adhoc_context_t* ctx = (ADM_adhoc_context_t*) data; + ADM_adhoc_context_t tmp = NULL; + hg_size_t ctx_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the context + ctx_length = *ctx ? sizeof(adm_adhoc_context) : 0; + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + return HG_SUCCESS; + } + + // if not NULL, write the context + tmp = *ctx; + ret = hg_proc_adm_adhoc_context(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + break; + + case HG_DECODE: { + + // find out the length of the context + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + *ctx = NULL; + break; + } + + // if not NULL, read the context + tmp = (ADM_adhoc_context_t) calloc( + 1, sizeof(struct adm_adhoc_context)); + ret = hg_proc_adm_adhoc_context(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + // return the newly-created ctx + *ctx = tmp; + break; + } + + case HG_FREE: + tmp = *ctx; + free(tmp); + ret = HG_SUCCESS; + break; + } + + return ret; +} diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index 099dcf95..824077ed 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -206,6 +206,8 @@ struct adm_dataset_list { hg_return_t hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data); +hg_return_t +hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data); /** The I/O requirements for a job */ typedef struct adm_job_requirements { @@ -222,7 +224,7 @@ MERCURY_GEN_STRUCT_PROC( adm_job_requirements, ((ADM_dataset_list_t) (r_inputs)) ((ADM_dataset_list_t) (r_outputs)) - ((adm_adhoc_context) (r_adhoc_ctx)) + ((ADM_adhoc_context_t) (r_adhoc_ctx)) ); // clang-format on -- GitLab From 38c0563e017fd3b1bf545d0de3e9ca055e420e1d Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 21 Jul 2022 09:19:26 +0200 Subject: [PATCH 07/25] Add encoding functions for ADM_storage_t --- src/common/network/proto/rpc_types.c | 118 +++++++++++++++++++++++++++ src/common/network/proto/rpc_types.h | 96 ++++++++++++---------- 2 files changed, 171 insertions(+), 43 deletions(-) diff --git a/src/common/network/proto/rpc_types.c b/src/common/network/proto/rpc_types.c index 50f91b60..6a158e26 100644 --- a/src/common/network/proto/rpc_types.c +++ b/src/common/network/proto/rpc_types.c @@ -95,6 +95,124 @@ hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { return ret; } + +hg_return_t +hg_proc_ADM_storage_t(hg_proc_t proc, void* data) { + (void) proc; + (void) data; + + hg_return_t ret = HG_SUCCESS; + ADM_storage_t* storage = (ADM_storage_t*) data; + ADM_storage_t tmp = NULL; + hg_size_t storage_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the adm_storage object we need to send + storage_length = *storage ? sizeof(adm_storage) : 0; + ret = hg_proc_hg_size_t(proc, &storage_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!storage_length) { + return HG_SUCCESS; + } + + // if we actually need to send an adm_storage object, + // write each of its fields to the mercury buffer + tmp = *storage; + + // 1. the storage type + ret = hg_proc_hg_uint32_t(proc, &tmp->s_type); + + if(ret != HG_SUCCESS) { + break; + } + + // 2. the storage id + ret = hg_proc_hg_const_string_t(proc, &tmp->s_id); + + if(ret != HG_SUCCESS) { + break; + } + + // 3. the appropriate storage context + switch(tmp->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + ret = hg_proc_ADM_adhoc_context_t(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_ADM_pfs_context_t(proc, &tmp->s_adhoc_ctx); + break; + } + + break; + + case HG_DECODE: + // find out the length of the adm_storage object + ret = hg_proc_hg_size_t(proc, &storage_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!storage_length) { + *storage = NULL; + break; + } + + // if the received adm_storage object was not NULL, read each of + // its fields from the mercury buffer + tmp = (adm_storage*) calloc(1, sizeof(adm_storage)); + + // 1. the storage type + ret = hg_proc_uint32_t(proc, &tmp->s_type); + + if(ret != HG_SUCCESS) { + break; + } + + // 2. the storage id + ret = hg_proc_hg_const_string_t(proc, &tmp->s_id); + + if(ret != HG_SUCCESS) { + break; + } + + // 3. the appropriate storage context + switch(tmp->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + ret = hg_proc_ADM_adhoc_context_t(proc, &tmp->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + ret = hg_proc_ADM_pfs_context_t(proc, &tmp->s_adhoc_ctx); + break; + } + + // return the newly-created ctx + *storage = tmp; + break; + + case HG_FREE: + tmp = *storage; + free(tmp); + break; + } + + return ret; +} + hg_return_t hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data) { diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index 824077ed..4741abc1 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -122,40 +122,6 @@ typedef struct adm_dataset_info { // clang-format off MERCURY_GEN_STRUCT_PROC( adm_dataset_info, - ((hg_int32_t) (placeholder)) -); -// clang-format on - -// TODO: union decoder -struct adm_storage { - const char* s_id; - ADM_storage_type_t s_type; - union { - ADM_adhoc_context_t s_adhoc_ctx; - ADM_pfs_context_t s_pfs_ctx; - }; -}; - -typedef struct adm_storage_resources { - // TODO: undefined for now - int32_t placeholder; -} adm_storage_resources; - -// clang-format off -MERCURY_GEN_STRUCT_PROC( - adm_storage_resources, - ((hg_int32_t) (placeholder)) -); -// clang-format on - -typedef struct adm_data_operation { - // TODO: undefined for now - int32_t placeholder; -} adm_data_operation; - -// clang-format off -MERCURY_GEN_STRUCT_PROC( - adm_data_operation, ((hg_int32_t) (placeholder)) ); // clang-format on @@ -175,12 +141,12 @@ typedef struct adm_adhoc_context { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_adhoc_context, + adm_adhoc_context, ((hg_int32_t) (c_mode)) - ((hg_int32_t) (c_access)) - ((hg_uint32_t) (c_nodes)) - ((hg_uint32_t) (c_walltime)) - ((hg_bool_t) (c_should_bg_flush)) + ((hg_int32_t) (c_access)) + ((hg_uint32_t) (c_nodes)) + ((hg_uint32_t) (c_walltime)) + ((hg_bool_t) (c_should_bg_flush)) ) // clang-format on @@ -196,6 +162,44 @@ MERCURY_GEN_STRUCT_PROC( ); // clang-format on +// TODO: union decoder +typedef struct adm_storage { + const char* s_id; + ADM_storage_type_t s_type; + union { + adm_adhoc_context s_adhoc_ctx; + adm_pfs_context s_pfs_ctx; + }; +} adm_storage; + +hg_return_t +hg_proc_ADM_storage_t(hg_proc_t proc, void* data); + +typedef struct adm_storage_resources { + // TODO: undefined for now + int32_t placeholder; +} adm_storage_resources; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_storage_resources, + ((hg_int32_t) (placeholder)) +); +// clang-format on + +typedef struct adm_data_operation { + // TODO: undefined for now + int32_t placeholder; +} adm_data_operation; + +// clang-format off +MERCURY_GEN_STRUCT_PROC( + adm_data_operation, + ((hg_int32_t) (placeholder)) +); +// clang-format on + + struct adm_dataset_list { /** An array of datasets */ adm_dataset* l_datasets; @@ -209,25 +213,30 @@ hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data); hg_return_t hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data); +hg_return_t +hg_proc_ADM_pfs_context_t(hg_proc_t proc, void* data); + + /** The I/O requirements for a job */ typedef struct adm_job_requirements { /** An array of input datasets */ ADM_dataset_list_t r_inputs; /** An array of output datasets */ ADM_dataset_list_t r_outputs; - /** An optional definition for a specific adhoc storage instance */ - adm_adhoc_context* r_adhoc_ctx; + /** An optional definition for a specific storage instance */ + ADM_storage_t r_storage; } adm_job_requirements; // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_job_requirements, + adm_job_requirements, // NOLINT ((ADM_dataset_list_t) (r_inputs)) ((ADM_dataset_list_t) (r_outputs)) - ((ADM_adhoc_context_t) (r_adhoc_ctx)) + ((ADM_storage_t) (r_storage)) ); // clang-format on +// clang-format off /// ADM_register_job MERCURY_GEN_PROC(ADM_register_job_in_t, ((adm_job_requirements) (reqs))) @@ -479,6 +488,7 @@ MERCURY_GEN_PROC(ADM_get_statistics_in_t, MERCURY_GEN_PROC(ADM_get_statistics_out_t, ((int32_t) (ret))((hg_const_string_t) (job_statistics))) +// clang-format on #ifdef __cplusplus }; // extern "C" -- GitLab From 5ecec4a9a2be156232023ac2f12dbcd28e8032b3 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Fri, 22 Jul 2022 08:45:57 +0200 Subject: [PATCH 08/25] Add encoding functions for ADM_job_t --- src/common/network/proto/rpc_types.c | 71 ++++++++++++++++++++++++++++ src/common/network/proto/rpc_types.h | 3 ++ 2 files changed, 74 insertions(+) diff --git a/src/common/network/proto/rpc_types.c b/src/common/network/proto/rpc_types.c index 6a158e26..9cc3a2e6 100644 --- a/src/common/network/proto/rpc_types.c +++ b/src/common/network/proto/rpc_types.c @@ -24,6 +24,77 @@ #include "rpc_types.h" +hg_return_t +hg_proc_ADM_job_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_job_t* job = (ADM_job_t*) data; + ADM_job_t tmp = NULL; + hg_size_t job_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the adm_storage object we need to send + job_length = *job ? sizeof(adm_job) : 0; + ret = hg_proc_hg_size_t(proc, &job_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!job_length) { + return HG_SUCCESS; + } + + // if we actually need to send an adm_job object, + // write it to the mercury buffer + tmp = *job; + + ret = hg_proc_adm_job(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + break; + + case HG_DECODE: + // find out the length of the adm_storage object + ret = hg_proc_hg_size_t(proc, &job_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!job_length) { + *job = NULL; + break; + } + + // if the received adm_job object was not NULL, read each of + // its fields from the mercury buffer + tmp = (adm_job*) calloc(1, sizeof(adm_job)); + + ret = hg_proc_adm_job(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + // return the newly-created ctx + *job = tmp; + break; + + case HG_FREE: + tmp = *job; + free(tmp); + break; + } + + return ret; +} + hg_return_t hg_proc_ADM_dataset_list_t(hg_proc_t proc, void* data) { hg_return_t ret = HG_SUCCESS; diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index 4741abc1..1d43fb7e 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -73,6 +73,9 @@ MERCURY_GEN_STRUCT_PROC( ); // clang-format on +hg_return_t +hg_proc_ADM_job_t(hg_proc_t proc, void* data); + struct adm_qos_entity { ADM_qos_scope_t e_scope; union { -- GitLab From 09810a13bfeab686012173356d197c424ec37a6f Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Fri, 22 Jul 2022 11:56:44 +0200 Subject: [PATCH 09/25] Add encoding functions for ADM_pfs_context_t --- src/common/network/proto/rpc_types.c | 70 ++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/common/network/proto/rpc_types.c b/src/common/network/proto/rpc_types.c index 9cc3a2e6..d23339e3 100644 --- a/src/common/network/proto/rpc_types.c +++ b/src/common/network/proto/rpc_types.c @@ -354,3 +354,73 @@ hg_proc_ADM_adhoc_context_t(hg_proc_t proc, void* data) { return ret; } + +hg_return_t +hg_proc_ADM_pfs_context_t(hg_proc_t proc, void* data) { + + hg_return_t ret = HG_SUCCESS; + ADM_pfs_context_t* ctx = (ADM_pfs_context_t*) data; + ADM_pfs_context_t tmp = NULL; + hg_size_t ctx_length = 0; + + switch(hg_proc_get_op(proc)) { + + case HG_ENCODE: + // find out the length of the context + ctx_length = *ctx ? sizeof(adm_pfs_context) : 0; + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + return HG_SUCCESS; + } + + // if not NULL, write the context + tmp = *ctx; + ret = hg_proc_adm_pfs_context(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + break; + + case HG_DECODE: { + + // find out the length of the context + ret = hg_proc_hg_size_t(proc, &ctx_length); + + if(ret != HG_SUCCESS) { + break; + } + + if(!ctx_length) { + *ctx = NULL; + break; + } + + // if not NULL, read the context + tmp = (ADM_pfs_context_t) calloc(1, sizeof(struct adm_pfs_context)); + ret = hg_proc_adm_pfs_context(proc, tmp); + + if(ret != HG_SUCCESS) { + break; + } + + // return the newly-created ctx + *ctx = tmp; + break; + } + + case HG_FREE: + tmp = *ctx; + free(tmp); + ret = HG_SUCCESS; + break; + } + + return ret; +} -- GitLab From 67f0575c1860facf8335dc9d0f1d24fca4bf67a7 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 12:59:13 +0200 Subject: [PATCH 10/25] Redefine ADM_register_job_out_t --- src/common/network/proto/rpc_types.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index 1d43fb7e..9df99dc3 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -244,7 +244,11 @@ MERCURY_GEN_STRUCT_PROC( /// ADM_register_job MERCURY_GEN_PROC(ADM_register_job_in_t, ((adm_job_requirements) (reqs))) -MERCURY_GEN_PROC(ADM_register_job_out_t, ((int32_t) (ret))) +MERCURY_GEN_PROC( + ADM_register_job_out_t, + ((int32_t) (retval)) + ((ADM_job_t) (job)) +); /// ADM_update_job MERCURY_GEN_PROC(ADM_update_job_in_t, ((int32_t) (reqs))) -- GitLab From 7ffd71ca473280eb5d31e547e7e763f093596d90 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 13:00:42 +0200 Subject: [PATCH 11/25] Redefine adm_storage --- src/common/network/proto/rpc_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index 9df99dc3..dd4ef22c 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -170,8 +170,8 @@ typedef struct adm_storage { const char* s_id; ADM_storage_type_t s_type; union { - adm_adhoc_context s_adhoc_ctx; - adm_pfs_context s_pfs_ctx; + ADM_adhoc_context_t s_adhoc_ctx; + ADM_pfs_context_t s_pfs_ctx; }; } adm_storage; -- GitLab From d99687f97138fd96fea4a24943f4f59d38655075 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Mon, 18 Jul 2022 09:44:51 +0200 Subject: [PATCH 12/25] Replace C types with C++ types in library core --- src/common/utils/CMakeLists.txt | 2 +- src/common/utils/c_ptr.hpp | 96 +++++++++++++++++++++++++++++++++ src/lib/admire.cpp | 60 ++++++++++++++++++++- src/lib/admire.hpp | 57 +++++++++++++++++++- src/lib/c_wrapper.cpp | 5 +- src/lib/detail/impl.cpp | 13 +++-- src/lib/detail/impl.hpp | 2 +- 7 files changed, 223 insertions(+), 12 deletions(-) create mode 100644 src/common/utils/c_ptr.hpp diff --git a/src/common/utils/CMakeLists.txt b/src/common/utils/CMakeLists.txt index 576d08a1..6f35c658 100644 --- a/src/common/utils/CMakeLists.txt +++ b/src/common/utils/CMakeLists.txt @@ -26,4 +26,4 @@ add_library(_utils STATIC) set_property(TARGET _utils PROPERTY POSITION_INDEPENDENT_CODE ON) -target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp) +target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp c_ptr.hpp) diff --git a/src/common/utils/c_ptr.hpp b/src/common/utils/c_ptr.hpp new file mode 100644 index 00000000..7a4a4f03 --- /dev/null +++ b/src/common/utils/c_ptr.hpp @@ -0,0 +1,96 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + + +#ifndef SCORD_UTILS_C_PTR_HPP +#define SCORD_UTILS_C_PTR_HPP + +#include +#include + +namespace scord::utils { + +// A manager for a C raw pointer. It allows to automatically delete dynamically +// allocated C structs in a RAII manner (provided that there is a deleter +// function for the struct available). +template +struct deleter { + void + operator()(T* ptr) { + fn(ptr); + } +}; + +template +using c_ptr = + std::unique_ptr::type, + deleter::type, fn>>; + +// A manager for a vector of C raw pointers. It allows to automatically +// delete the dynamically allocated C structs pointed by each vector elements +// in a RAII manner (provided that there is a deleter function for the struct +// available). Can also be used to directly pass an array of C pointers to C +// APIs by means of the data() function. +template +struct c_ptr_vector { + + c_ptr_vector() = default; + + ~c_ptr_vector() = default; + + constexpr void + reserve(size_t n) { + m_data.reserve(n); + m_addrs.reserve(n); + } + + template + constexpr void + emplace_back(Args&&... args) { + const auto& tmp = m_data.emplace_back(args...); + m_addrs.push_back(tmp.get()); + } + + constexpr const T* + data() const noexcept { + return m_addrs.data(); + } + + constexpr T* + data() noexcept { + return m_addrs.data(); + } + + constexpr std::size_t + size() const noexcept { + return m_data.size(); + } + + std::vector> m_data{}; + std::vector m_addrs{}; +}; + +} // namespace scord::utils + +#endif // SCORD_UTILS_C_PTR_HPP diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index f771f98b..86049700 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "detail/impl.hpp" @@ -171,6 +172,61 @@ rpc_registration_cb(scord::network::rpc_client* client) { namespace admire { +job_requirements::job_requirements(std::vector inputs, + std::vector outputs) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} + +job_requirements::job_requirements( + std::vector inputs, + std::vector outputs, + std::optional adhoc_context) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), + m_adhoc_context(adhoc_context) {} + +job_requirements::job_requirements(ADM_job_requirements_t reqs) { + + m_inputs.reserve(reqs->r_inputs->l_length); + + for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { + m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); + } + + m_outputs.reserve(reqs->r_outputs->l_length); + + for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { + m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); + } +} + + +ADM_job_requirements_t +job_requirements::to_rpc_type() const { + + using scord::utils::c_ptr; + using scord::utils::c_ptr_vector; + using dataset_vector = c_ptr_vector; + + dataset_vector inputs; + inputs.reserve(m_inputs.size()); + + for(const auto& in : m_inputs) { + inputs.emplace_back(ADM_dataset_create(in.m_id.c_str())); + } + + dataset_vector outputs; + outputs.reserve(m_outputs.size()); + + for(const auto& out : m_outputs) { + outputs.emplace_back(ADM_dataset_create(out.m_id.c_str())); + } + + if(m_adhoc_context) { + } + + return ADM_job_requirements_create(inputs.data(), inputs.size(), + outputs.data(), outputs.size(), nullptr); +} + void ping(const server& srv) { @@ -182,7 +238,7 @@ ping(const server& srv) { admire::job -register_job(const server& srv, ADM_job_requirements_t reqs) { +register_job(const server& srv, const job_requirements& reqs) { const auto rv = detail::register_job(srv, reqs); @@ -195,7 +251,7 @@ register_job(const server& srv, ADM_job_requirements_t reqs) { } ADM_return_t -update_job(const server& srv, ADM_job_t job, ADM_job_requirements_t reqs) { +update_job(const server& srv, ADM_job_t job, const job_requirements& reqs) { (void) srv; (void) job; (void) reqs; diff --git a/src/lib/admire.hpp b/src/lib/admire.hpp index 9f58a953..0030ca1b 100644 --- a/src/lib/admire.hpp +++ b/src/lib/admire.hpp @@ -24,8 +24,11 @@ #include #include +#include #include #include +#include +#include "network/proto/rpc_types.h" #ifndef SCORD_ADMIRE_HPP #define SCORD_ADMIRE_HPP @@ -43,14 +46,64 @@ struct job { job_id m_id; }; +struct dataset { + explicit dataset(std::string id) : m_id(std::move(id)) {} + std::string m_id; +}; + +namespace storage::adhoc { + +enum class execution_mode : std::underlying_type::type { + in_job_shared = ADM_ADHOC_MODE_IN_JOB_SHARED, + in_job_dedicated = ADM_ADHOC_MODE_IN_JOB_DEDICATED, + separate_new = ADM_ADHOC_MODE_SEPARATE_NEW, + separate_existing = ADM_ADHOC_MODE_SEPARATE_EXISTING +}; + +enum class access_mode : std::underlying_type::type { + read_only = ADM_ADHOC_ACCESS_RDONLY, + write_only = ADM_ADHOC_ACCESS_WRONLY, + read_write = ADM_ADHOC_ACCESS_RDWR, +}; + +struct context { + execution_mode m_exec_mode; + access_mode m_access_mode; + std::uint32_t m_nodes; + std::uint32_t m_walltime; + bool m_should_flush; +}; + +} // namespace storage::adhoc + +struct job_requirements { + + job_requirements(std::vector inputs, + std::vector outputs); + + job_requirements(std::vector inputs, + std::vector outputs, + std::optional adhoc_context); + + explicit job_requirements(ADM_job_requirements_t reqs); + + ADM_job_requirements_t + to_rpc_type() const; + + std::vector m_inputs; + std::vector m_outputs; + std::optional m_adhoc_context; +}; + + void ping(const server& srv); admire::job -register_job(const server& srv, ADM_job_requirements_t reqs); +register_job(const server& srv, const job_requirements& reqs); ADM_return_t -update_job(const server& srv, ADM_job_t job, ADM_job_requirements_t reqs); +update_job(const server& srv, ADM_job_t job, const job_requirements& reqs); ADM_return_t remove_job(const server& srv, ADM_job_t job); diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index ad792c63..1aa7fa58 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -641,7 +641,8 @@ ADM_register_job(ADM_server_t server, ADM_job_requirements_t reqs, const admire::server srv{server->s_protocol, server->s_address}; - const auto rv = admire::detail::register_job(srv, reqs); + const auto rv = + admire::detail::register_job(srv, admire::job_requirements{reqs}); if(!rv) { return rv.error(); @@ -664,7 +665,7 @@ ADM_update_job(ADM_server_t server, ADM_job_t job, const admire::server srv{server->s_protocol, server->s_address}; - return admire::update_job(srv, job, reqs); + return admire::update_job(srv, job, admire::job_requirements{reqs}); } ADM_return_t diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 816fe549..402bebd4 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "impl.hpp" void @@ -160,10 +161,14 @@ ping(const server& srv) { return ADM_SUCCESS; } + tl::expected -register_job(const admire::server& srv, ADM_job_requirements_t reqs) { - (void) srv; - (void) reqs; +register_job(const admire::server& srv, const admire::job_requirements& reqs) { + + using scord::utils::c_ptr; + using job_requirements_ptr = + c_ptr; + const auto preqs = job_requirements_ptr{reqs.to_rpc_type()}; scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; @@ -171,7 +176,7 @@ register_job(const admire::server& srv, ADM_job_requirements_t reqs) { LOGGER_INFO("ADM_register_job(...)"); - ADM_register_job_in_t in{*reqs}; + ADM_register_job_in_t in{*preqs}; ADM_register_job_out_t out; endp.call("ADM_register_job", &in, &out); diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index cacc056f..ee12fe9d 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -38,7 +38,7 @@ admire::error_code ping(const server& srv); tl::expected -register_job(const server& srv, ADM_job_requirements_t reqs); +register_job(const server& srv, const job_requirements& reqs); } // namespace admire::detail -- GitLab From 33f3578cdcea1c1b094ec63ed32213a3d4356f82 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 21 Jul 2022 09:21:49 +0200 Subject: [PATCH 13/25] Move admire types into dedicated 'admire_types' CMake target This makes it much simpler to share type definitions between the library and the daemons. - C++ types are now declared in admire_types.hpp - C & C++ types are defined in types.cpp. The reason for them being in the same file is that the C type-creation functions use logging facilities that are C++ code. Until we offer a C interface for them, C-type functions need to be compiled with a C++ compiler. --- src/lib/CMakeLists.txt | 17 +- src/lib/admire.cpp | 59 +-- src/lib/admire.hpp | 74 +-- src/lib/admire_types.hpp | 183 ++++++++ src/lib/c_wrapper.cpp | 655 ++------------------------ src/lib/detail/impl.hpp | 1 + src/lib/types.cpp | 868 +++++++++++++++++++++++++++++++++++ src/scord-ctl/CMakeLists.txt | 2 +- src/scord/CMakeLists.txt | 1 + 9 files changed, 1112 insertions(+), 748 deletions(-) create mode 100644 src/lib/admire_types.hpp create mode 100644 src/lib/types.cpp diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 76825c6b..a8030510 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -22,16 +22,27 @@ # SPDX-License-Identifier: GPL-3.0-or-later # ################################################################################ +add_library(admire_types STATIC) + +target_sources(admire_types PUBLIC admire_types.h admire_types.hpp PRIVATE + types.cpp) + +target_link_libraries(admire_types PRIVATE common::network::rpc_types + Margo::Margo common::logger) + +set_target_properties(admire_types PROPERTIES POSITION_INDEPENDENT_CODE ON) + # the client library implementing the actual API add_library(adm_iosched SHARED) target_sources(adm_iosched - PUBLIC admire.h admire_types.h admire.hpp - PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c) + PUBLIC admire.h admire_types.h admire.hpp admire_types.hpp + PRIVATE admire.cpp c_wrapper.cpp detail/impl.hpp detail/impl.cpp errors.c types.cpp) target_include_directories(adm_iosched PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(adm_iosched PRIVATE common::network::engine common::network::rpc_types PUBLIC +target_link_libraries(adm_iosched PRIVATE common::network::engine + common::network::rpc_types admire_types PUBLIC tl::expected) install( diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 86049700..ddb433cc 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -172,61 +172,6 @@ rpc_registration_cb(scord::network::rpc_client* client) { namespace admire { -job_requirements::job_requirements(std::vector inputs, - std::vector outputs) - : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} - -job_requirements::job_requirements( - std::vector inputs, - std::vector outputs, - std::optional adhoc_context) - : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), - m_adhoc_context(adhoc_context) {} - -job_requirements::job_requirements(ADM_job_requirements_t reqs) { - - m_inputs.reserve(reqs->r_inputs->l_length); - - for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { - m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); - } - - m_outputs.reserve(reqs->r_outputs->l_length); - - for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { - m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); - } -} - - -ADM_job_requirements_t -job_requirements::to_rpc_type() const { - - using scord::utils::c_ptr; - using scord::utils::c_ptr_vector; - using dataset_vector = c_ptr_vector; - - dataset_vector inputs; - inputs.reserve(m_inputs.size()); - - for(const auto& in : m_inputs) { - inputs.emplace_back(ADM_dataset_create(in.m_id.c_str())); - } - - dataset_vector outputs; - outputs.reserve(m_outputs.size()); - - for(const auto& out : m_outputs) { - outputs.emplace_back(ADM_dataset_create(out.m_id.c_str())); - } - - if(m_adhoc_context) { - } - - return ADM_job_requirements_create(inputs.data(), inputs.size(), - outputs.data(), outputs.size(), nullptr); -} - void ping(const server& srv) { @@ -251,7 +196,7 @@ register_job(const server& srv, const job_requirements& reqs) { } ADM_return_t -update_job(const server& srv, ADM_job_t job, const job_requirements& reqs) { +update_job(const server& srv, const job& job, const job_requirements& reqs) { (void) srv; (void) job; (void) reqs; @@ -277,7 +222,7 @@ update_job(const server& srv, ADM_job_t job, const job_requirements& reqs) { } ADM_return_t -remove_job(const server& srv, ADM_job_t job) { +remove_job(const server& srv, const job& job) { (void) srv; (void) job; diff --git a/src/lib/admire.hpp b/src/lib/admire.hpp index 0030ca1b..04dfb599 100644 --- a/src/lib/admire.hpp +++ b/src/lib/admire.hpp @@ -23,78 +23,26 @@ *****************************************************************************/ #include -#include -#include -#include #include #include +#include "admire_types.hpp" #include "network/proto/rpc_types.h" #ifndef SCORD_ADMIRE_HPP #define SCORD_ADMIRE_HPP -namespace admire { - -using job_id = int64_t; - -struct server { - std::string m_protocol; - std::string m_address; -}; - -struct job { - job_id m_id; -}; - -struct dataset { - explicit dataset(std::string id) : m_id(std::move(id)) {} - std::string m_id; -}; - -namespace storage::adhoc { - -enum class execution_mode : std::underlying_type::type { - in_job_shared = ADM_ADHOC_MODE_IN_JOB_SHARED, - in_job_dedicated = ADM_ADHOC_MODE_IN_JOB_DEDICATED, - separate_new = ADM_ADHOC_MODE_SEPARATE_NEW, - separate_existing = ADM_ADHOC_MODE_SEPARATE_EXISTING -}; +/******************************************************************************/ +/* Public type definitions and type-related functions */ +/******************************************************************************/ -enum class access_mode : std::underlying_type::type { - read_only = ADM_ADHOC_ACCESS_RDONLY, - write_only = ADM_ADHOC_ACCESS_WRONLY, - read_write = ADM_ADHOC_ACCESS_RDWR, -}; +// See admire_types.hpp -struct context { - execution_mode m_exec_mode; - access_mode m_access_mode; - std::uint32_t m_nodes; - std::uint32_t m_walltime; - bool m_should_flush; -}; -} // namespace storage::adhoc - -struct job_requirements { - - job_requirements(std::vector inputs, - std::vector outputs); - - job_requirements(std::vector inputs, - std::vector outputs, - std::optional adhoc_context); - - explicit job_requirements(ADM_job_requirements_t reqs); - - ADM_job_requirements_t - to_rpc_type() const; - - std::vector m_inputs; - std::vector m_outputs; - std::optional m_adhoc_context; -}; +/******************************************************************************/ +/* Public prototypes */ +/******************************************************************************/ +namespace admire { void ping(const server& srv); @@ -103,10 +51,10 @@ admire::job register_job(const server& srv, const job_requirements& reqs); ADM_return_t -update_job(const server& srv, ADM_job_t job, const job_requirements& reqs); +update_job(const server& srv, const job&, const job_requirements& reqs); ADM_return_t -remove_job(const server& srv, ADM_job_t job); +remove_job(const server& srv, const job& job); ADM_return_t register_adhoc_storage(const server& srv, ADM_job_t job, diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp new file mode 100644 index 00000000..b741e658 --- /dev/null +++ b/src/lib/admire_types.hpp @@ -0,0 +1,183 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#ifndef SCORD_ADMIRE_TYPES_HPP +#define SCORD_ADMIRE_TYPES_HPP + +#include +#include +#include +#include +#include +#include +#include "admire_types.h" + +namespace admire { + +using job_id = std::uint64_t; + +struct server { + + server(std::string protocol, std::string address); + + explicit server(const ADM_server_t& srv); + + std::string m_protocol; + std::string m_address; +}; + +struct job { + + explicit job(job_id id); + + explicit job(ADM_job_t job); + + job_id m_id; +}; + +struct dataset { + explicit dataset(std::string id) : m_id(std::move(id)) {} + + std::string + to_string() const { + return "foo"; + } + + std::string m_id; +}; + +struct storage { + + enum class type : std::underlying_type::type { + gekkofs = ADM_STORAGE_GEKKOFS, + dataclay = ADM_STORAGE_DATACLAY, + expand = ADM_STORAGE_EXPAND, + hercules = ADM_STORAGE_HERCULES, + lustre = ADM_STORAGE_LUSTRE, + gpfs = ADM_STORAGE_GPFS + }; + + storage(storage::type type, std::string id); + + virtual ~storage() = default; + + virtual ADM_storage_t + to_rpc_type() const = 0; + + std::string m_id; + type m_type; +}; + +struct adhoc_storage : public storage { + + enum class execution_mode : std::underlying_type::type { + in_job_shared = ADM_ADHOC_MODE_IN_JOB_SHARED, + in_job_dedicated = ADM_ADHOC_MODE_IN_JOB_DEDICATED, + separate_new = ADM_ADHOC_MODE_SEPARATE_NEW, + separate_existing = ADM_ADHOC_MODE_SEPARATE_EXISTING + }; + + enum class access_type : std::underlying_type::type { + read_only = ADM_ADHOC_ACCESS_RDONLY, + write_only = ADM_ADHOC_ACCESS_WRONLY, + read_write = ADM_ADHOC_ACCESS_RDWR, + }; + + struct context { + + context(execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, bool should_flush); + + explicit context(ADM_adhoc_context_t ctx); + + ADM_adhoc_context_t + to_rpc_type() const; + + execution_mode m_exec_mode; + access_type m_access_type; + std::uint32_t m_nodes; + std::uint32_t m_walltime; + bool m_should_flush; + }; + + adhoc_storage(storage::type type, std::string id, execution_mode exec_mode, + access_type access_type, std::uint32_t nodes, + std::uint32_t walltime, bool should_flush); + + adhoc_storage(storage::type type, std::string id, ADM_adhoc_context_t ctx); + + + ADM_storage_t + to_rpc_type() const final; + + context m_ctx; +}; + +struct pfs_storage : public storage { + + struct context { + + explicit context(std::filesystem::path mount_point); + + explicit context(ADM_pfs_context_t ctx); + + ADM_pfs_context_t + to_rpc_type() const; + + std::filesystem::path m_mount_point; + }; + + pfs_storage(storage::type type, std::string id, + std::filesystem::path mount_point); + + pfs_storage(storage::type type, std::string id, ADM_pfs_context_t ctx); + + ADM_storage_t + to_rpc_type() const final; + + context m_ctx; +}; + +struct job_requirements { + + job_requirements(std::vector inputs, + std::vector outputs); + + job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage); + + explicit job_requirements(ADM_job_requirements_t reqs); + + ADM_job_requirements_t + to_rpc_type() const; + + std::vector m_inputs; + std::vector m_outputs; + std::unique_ptr m_storage; +}; + +} // namespace admire + +#endif // SCORD_ADMIRE_TYPES_HPP diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 1aa7fa58..e0cf7fc5 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -26,612 +26,18 @@ #include #include #include +#include +#include "admire_types.hpp" +#include "admire_types.h" #include "detail/impl.hpp" -/******************************************************************************/ -/* Type definitions and related functions */ -/******************************************************************************/ - -struct adm_server { - const char* s_protocol; - const char* s_address; -}; - -ADM_server_t -ADM_server_create(const char* protocol, const char* address) { - - struct adm_server* adm_server = - (struct adm_server*) malloc(sizeof(struct adm_server)); - - if(!adm_server) { - LOGGER_ERROR("Could not allocate ADM_server_t") - return NULL; - } - - adm_server->s_protocol = protocol; - adm_server->s_address = address; - - return adm_server; -} - -ADM_return_t -ADM_server_destroy(ADM_server_t server) { - ADM_return_t ret = ADM_SUCCESS; - - if(!server) { - LOGGER_ERROR("Invalid ADM_server_t") - return ADM_EBADARGS; - } - - free(server); - return ret; -} - - -ADM_node_t -ADM_node_create(const char* hostname) { - - struct adm_node* adm_node = - (struct adm_node*) malloc(sizeof(struct adm_node)); - - if(!adm_node) { - LOGGER_ERROR("Could not allocate ADM_node_t") - return NULL; - } - - adm_node->n_hostname = hostname; - - return adm_node; -} - -ADM_return_t -ADM_node_destroy(ADM_node_t node) { - ADM_return_t ret = ADM_SUCCESS; - - if(!node) { - LOGGER_ERROR("Invalid ADM_node_t") - return ADM_EBADARGS; - } - - free(node); - return ret; -} - - -ADM_dataset_t -ADM_dataset_create(const char* id) { - - struct adm_dataset* adm_dataset = - (struct adm_dataset*) calloc(1, sizeof(struct adm_dataset)); - - if(!adm_dataset) { - LOGGER_ERROR("Could not allocate ADM_dataset_t") - return NULL; - } - - if(id) { - size_t n = strlen(id); - adm_dataset->d_id = (const char*) calloc(n + 1, sizeof(char)); - strncpy((char*) adm_dataset->d_id, id, n); - } - - return adm_dataset; -} - -ADM_dataset_t -ADM_dataset_copy(ADM_dataset_t dst, const ADM_dataset_t src) { - - if(!src || !dst) { - return NULL; - } - - // copy all primitive types - *dst = *src; - - // duplicate copy any pointer types - if(src->d_id) { - size_t n = strlen(src->d_id); - dst->d_id = (const char*) calloc(n + 1, sizeof(char)); - strncpy((char*) dst->d_id, src->d_id, n); - } - - return dst; -} - -ADM_return_t -ADM_dataset_destroy(ADM_dataset_t dataset) { - ADM_return_t ret = ADM_SUCCESS; - - if(!dataset) { - LOGGER_ERROR("Invalid ADM_dataset_t") - return ADM_EBADARGS; - } - - if(dataset->d_id) { - free((void*) dataset->d_id); - } - - free(dataset); - return ret; -} - -ADM_qos_entity_t -ADM_qos_entity_create(ADM_qos_scope_t scope, ...) { - - struct adm_qos_entity* adm_qos_entity = - (struct adm_qos_entity*) malloc(sizeof(struct adm_qos_entity)); - - if(!adm_qos_entity) { - LOGGER_ERROR("Could not allocate ADM_qos_entity_t") - return NULL; - } - - adm_qos_entity->e_scope = scope; - - va_list ap; - va_start(ap, scope); - - switch(scope) { - case ADM_QOS_SCOPE_NODE: - adm_qos_entity->e_node = va_arg(ap, ADM_node_t); - break; - case ADM_QOS_SCOPE_JOB: - adm_qos_entity->e_job = va_arg(ap, ADM_job_t); - break; - case ADM_QOS_SCOPE_DATASET: - adm_qos_entity->e_dataset = va_arg(ap, ADM_dataset_t); - break; - } - va_end(ap); - - return adm_qos_entity; -} - -ADM_return_t -ADM_qos_entity_destroy(ADM_qos_entity_t entity) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!entity) { - LOGGER_ERROR("Invalid ADM_qos_entity_t") - return ADM_EBADARGS; - } - - free(entity); - return ret; -} - -ADM_qos_limit_t -ADM_qos_limit_create(ADM_qos_entity_t entity, ADM_qos_class_t cls, - uint64_t value) { - - struct adm_qos_limit* adm_qos_limit = - (struct adm_qos_limit*) malloc(sizeof(struct adm_qos_limit)); - - if(!adm_qos_limit) { - LOGGER_ERROR("Could not allocate ADM_qos_limit_t") - return NULL; - } - - adm_qos_limit->l_entity = entity; - adm_qos_limit->l_class = cls; - adm_qos_limit->l_value = value; - - return adm_qos_limit; -} - -ADM_return_t -ADM_qos_limit_destroy(ADM_qos_limit_t limit) { - ADM_return_t ret = ADM_SUCCESS; - - if(!limit) { - LOGGER_ERROR("Invalid ADM_qos_limit_t") - return ADM_EBADARGS; - } - - free(limit); - return ret; -} - -ADM_dataset_info_t -ADM_dataset_info_create() { - - struct adm_dataset_info* adm_dataset_info = - (struct adm_dataset_info*) malloc(sizeof(*adm_dataset_info)); - - if(!adm_dataset_info) { - LOGGER_ERROR("Could not allocate ADM_dataset_info_t"); - return NULL; - } - - return adm_dataset_info; -} - -ADM_return_t -ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info) { - ADM_return_t ret = ADM_SUCCESS; - - if(!dataset_info) { - LOGGER_ERROR("Invalid ADM_dataset_info_t") - return ADM_EBADARGS; - } - - free(dataset_info); - return ret; -} - -ADM_dataset_list_t -ADM_dataset_list_create(ADM_dataset_t datasets[], size_t length) { - - ADM_dataset_list_t p = (ADM_dataset_list_t) malloc(sizeof(*p)); - - if(!p) { - LOGGER_ERROR("Could not allocate ADM_dataset_list_t") - return NULL; - } - - const char* error_msg = NULL; - - p->l_length = length; - p->l_datasets = (struct adm_dataset*) calloc(length, sizeof(adm_dataset)); - - if(!p->l_datasets) { - error_msg = "Could not allocate ADM_dataset_list_t"; - goto cleanup_on_error; - } - - for(size_t i = 0; i < length; ++i) { - if(!ADM_dataset_copy(&p->l_datasets[i], datasets[i])) { - error_msg = "Could not allocate ADM_dataset_list_t"; - goto cleanup_on_error; - }; - - fprintf(stderr, "o: %s -> %s\n", datasets[i]->d_id, - p->l_datasets[i].d_id); - } - - return p; - -cleanup_on_error: - if(p->l_datasets) { - free(p->l_datasets); - } - free(p); - - if(error_msg) { - LOGGER_ERROR(error_msg); - } - - return NULL; -} - -ADM_return_t -ADM_dataset_list_destroy(ADM_dataset_list_t list) { - ADM_return_t ret = ADM_SUCCESS; - - if(!list) { - LOGGER_ERROR("Invalid ADM_pfs_context_t") - return ADM_EBADARGS; - } - - // We cannot call ADM_dataset_destroy here because adm_datasets - // are stored as a consecutive array in memory. Thus, we free - // the dataset ids themselves and then the array. - if(list->l_datasets) { - for(size_t i = 0; i < list->l_length; ++i) { - free((void*) list->l_datasets[i].d_id); - } - free(list->l_datasets); - } - - free(list); - return ret; -} - -ADM_storage_t -ADM_storage_create(const char* id, ADM_storage_type_t type, void* ctx) { - - struct adm_storage* adm_storage = - (struct adm_storage*) malloc(sizeof(*adm_storage)); - - if(!adm_storage) { - LOGGER_ERROR("Could not allocate ADM_storage_t"); - return NULL; - } - - if(!id) { - LOGGER_ERROR("Null storage id") - return NULL; - } - - if(!ctx) { - LOGGER_ERROR("Null storage context") - return NULL; - } - - adm_storage->s_id = id; - adm_storage->s_type = type; - - switch(adm_storage->s_type) { - case ADM_STORAGE_GEKKOFS: - case ADM_STORAGE_DATACLAY: - case ADM_STORAGE_EXPAND: - case ADM_STORAGE_HERCULES: - adm_storage->s_adhoc_ctx = *((ADM_adhoc_context_t*) ctx); - break; - - case ADM_STORAGE_LUSTRE: - case ADM_STORAGE_GPFS: - adm_storage->s_pfs_ctx = *((ADM_pfs_context_t*) ctx); - break; - } - - return adm_storage; -} - -ADM_return_t -ADM_storage_destroy(ADM_storage_t storage) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!storage) { - LOGGER_ERROR("Invalid ADM_storage_t") - return ADM_EBADARGS; - } - - free(storage); - return ret; -} - -ADM_storage_resources_t -ADM_storage_resources_create() { - - struct adm_storage_resources* adm_storage_resources = - (struct adm_storage_resources*) malloc( - sizeof(*adm_storage_resources)); - - if(!adm_storage_resources) { - LOGGER_ERROR("Could not allocate ADM_storage_resources_t"); - return NULL; - } - - return adm_storage_resources; -} - -ADM_return_t -ADM_storage_resources_destroy(ADM_storage_resources_t res) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!res) { - LOGGER_ERROR("Invalid ADM_storage_resources_t") - return ADM_EBADARGS; - } - - free(res); - return ret; -} - -ADM_data_operation_t -ADM_data_operation_create() { - - struct adm_data_operation* adm_data_operation = - (struct adm_data_operation*) malloc(sizeof(*adm_data_operation)); - - if(!adm_data_operation) { - LOGGER_ERROR("Could not allocate ADM_data_operation_t"); - return NULL; - } - - return adm_data_operation; -} - -ADM_return_t -ADM_data_operation_destroy(ADM_data_operation_t op) { - - ADM_return_t ret = ADM_SUCCESS; - - if(!op) { - LOGGER_ERROR("Invalid ADM_data_operation_t") - return ADM_EBADARGS; - } - - free(op); - return ret; -} - - -ADM_adhoc_context_t -ADM_adhoc_context_create(ADM_adhoc_mode_t exec_mode, - ADM_adhoc_access_t access_type, uint32_t nodes, - uint32_t walltime, bool should_flush) { - - struct adm_adhoc_context* adm_adhoc_context = - (struct adm_adhoc_context*) malloc(sizeof(*adm_adhoc_context)); - - if(!adm_adhoc_context) { - LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); - return NULL; - } - - adm_adhoc_context->c_mode = exec_mode; - adm_adhoc_context->c_access = access_type; - adm_adhoc_context->c_nodes = nodes; - adm_adhoc_context->c_walltime = walltime; - adm_adhoc_context->c_should_bg_flush = should_flush; - - return adm_adhoc_context; -} - -ADM_return_t -ADM_adhoc_context_destroy(ADM_adhoc_context_t ctx) { - - - ADM_return_t ret = ADM_SUCCESS; - - if(!ctx) { - LOGGER_ERROR("Invalid ADM_adhoc_context_t") - return ADM_EBADARGS; - } - - free(ctx); - return ret; -} - -ADM_pfs_context_t -ADM_pfs_context_create(const char* mountpoint) { - - struct adm_pfs_context* adm_pfs_context = - (struct adm_pfs_context*) malloc(sizeof(*adm_pfs_context)); - - if(!adm_pfs_context) { - LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); - return NULL; - } - - adm_pfs_context->c_mount = mountpoint; - - return adm_pfs_context; -} - -ADM_return_t -ADM_pfs_context_destroy(ADM_pfs_context_t ctx) { - ADM_return_t ret = ADM_SUCCESS; - - if(!ctx) { - LOGGER_ERROR("Invalid ADM_pfs_context_t") - return ADM_EBADARGS; - } - - free(ctx); - return ret; -} - -ADM_job_requirements_t -ADM_job_requirements_create(ADM_dataset_t inputs[], size_t inputs_len, - ADM_dataset_t outputs[], size_t outputs_len, - ADM_storage_t storage) { - - struct adm_job_requirements* adm_job_reqs = - (struct adm_job_requirements*) malloc( - sizeof(struct adm_job_requirements)); - - if(!adm_job_reqs) { - LOGGER_ERROR("Could not allocate ADM_job_requirements_t") - return NULL; - } - - ADM_dataset_list_t inputs_list = NULL; - ADM_dataset_list_t outputs_list = NULL; - const char* error_msg = NULL; - - inputs_list = ADM_dataset_list_create(inputs, inputs_len); - - if(!inputs_list) { - error_msg = "Could not allocate ADM_job_requirements_t"; - goto cleanup_on_error; - } - - outputs_list = ADM_dataset_list_create(outputs, outputs_len); - - if(!outputs_list) { - error_msg = "Could not allocate ADM_job_requirements_t"; - goto cleanup_on_error; - } - - adm_job_reqs->r_inputs = inputs_list; - adm_job_reqs->r_outputs = outputs_list; - - if(!storage) { - adm_job_reqs->r_adhoc_ctx = NULL; - return adm_job_reqs; - } - - if(storage->s_type != ADM_STORAGE_GEKKOFS && - storage->s_type != ADM_STORAGE_DATACLAY && - storage->s_type != ADM_STORAGE_EXPAND && - storage->s_type != ADM_STORAGE_HERCULES) { - error_msg = "Invalid adhoc_storage argument"; - goto cleanup_on_error; - } - adm_job_reqs->r_adhoc_ctx = storage->s_adhoc_ctx; - - return adm_job_reqs; - -cleanup_on_error: - - if(outputs_list) { - ADM_dataset_list_destroy(outputs_list); - } - - if(inputs_list) { - ADM_dataset_list_destroy(inputs_list); - } - - if(adm_job_reqs) { - ADM_job_requirements_destroy(adm_job_reqs); - } - - if(error_msg) { - LOGGER_ERROR(error_msg); - } - - return NULL; -} - -ADM_return_t -ADM_job_requirements_destroy(ADM_job_requirements_t reqs) { - ADM_return_t ret = ADM_SUCCESS; - - if(!reqs) { - LOGGER_ERROR("Invalid ADM_job_requirements_t") - return ADM_EBADARGS; - } - - if(reqs->r_inputs) { - ADM_dataset_list_destroy(reqs->r_inputs); - } - - if(reqs->r_outputs) { - ADM_dataset_list_destroy(reqs->r_outputs); - } - - free(reqs); - return ret; -} - -/** - * Initialize a job handle that can be used by clients to refer to a job. - * - * @remark This function is not actually part of the public API, but it is - * useful to have for internal purposes - * - * @param [in] id The identifier for this job - * @return A valid JOB HANDLE or NULL in case of failure. - */ -static ADM_job_t -ADM_job_create(uint64_t id) { - - struct adm_job* adm_job = (struct adm_job*) malloc(sizeof(struct adm_job)); - - if(!adm_job) { - LOGGER_ERROR("Could not allocate ADM_job_t") - return NULL; - } - - adm_job->j_id = id; - - return adm_job; -} - - /******************************************************************************/ /* C API implementation */ /******************************************************************************/ ADM_return_t ADM_ping(ADM_server_t server) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::detail::ping(srv); } @@ -639,7 +45,7 @@ ADM_return_t ADM_register_job(ADM_server_t server, ADM_job_requirements_t reqs, ADM_job_t* job) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; const auto rv = admire::detail::register_job(srv, admire::job_requirements{reqs}); @@ -663,17 +69,18 @@ ADM_return_t ADM_update_job(ADM_server_t server, ADM_job_t job, ADM_job_requirements_t reqs) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; - return admire::update_job(srv, job, admire::job_requirements{reqs}); + return admire::update_job(srv, admire::job{job}, + admire::job_requirements{reqs}); } ADM_return_t ADM_remove_job(ADM_server_t server, ADM_job_t job) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; - return admire::remove_job(srv, job); + return admire::remove_job(srv, admire::job{job}); } ADM_return_t @@ -681,7 +88,7 @@ ADM_register_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_adhoc_context_t ctx, ADM_storage_t* adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::register_adhoc_storage(srv, job, ctx, adhoc_storage); } @@ -690,7 +97,7 @@ ADM_return_t ADM_update_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_adhoc_context_t ctx, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::update_adhoc_storage(srv, job, ctx, adhoc_storage); } @@ -699,7 +106,7 @@ ADM_return_t ADM_remove_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::remove_adhoc_storage(srv, job, adhoc_storage); } @@ -708,7 +115,7 @@ ADM_return_t ADM_deploy_adhoc_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t adhoc_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::deploy_adhoc_storage(srv, job, adhoc_storage); } @@ -717,7 +124,7 @@ ADM_return_t ADM_register_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_pfs_context_t ctx, ADM_storage_t* pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::register_pfs_storage(srv, job, ctx, pfs_storage); } @@ -726,7 +133,7 @@ ADM_return_t ADM_update_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_pfs_context_t ctx, ADM_storage_t pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::update_pfs_storage(srv, job, ctx, pfs_storage); } @@ -735,7 +142,7 @@ ADM_return_t ADM_remove_pfs_storage(ADM_server_t server, ADM_job_t job, ADM_storage_t pfs_storage) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::remove_pfs_storage(srv, job, pfs_storage); } @@ -746,7 +153,7 @@ ADM_transfer_dataset(ADM_server_t server, ADM_job_t job, ADM_qos_limit_t** limits, ADM_transfer_mapping_t mapping, ADM_transfer_t* transfer) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::transfer_dataset(srv, job, sources, targets, limits, mapping, transfer); @@ -756,7 +163,7 @@ ADM_return_t ADM_set_dataset_information(ADM_server_t server, ADM_job_t job, ADM_dataset_t target, ADM_dataset_info_t info) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_dataset_information(srv, job, target, info); } @@ -765,7 +172,7 @@ ADM_return_t ADM_set_io_resources(ADM_server_t server, ADM_job_t job, ADM_storage_t tier, ADM_storage_resources_t resources) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_io_resources(srv, job, tier, resources); } @@ -775,7 +182,7 @@ ADM_get_transfer_priority(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer, ADM_transfer_priority_t* priority) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_transfer_priority(srv, job, transfer, priority); } @@ -784,7 +191,7 @@ ADM_return_t ADM_set_transfer_priority(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer, int incr) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_transfer_priority(srv, job, transfer, incr); } @@ -793,7 +200,7 @@ ADM_return_t ADM_cancel_transfer(ADM_server_t server, ADM_job_t job, ADM_transfer_t transfer) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::cancel_transfer(srv, job, transfer); } @@ -802,7 +209,7 @@ ADM_return_t ADM_get_pending_transfers(ADM_server_t server, ADM_job_t job, ADM_transfer_t** pending_transfers) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_pending_transfers(srv, job, pending_transfers); } @@ -811,7 +218,7 @@ ADM_return_t ADM_set_qos_constraints(ADM_server_t server, ADM_job_t job, ADM_qos_entity_t entity, ADM_qos_limit_t limit) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::set_qos_constraints(srv, job, entity, limit); } @@ -820,7 +227,7 @@ ADM_return_t ADM_get_qos_constraints(ADM_server_t server, ADM_job_t job, ADM_qos_entity_t entity, ADM_qos_limit_t** limits) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_qos_constraints(srv, job, entity, limits); } @@ -829,7 +236,7 @@ ADM_return_t ADM_define_data_operation(ADM_server_t server, ADM_job_t job, const char* path, ADM_data_operation_t* op, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, op); @@ -844,7 +251,7 @@ ADM_connect_data_operation(ADM_server_t server, ADM_job_t job, ADM_dataset_t input, ADM_dataset_t output, bool should_stream, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, should_stream); @@ -860,7 +267,7 @@ ADM_finalize_data_operation(ADM_server_t server, ADM_job_t job, ADM_data_operation_t op, ADM_data_operation_status_t* status) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::finalize_data_operation(srv, job, op, status); } @@ -870,7 +277,7 @@ ADM_link_transfer_to_data_operation(ADM_server_t server, ADM_job_t job, ADM_data_operation_t op, bool should_stream, ...) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; va_list args; va_start(args, should_stream); @@ -884,6 +291,6 @@ ADM_link_transfer_to_data_operation(ADM_server_t server, ADM_job_t job, ADM_return_t ADM_get_statistics(ADM_server_t server, ADM_job_t job, ADM_job_stats_t** stats) { - const admire::server srv{server->s_protocol, server->s_address}; + const admire::server srv{server}; return admire::get_statistics(srv, job, stats); } diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index ee12fe9d..327f1661 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -27,6 +27,7 @@ #define SCORD_ADMIRE_IMPL_HPP #include +#include namespace admire { using error_code = ADM_return_t; diff --git a/src/lib/types.cpp b/src/lib/types.cpp new file mode 100644 index 00000000..2e8ed350 --- /dev/null +++ b/src/lib/types.cpp @@ -0,0 +1,868 @@ +/****************************************************************************** + * Copyright 2021-2022, Barcelona Supercomputing Center (BSC), Spain + * + * This software was partially supported by the EuroHPC-funded project ADMIRE + * (Project ID: 956748, https://www.admire-eurohpc.eu). + * + * This file is part of scord. + * + * scord is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * scord is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with scord. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include "admire_types.hpp" + +/******************************************************************************/ +/* C Type definitions and related functions */ +/******************************************************************************/ + +struct adm_server { + const char* s_protocol; + const char* s_address; +}; + +ADM_server_t +ADM_server_create(const char* protocol, const char* address) { + + struct adm_server* adm_server = + (struct adm_server*) malloc(sizeof(struct adm_server)); + + if(!adm_server) { + LOGGER_ERROR("Could not allocate ADM_server_t") + return NULL; + } + + adm_server->s_protocol = protocol; + adm_server->s_address = address; + + return adm_server; +} + +ADM_return_t +ADM_server_destroy(ADM_server_t server) { + ADM_return_t ret = ADM_SUCCESS; + + if(!server) { + LOGGER_ERROR("Invalid ADM_server_t") + return ADM_EBADARGS; + } + + free(server); + return ret; +} + + +ADM_node_t +ADM_node_create(const char* hostname) { + + struct adm_node* adm_node = + (struct adm_node*) malloc(sizeof(struct adm_node)); + + if(!adm_node) { + LOGGER_ERROR("Could not allocate ADM_node_t") + return NULL; + } + + adm_node->n_hostname = hostname; + + return adm_node; +} + +ADM_return_t +ADM_node_destroy(ADM_node_t node) { + ADM_return_t ret = ADM_SUCCESS; + + if(!node) { + LOGGER_ERROR("Invalid ADM_node_t") + return ADM_EBADARGS; + } + + free(node); + return ret; +} + + +ADM_dataset_t +ADM_dataset_create(const char* id) { + + struct adm_dataset* adm_dataset = + (struct adm_dataset*) calloc(1, sizeof(struct adm_dataset)); + + if(!adm_dataset) { + LOGGER_ERROR("Could not allocate ADM_dataset_t") + return NULL; + } + + if(id) { + size_t n = strlen(id); + adm_dataset->d_id = (const char*) calloc(n + 1, sizeof(char)); + strcpy((char*) adm_dataset->d_id, id); + } + + return adm_dataset; +} + +ADM_dataset_t +ADM_dataset_copy(ADM_dataset_t dst, const ADM_dataset_t src) { + + if(!src || !dst) { + return NULL; + } + + // copy all primitive types + *dst = *src; + + // duplicate copy any pointer types + if(src->d_id) { + size_t n = strlen(src->d_id); + dst->d_id = (const char*) calloc(n + 1, sizeof(char)); + strncpy((char*) dst->d_id, src->d_id, n); + } + + return dst; +} + +ADM_return_t +ADM_dataset_destroy(ADM_dataset_t dataset) { + ADM_return_t ret = ADM_SUCCESS; + + if(!dataset) { + LOGGER_ERROR("Invalid ADM_dataset_t") + return ADM_EBADARGS; + } + + if(dataset->d_id) { + free((void*) dataset->d_id); + } + + free(dataset); + return ret; +} + +ADM_qos_entity_t +ADM_qos_entity_create(ADM_qos_scope_t scope, ...) { + + struct adm_qos_entity* adm_qos_entity = + (struct adm_qos_entity*) malloc(sizeof(struct adm_qos_entity)); + + if(!adm_qos_entity) { + LOGGER_ERROR("Could not allocate ADM_qos_entity_t") + return NULL; + } + + adm_qos_entity->e_scope = scope; + + va_list ap; + va_start(ap, scope); + + switch(scope) { + case ADM_QOS_SCOPE_NODE: + adm_qos_entity->e_node = va_arg(ap, ADM_node_t); + break; + case ADM_QOS_SCOPE_JOB: + adm_qos_entity->e_job = va_arg(ap, ADM_job_t); + break; + case ADM_QOS_SCOPE_DATASET: + adm_qos_entity->e_dataset = va_arg(ap, ADM_dataset_t); + break; + } + va_end(ap); + + return adm_qos_entity; +} + +ADM_return_t +ADM_qos_entity_destroy(ADM_qos_entity_t entity) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!entity) { + LOGGER_ERROR("Invalid ADM_qos_entity_t") + return ADM_EBADARGS; + } + + free(entity); + return ret; +} + +ADM_qos_limit_t +ADM_qos_limit_create(ADM_qos_entity_t entity, ADM_qos_class_t cls, + uint64_t value) { + + struct adm_qos_limit* adm_qos_limit = + (struct adm_qos_limit*) malloc(sizeof(struct adm_qos_limit)); + + if(!adm_qos_limit) { + LOGGER_ERROR("Could not allocate ADM_qos_limit_t") + return NULL; + } + + adm_qos_limit->l_entity = entity; + adm_qos_limit->l_class = cls; + adm_qos_limit->l_value = value; + + return adm_qos_limit; +} + +ADM_return_t +ADM_qos_limit_destroy(ADM_qos_limit_t limit) { + ADM_return_t ret = ADM_SUCCESS; + + if(!limit) { + LOGGER_ERROR("Invalid ADM_qos_limit_t") + return ADM_EBADARGS; + } + + free(limit); + return ret; +} + +ADM_dataset_info_t +ADM_dataset_info_create() { + + struct adm_dataset_info* adm_dataset_info = + (struct adm_dataset_info*) malloc(sizeof(*adm_dataset_info)); + + if(!adm_dataset_info) { + LOGGER_ERROR("Could not allocate ADM_dataset_info_t"); + return NULL; + } + + return adm_dataset_info; +} + +ADM_return_t +ADM_dataset_info_destroy(ADM_dataset_info_t dataset_info) { + ADM_return_t ret = ADM_SUCCESS; + + if(!dataset_info) { + LOGGER_ERROR("Invalid ADM_dataset_info_t") + return ADM_EBADARGS; + } + + free(dataset_info); + return ret; +} + +ADM_dataset_list_t +ADM_dataset_list_create(ADM_dataset_t datasets[], size_t length) { + + ADM_dataset_list_t p = (ADM_dataset_list_t) malloc(sizeof(*p)); + + if(!p) { + LOGGER_ERROR("Could not allocate ADM_dataset_list_t") + return NULL; + } + + const char* error_msg = NULL; + + p->l_length = length; + p->l_datasets = (struct adm_dataset*) calloc(length, sizeof(adm_dataset)); + + if(!p->l_datasets) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + } + + for(size_t i = 0; i < length; ++i) { + if(!ADM_dataset_copy(&p->l_datasets[i], datasets[i])) { + error_msg = "Could not allocate ADM_dataset_list_t"; + goto cleanup_on_error; + }; + } + + return p; + +cleanup_on_error: + if(p->l_datasets) { + free(p->l_datasets); + } + free(p); + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + return NULL; +} + +ADM_return_t +ADM_dataset_list_destroy(ADM_dataset_list_t list) { + ADM_return_t ret = ADM_SUCCESS; + + if(!list) { + LOGGER_ERROR("Invalid ADM_pfs_context_t") + return ADM_EBADARGS; + } + + // We cannot call ADM_dataset_destroy here because adm_datasets + // are stored as a consecutive array in memory. Thus, we free + // the dataset ids themselves and then the array. + if(list->l_datasets) { + for(size_t i = 0; i < list->l_length; ++i) { + free((void*) list->l_datasets[i].d_id); + } + free(list->l_datasets); + } + + free(list); + return ret; +} + +ADM_storage_t +ADM_storage_create(const char* id, ADM_storage_type_t type, void* ctx) { + + struct adm_storage* adm_storage = + (struct adm_storage*) malloc(sizeof(*adm_storage)); + const char* error_msg = NULL; + + if(!adm_storage) { + LOGGER_ERROR("Could not allocate ADM_storage_t"); + return NULL; + } + + if(!id) { + LOGGER_ERROR("Null storage id") + return NULL; + } + + if(!ctx) { + LOGGER_ERROR("Null storage context") + return NULL; + } + + adm_storage->s_id = (const char*) calloc(strlen(id) + 1, sizeof(char)); + strcpy((char*) adm_storage->s_id, id); + adm_storage->s_type = type; + + switch(adm_storage->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + adm_storage->s_adhoc_ctx = + (ADM_adhoc_context_t) calloc(1, sizeof(adm_adhoc_context)); + if(!adm_storage->s_adhoc_ctx) { + error_msg = "Could not allocate ADM_adhoc_context_t"; + goto cleanup_on_error; + } + + memcpy(adm_storage->s_adhoc_ctx, (ADM_adhoc_context_t) ctx, + sizeof(*(ADM_adhoc_context_t) ctx)); + break; + + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + adm_storage->s_pfs_ctx = + (ADM_pfs_context_t) calloc(1, sizeof(adm_pfs_context)); + if(!adm_storage->s_pfs_ctx) { + error_msg = "Could not allocate ADM_pfs_context_t"; + goto cleanup_on_error; + } + + memcpy(adm_storage->s_pfs_ctx, (ADM_pfs_context_t) ctx, + sizeof(*(ADM_pfs_context_t) ctx)); + break; + } + + return adm_storage; + +cleanup_on_error: + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + [[maybe_unused]] ADM_return_t ret = ADM_storage_destroy(adm_storage); + assert(ret); + + return NULL; +} + +ADM_return_t +ADM_storage_destroy(ADM_storage_t storage) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!storage) { + LOGGER_ERROR("Invalid ADM_storage_t") + return ADM_EBADARGS; + } + + if(storage->s_id) { + free((void*) storage->s_id); + } + + switch(storage->s_type) { + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + if(storage->s_adhoc_ctx) { + free(storage->s_adhoc_ctx); + } + break; + + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + if(storage->s_pfs_ctx) { + free(storage->s_pfs_ctx); + } + break; + } + + free(storage); + return ret; +} + +ADM_storage_resources_t +ADM_storage_resources_create() { + + struct adm_storage_resources* adm_storage_resources = + (struct adm_storage_resources*) malloc( + sizeof(*adm_storage_resources)); + + if(!adm_storage_resources) { + LOGGER_ERROR("Could not allocate ADM_storage_resources_t"); + return NULL; + } + + return adm_storage_resources; +} + +ADM_return_t +ADM_storage_resources_destroy(ADM_storage_resources_t res) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!res) { + LOGGER_ERROR("Invalid ADM_storage_resources_t") + return ADM_EBADARGS; + } + + free(res); + return ret; +} + +ADM_data_operation_t +ADM_data_operation_create() { + + struct adm_data_operation* adm_data_operation = + (struct adm_data_operation*) malloc(sizeof(*adm_data_operation)); + + if(!adm_data_operation) { + LOGGER_ERROR("Could not allocate ADM_data_operation_t"); + return NULL; + } + + return adm_data_operation; +} + +ADM_return_t +ADM_data_operation_destroy(ADM_data_operation_t op) { + + ADM_return_t ret = ADM_SUCCESS; + + if(!op) { + LOGGER_ERROR("Invalid ADM_data_operation_t") + return ADM_EBADARGS; + } + + free(op); + return ret; +} + + +ADM_adhoc_context_t +ADM_adhoc_context_create(ADM_adhoc_mode_t exec_mode, + ADM_adhoc_access_t access_type, uint32_t nodes, + uint32_t walltime, bool should_flush) { + + struct adm_adhoc_context* adm_adhoc_context = + (struct adm_adhoc_context*) malloc(sizeof(*adm_adhoc_context)); + + if(!adm_adhoc_context) { + LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); + return NULL; + } + + adm_adhoc_context->c_mode = exec_mode; + adm_adhoc_context->c_access = access_type; + adm_adhoc_context->c_nodes = nodes; + adm_adhoc_context->c_walltime = walltime; + adm_adhoc_context->c_should_bg_flush = should_flush; + + return adm_adhoc_context; +} + +ADM_return_t +ADM_adhoc_context_destroy(ADM_adhoc_context_t ctx) { + + + ADM_return_t ret = ADM_SUCCESS; + + if(!ctx) { + LOGGER_ERROR("Invalid ADM_adhoc_context_t") + return ADM_EBADARGS; + } + + free(ctx); + return ret; +} + +ADM_pfs_context_t +ADM_pfs_context_create(const char* mountpoint) { + + struct adm_pfs_context* adm_pfs_context = + (struct adm_pfs_context*) malloc(sizeof(*adm_pfs_context)); + + if(!adm_pfs_context) { + LOGGER_ERROR("Could not allocate ADM_adhoc_context_t"); + return NULL; + } + + adm_pfs_context->c_mount = mountpoint; + + return adm_pfs_context; +} + +ADM_return_t +ADM_pfs_context_destroy(ADM_pfs_context_t ctx) { + ADM_return_t ret = ADM_SUCCESS; + + if(!ctx) { + LOGGER_ERROR("Invalid ADM_pfs_context_t") + return ADM_EBADARGS; + } + + free(ctx); + return ret; +} + +ADM_job_requirements_t +ADM_job_requirements_create(ADM_dataset_t inputs[], size_t inputs_len, + ADM_dataset_t outputs[], size_t outputs_len, + ADM_storage_t storage) { + + struct adm_job_requirements* adm_job_reqs = + (struct adm_job_requirements*) calloc( + 1, sizeof(struct adm_job_requirements)); + + if(!adm_job_reqs) { + LOGGER_ERROR("Could not allocate ADM_job_requirements_t") + return NULL; + } + + ADM_dataset_list_t inputs_list = NULL; + ADM_dataset_list_t outputs_list = NULL; + const char* error_msg = NULL; + + inputs_list = ADM_dataset_list_create(inputs, inputs_len); + + if(!inputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; + } + + outputs_list = ADM_dataset_list_create(outputs, outputs_len); + + if(!outputs_list) { + error_msg = "Could not allocate ADM_job_requirements_t"; + goto cleanup_on_error; + } + + adm_job_reqs->r_inputs = inputs_list; + adm_job_reqs->r_outputs = outputs_list; + + if(!storage) { + return adm_job_reqs; + } + + if(storage->s_type != ADM_STORAGE_GEKKOFS && + storage->s_type != ADM_STORAGE_DATACLAY && + storage->s_type != ADM_STORAGE_EXPAND && + storage->s_type != ADM_STORAGE_HERCULES) { + error_msg = "Invalid adhoc_storage type"; + goto cleanup_on_error; + } + + adm_job_reqs->r_storage = ADM_storage_create(storage->s_id, storage->s_type, + storage->s_adhoc_ctx); + + return adm_job_reqs; + +cleanup_on_error: + + if(error_msg) { + LOGGER_ERROR(error_msg); + } + + if(adm_job_reqs) { + ADM_job_requirements_destroy(adm_job_reqs); + } + + return NULL; +} + +ADM_return_t +ADM_job_requirements_destroy(ADM_job_requirements_t reqs) { + ADM_return_t ret = ADM_SUCCESS; + + if(!reqs) { + LOGGER_ERROR("Invalid ADM_job_requirements_t") + return ADM_EBADARGS; + } + + if(reqs->r_inputs) { + ADM_dataset_list_destroy(reqs->r_inputs); + } + + if(reqs->r_outputs) { + ADM_dataset_list_destroy(reqs->r_outputs); + } + + if(reqs->r_storage) { + ADM_storage_destroy(reqs->r_storage); + } + + free(reqs); + return ret; +} + +/** + * Initialize a job handle that can be used by clients to refer to a job. + * + * @remark This function is not actually part of the public API, but it is + * useful to have for internal purposes + * + * @param [in] id The identifier for this job + * @return A valid JOB HANDLE or NULL in case of failure. + */ +ADM_job_t +ADM_job_create(uint64_t id) { + + struct adm_job* adm_job = (struct adm_job*) malloc(sizeof(struct adm_job)); + + if(!adm_job) { + LOGGER_ERROR("Could not allocate ADM_job_t") + return NULL; + } + + adm_job->j_id = id; + + return adm_job; +} + +/** + * Destroy a ADM_job_t created by ADM_job_create(). + * + * @remark This function is not actually part of the public API, but it is + * useful to have for internal purposes + * + * @param[in] reqs The ADM_job_t to destroy. + * @return ADM_SUCCESS or corresponding error code. + */ +ADM_return_t +ADM_job_destroy(ADM_job_t job) { + ADM_return_t ret = ADM_SUCCESS; + + if(!job) { + LOGGER_ERROR("Invalid ADM_job_t") + return ADM_EBADARGS; + } + + free(job); + return ret; +} + + +/******************************************************************************/ +/* C++ Type definitions and related functions */ +/******************************************************************************/ + +namespace admire { + +server::server(std::string protocol, std::string address) + : m_protocol(std::move(protocol)), m_address(std::move(address)) {} + +server::server(const ADM_server_t& srv) + : m_protocol(srv->s_protocol), m_address(srv->s_address) {} + +job::job(job_id id) : m_id(id) {} + +job::job(ADM_job_t job) : m_id(job->j_id) {} + +storage::storage(storage::type type, std::string id) + : m_id(std::move(id)), m_type(type) {} + +adhoc_storage::adhoc_storage(storage::type type, std::string id, + execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) + : storage(type, std::move(id)), m_ctx{exec_mode, access_type, nodes, + walltime, should_flush} {} + +adhoc_storage::adhoc_storage(storage::type type, std::string id, + ADM_adhoc_context_t ctx) + : storage(type, std::move(id)), m_ctx(ctx) {} + +ADM_storage_t +adhoc_storage::to_rpc_type() const { + + // ADM_storage_create() copies the context internally, so it is fine + // to use a local variable address here as an argument + adm_adhoc_context ctx{ + .c_mode = static_cast(m_ctx.m_exec_mode), + .c_access = static_cast(m_ctx.m_access_type), + .c_nodes = m_ctx.m_nodes, + .c_walltime = m_ctx.m_walltime, + .c_should_bg_flush = m_ctx.m_should_flush}; + + return ADM_storage_create(m_id.c_str(), + static_cast(m_type), + reinterpret_cast(&ctx)); +} + + +adhoc_storage::context::context(adhoc_storage::execution_mode exec_mode, + adhoc_storage::access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) + : m_exec_mode(exec_mode), m_access_type(access_type), m_nodes(nodes), + m_walltime(walltime), m_should_flush(should_flush) {} + +adhoc_storage::context::context(ADM_adhoc_context_t ctx) + : context(static_cast(ctx->c_mode), + static_cast(ctx->c_access), ctx->c_nodes, + ctx->c_walltime, ctx->c_should_bg_flush) {} + +ADM_adhoc_context_t +adhoc_storage::context::to_rpc_type() const { + + return ADM_adhoc_context_create( + static_cast(m_exec_mode), + static_cast(m_access_type), m_nodes, m_walltime, + m_should_flush); +} + + +pfs_storage::pfs_storage(storage::type type, std::string id, + std::filesystem::path mount_point) + : storage(type, std::move(id)), m_ctx(std::move(mount_point)) {} + +pfs_storage::pfs_storage(storage::type type, std::string id, + ADM_pfs_context_t ctx) + : storage(type, std::move(id)), m_ctx(ctx) {} + +ADM_storage_t +pfs_storage::to_rpc_type() const { + + // ADM_storage_create() copies the context internally, so it is fine + // to use a local variable address here as an argument + adm_pfs_context ctx{.c_mount = m_ctx.m_mount_point.c_str()}; + + return ADM_storage_create(m_id.c_str(), + static_cast(m_type), + reinterpret_cast(&ctx)); +} + + +pfs_storage::context::context(std::filesystem::path mount_point) + : m_mount_point(std::move(mount_point)) {} + +pfs_storage::context::context(ADM_pfs_context_t ctx) : context(ctx->c_mount) {} + +ADM_pfs_context_t +pfs_storage::context::to_rpc_type() const { + return ADM_pfs_context_create(m_mount_point.c_str()); +} + + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), + m_storage(std::move(storage)) {} + +job_requirements::job_requirements(ADM_job_requirements_t reqs) { + m_inputs.reserve(reqs->r_inputs->l_length); + + for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { + m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); + } + + m_outputs.reserve(reqs->r_outputs->l_length); + + for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { + m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); + } + + if(reqs->r_storage) { + + switch(reqs->r_storage->s_type) { + + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + m_storage = std::make_unique( + static_cast(reqs->r_storage->s_type), + reqs->r_storage->s_id, reqs->r_storage->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + m_storage = std::make_unique( + static_cast(reqs->r_storage->s_type), + reqs->r_storage->s_id, reqs->r_storage->s_pfs_ctx); + break; + } + } +} + +ADM_job_requirements_t +job_requirements::to_rpc_type() const { + using scord::utils::c_ptr; + using scord::utils::c_ptr_vector; + using dataset_vector = c_ptr_vector; + + dataset_vector inputs; + inputs.reserve(m_inputs.size()); + + for(const auto& in : m_inputs) { + inputs.emplace_back(ADM_dataset_create(in.m_id.c_str())); + } + + dataset_vector outputs; + outputs.reserve(m_outputs.size()); + + for(const auto& out : m_outputs) { + outputs.emplace_back(ADM_dataset_create(out.m_id.c_str())); + } + + return ADM_job_requirements_create( + inputs.data(), inputs.size(), outputs.data(), outputs.size(), + m_storage ? m_storage->to_rpc_type() : nullptr); +} + + +} // namespace admire diff --git a/src/scord-ctl/CMakeLists.txt b/src/scord-ctl/CMakeLists.txt index 76cd26aa..6d7c474b 100644 --- a/src/scord-ctl/CMakeLists.txt +++ b/src/scord-ctl/CMakeLists.txt @@ -35,7 +35,7 @@ target_include_directories( target_link_libraries( scord-ctl PRIVATE common::config common::logger common::network::rpc_server - common::network::rpc_types fmt::fmt Boost::program_options + common::network::rpc_types admire_types fmt::fmt Boost::program_options ) install(TARGETS scord DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/scord/CMakeLists.txt b/src/scord/CMakeLists.txt index be566b3d..e842d425 100644 --- a/src/scord/CMakeLists.txt +++ b/src/scord/CMakeLists.txt @@ -39,6 +39,7 @@ target_link_libraries( common::logger common::network::rpc_server common::network::rpc_types + admire_types fmt::fmt Boost::program_options RedisPlusPlus::RedisPlusPlus -- GitLab From 1ab54ef2adbaace6e3adced6631111525d626ef4 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 10:46:21 +0200 Subject: [PATCH 14/25] C++ API now relies on pimpl idiom to hide implementation --- src/lib/admire.cpp | 92 ++++---- src/lib/admire_types.hpp | 177 ++++++++++----- src/lib/types.cpp | 464 +++++++++++++++++++++++++++++---------- 3 files changed, 523 insertions(+), 210 deletions(-) diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index ddb433cc..6555b862 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -201,9 +201,9 @@ update_job(const server& srv, const job& job, const job_requirements& reqs) { (void) job; (void) reqs; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_update_job(...)"); @@ -226,9 +226,9 @@ remove_job(const server& srv, const job& job) { (void) srv; (void) job; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_remove_job(...)"); @@ -254,9 +254,9 @@ register_adhoc_storage(const server& srv, ADM_job_t job, (void) ctx; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_register_adhoc_storage(...)"); @@ -282,9 +282,9 @@ update_adhoc_storage(const server& srv, ADM_job_t job, ADM_adhoc_context_t ctx, (void) ctx; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_update_adhoc_storage(...)"); @@ -309,9 +309,9 @@ remove_adhoc_storage(const server& srv, ADM_job_t job, (void) job; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_remove_adhoc_storage(...)"); @@ -336,9 +336,9 @@ deploy_adhoc_storage(const server& srv, ADM_job_t job, (void) job; (void) adhoc_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_deploy_adhoc_storage(...)"); @@ -364,9 +364,9 @@ register_pfs_storage(const server& srv, ADM_job_t job, ADM_pfs_context_t ctx, (void) ctx; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_register_pfs_storage(...)"); @@ -392,9 +392,9 @@ update_pfs_storage(const server& srv, ADM_job_t job, ADM_pfs_context_t ctx, (void) ctx; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_update_pfs_storage(...)"); @@ -419,9 +419,9 @@ remove_pfs_storage(const server& srv, ADM_job_t job, (void) job; (void) pfs_storage; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_remove_pfs_storage(...)"); @@ -451,9 +451,9 @@ transfer_dataset(const server& srv, ADM_job_t job, ADM_dataset_t** sources, (void) mapping; (void) transfer; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_transfer_dataset(...)"); @@ -479,9 +479,9 @@ set_dataset_information(const server& srv, ADM_job_t job, ADM_dataset_t target, (void) target; (void) info; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_dataset_information(...)"); @@ -507,9 +507,9 @@ set_io_resources(const server& srv, ADM_job_t job, ADM_storage_t tier, (void) tier; (void) resources; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_io_resources(...)"); @@ -535,9 +535,9 @@ get_transfer_priority(const server& srv, ADM_job_t job, ADM_transfer_t transfer, (void) transfer; (void) priority; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_transfer_priority(...)"); @@ -563,9 +563,9 @@ set_transfer_priority(const server& srv, ADM_job_t job, ADM_transfer_t transfer, (void) transfer; (void) incr; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_transfer_priority(...)"); @@ -589,9 +589,9 @@ cancel_transfer(const server& srv, ADM_job_t job, ADM_transfer_t transfer) { (void) job; (void) transfer; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_cancel_transfer(...)"); @@ -617,9 +617,9 @@ get_pending_transfers(const server& srv, ADM_job_t job, (void) job; (void) pending_transfers; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_pending_transfers(...)"); @@ -646,9 +646,9 @@ set_qos_constraints(const server& srv, ADM_job_t job, ADM_qos_entity_t entity, (void) entity; (void) limit; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_set_qos_constraints(...)"); @@ -675,9 +675,9 @@ get_qos_constraints(const server& srv, ADM_job_t job, ADM_qos_entity_t entity, (void) entity; (void) limits; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_qos_constraints(...)"); @@ -705,9 +705,9 @@ define_data_operation(const server& srv, ADM_job_t job, const char* path, (void) op; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_define_data_operation(...)"); @@ -736,9 +736,9 @@ connect_data_operation(const server& srv, ADM_job_t job, ADM_dataset_t input, (void) should_stream; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_connect_data_operation(...)"); @@ -766,9 +766,9 @@ finalize_data_operation(const server& srv, ADM_job_t job, (void) op; (void) status; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_finalize_data_operation(...)"); @@ -797,9 +797,9 @@ link_transfer_to_data_operation(const server& srv, ADM_job_t job, (void) should_stream; (void) args; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_link_transfer_to_data_operation(...)"); @@ -824,9 +824,9 @@ get_statistics(const server& srv, ADM_job_t job, ADM_job_stats_t** stats) { (void) job; (void) stats; - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_get_statistics(...)"); diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index b741e658..8fe103d6 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -40,31 +40,62 @@ using job_id = std::uint64_t; struct server { server(std::string protocol, std::string address); - explicit server(const ADM_server_t& srv); + server(server&&) noexcept; + server& + operator=(server&&) noexcept; + ~server(); - std::string m_protocol; - std::string m_address; + std::string + protocol() const; + std::string + address() const; + +private: + class impl; + std::unique_ptr m_pimpl; }; struct job { explicit job(job_id id); - explicit job(ADM_job_t job); - - job_id m_id; + job(const job&) noexcept; + job(job&&) noexcept; + job& + operator=(job&&) noexcept; + job& + operator=(const job&) noexcept; + ~job(); + + job_id + id() const; + + [[nodiscard]] ADM_job_t + to_ctype() const; + +private: + class impl; + std::unique_ptr m_pimpl; }; struct dataset { - explicit dataset(std::string id) : m_id(std::move(id)) {} + explicit dataset(std::string id); + explicit dataset(ADM_dataset_t dataset); + dataset(const dataset&) noexcept; + dataset(dataset&&) noexcept; + dataset& + operator=(const dataset&) noexcept; + dataset& + operator=(dataset&&) noexcept; + ~dataset(); std::string - to_string() const { - return "foo"; - } + id() const; - std::string m_id; +private: + class impl; + std::unique_ptr m_pimpl; }; struct storage { @@ -78,15 +109,25 @@ struct storage { gpfs = ADM_STORAGE_GPFS }; + struct ctx { + virtual ~ctx() = default; + }; + storage(storage::type type, std::string id); virtual ~storage() = default; - virtual ADM_storage_t - to_rpc_type() const = 0; + std::string + id() const; + type + type() const; + virtual std::shared_ptr + context() const = 0; + +protected: std::string m_id; - type m_type; + enum type m_type; }; struct adhoc_storage : public storage { @@ -104,59 +145,80 @@ struct adhoc_storage : public storage { read_write = ADM_ADHOC_ACCESS_RDWR, }; - struct context { + struct ctx : storage::ctx { - context(execution_mode exec_mode, access_type access_type, - std::uint32_t nodes, std::uint32_t walltime, bool should_flush); + ctx(execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, bool should_flush); - explicit context(ADM_adhoc_context_t ctx); + explicit ctx(ADM_adhoc_context_t ctx); - ADM_adhoc_context_t - to_rpc_type() const; + execution_mode + exec_mode() const; + enum access_type + access_type() const; + std::uint32_t + nodes() const; + std::uint32_t + walltime() const; + bool + should_flush() const; + private: execution_mode m_exec_mode; - access_type m_access_type; + enum access_type m_access_type; std::uint32_t m_nodes; std::uint32_t m_walltime; bool m_should_flush; }; - adhoc_storage(storage::type type, std::string id, execution_mode exec_mode, - access_type access_type, std::uint32_t nodes, - std::uint32_t walltime, bool should_flush); - - adhoc_storage(storage::type type, std::string id, ADM_adhoc_context_t ctx); - - - ADM_storage_t - to_rpc_type() const final; - - context m_ctx; + adhoc_storage(enum storage::type type, std::string id, + execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush); + adhoc_storage(enum storage::type type, std::string id, + ADM_adhoc_context_t ctx); + adhoc_storage(adhoc_storage&&) noexcept = default; + adhoc_storage& + operator=(adhoc_storage&&) noexcept = default; + ~adhoc_storage() override; + + std::shared_ptr + context() const final; + +private: + class impl; + std::unique_ptr m_pimpl; }; struct pfs_storage : public storage { - struct context { + struct ctx : storage::ctx { - explicit context(std::filesystem::path mount_point); + explicit ctx(std::filesystem::path mount_point); - explicit context(ADM_pfs_context_t ctx); + explicit ctx(ADM_pfs_context_t ctx); - ADM_pfs_context_t - to_rpc_type() const; + std::filesystem::path + mount_point() const; + private: std::filesystem::path m_mount_point; }; - pfs_storage(storage::type type, std::string id, + pfs_storage(enum storage::type type, std::string id, std::filesystem::path mount_point); - - pfs_storage(storage::type type, std::string id, ADM_pfs_context_t ctx); - - ADM_storage_t - to_rpc_type() const final; - - context m_ctx; + pfs_storage(enum storage::type type, std::string id, ADM_pfs_context_t ctx); + pfs_storage(pfs_storage&&) noexcept = default; + pfs_storage& + operator=(pfs_storage&&) noexcept = default; + ~pfs_storage() override; + + std::shared_ptr + context() const final; + +private: + class impl; + std::unique_ptr m_pimpl; }; struct job_requirements { @@ -170,12 +232,25 @@ struct job_requirements { explicit job_requirements(ADM_job_requirements_t reqs); - ADM_job_requirements_t - to_rpc_type() const; - - std::vector m_inputs; - std::vector m_outputs; - std::unique_ptr m_storage; + job_requirements(const job_requirements&) noexcept; + job_requirements(job_requirements&&) noexcept; + job_requirements& + operator=(const job_requirements&) noexcept; + job_requirements& + operator=(job_requirements&&) noexcept; + + ~job_requirements(); + + std::vector + inputs() const; + std::vector + outputs() const; + std::shared_ptr + storage() const; + +private: + class impl; + std::unique_ptr m_pimpl; }; } // namespace admire diff --git a/src/lib/types.cpp b/src/lib/types.cpp index 2e8ed350..67cfa13d 100644 --- a/src/lib/types.cpp +++ b/src/lib/types.cpp @@ -698,170 +698,408 @@ ADM_job_destroy(ADM_job_t job) { namespace admire { +class server::impl { + +public: + impl(std::string protocol, std::string address) + : m_protocol(std::move(protocol)), m_address(std::move(address)) {} + + std::string + protocol() const { + return m_protocol; + } + + std::string + address() const { + return m_address; + } + +private: + std::string m_protocol; + std::string m_address; +}; + server::server(std::string protocol, std::string address) - : m_protocol(std::move(protocol)), m_address(std::move(address)) {} + : m_pimpl(std::make_unique(std::move(protocol), + std::move(address))) {} server::server(const ADM_server_t& srv) - : m_protocol(srv->s_protocol), m_address(srv->s_address) {} + : server::server(srv->s_protocol, srv->s_address) {} -job::job(job_id id) : m_id(id) {} +server::server(server&&) noexcept = default; -job::job(ADM_job_t job) : m_id(job->j_id) {} +server& +server::operator=(server&&) noexcept = default; -storage::storage(storage::type type, std::string id) - : m_id(std::move(id)), m_type(type) {} +server::~server() = default; -adhoc_storage::adhoc_storage(storage::type type, std::string id, - execution_mode exec_mode, access_type access_type, - std::uint32_t nodes, std::uint32_t walltime, - bool should_flush) - : storage(type, std::move(id)), m_ctx{exec_mode, access_type, nodes, - walltime, should_flush} {} +std::string +server::protocol() const { + return m_pimpl->protocol(); +} -adhoc_storage::adhoc_storage(storage::type type, std::string id, - ADM_adhoc_context_t ctx) - : storage(type, std::move(id)), m_ctx(ctx) {} +std::string +server::address() const { + return m_pimpl->address(); +} -ADM_storage_t -adhoc_storage::to_rpc_type() const { - // ADM_storage_create() copies the context internally, so it is fine - // to use a local variable address here as an argument - adm_adhoc_context ctx{ - .c_mode = static_cast(m_ctx.m_exec_mode), - .c_access = static_cast(m_ctx.m_access_type), - .c_nodes = m_ctx.m_nodes, - .c_walltime = m_ctx.m_walltime, - .c_should_bg_flush = m_ctx.m_should_flush}; +class job::impl { + +public: + explicit impl(job_id id) : m_id(id) {} + + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + job_id + id() const { + return m_id; + } + +private: + job_id m_id; +}; + +job::job(job_id id) : m_pimpl(std::make_unique(id)) {} + +job::job(ADM_job_t job) : job::job(job->j_id) {} + +job::job(job&&) noexcept = default; + +job& +job::operator=(job&&) noexcept = default; + +job::job(const job& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +job& +job::operator=(const job& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +job::~job() = default; + +job_id +job::id() const { + return m_pimpl->id(); +} + +class dataset::impl { +public: + explicit impl(std::string id) : m_id(std::move(id)) {} + + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + ~impl() = default; + + std::string + id() const { + return m_id; + } + +private: + std::string m_id; +}; + +dataset::dataset(std::string id) + : m_pimpl(std::make_unique(std::move(id))) {} + +dataset::dataset(ADM_dataset_t dataset) : dataset::dataset(dataset->d_id) {} + +dataset::dataset(const dataset& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +dataset::dataset(dataset&&) noexcept = default; + +dataset& +dataset::operator=(const dataset& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +dataset& +dataset::operator=(dataset&&) noexcept = default; + +dataset::~dataset() = default; - return ADM_storage_create(m_id.c_str(), - static_cast(m_type), - reinterpret_cast(&ctx)); +std::string +dataset::id() const { + return m_pimpl->id(); } -adhoc_storage::context::context(adhoc_storage::execution_mode exec_mode, - adhoc_storage::access_type access_type, - std::uint32_t nodes, std::uint32_t walltime, - bool should_flush) +storage::storage(enum storage::type type, std::string id) + : m_id(std::move(id)), m_type(type) {} + +std::string +storage::id() const { + return m_id; +} + +enum storage::type +storage::type() const { + return m_type; +} + +adhoc_storage::ctx::ctx(adhoc_storage::execution_mode exec_mode, + adhoc_storage::access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) : m_exec_mode(exec_mode), m_access_type(access_type), m_nodes(nodes), m_walltime(walltime), m_should_flush(should_flush) {} -adhoc_storage::context::context(ADM_adhoc_context_t ctx) - : context(static_cast(ctx->c_mode), - static_cast(ctx->c_access), ctx->c_nodes, - ctx->c_walltime, ctx->c_should_bg_flush) {} +adhoc_storage::ctx::ctx(ADM_adhoc_context_t ctx) + : adhoc_storage::ctx(static_cast(ctx->c_mode), + static_cast(ctx->c_access), + ctx->c_nodes, ctx->c_walltime, + ctx->c_should_bg_flush) {} -ADM_adhoc_context_t -adhoc_storage::context::to_rpc_type() const { +adhoc_storage::execution_mode +adhoc_storage::ctx::exec_mode() const { + return m_exec_mode; +} - return ADM_adhoc_context_create( - static_cast(m_exec_mode), - static_cast(m_access_type), m_nodes, m_walltime, - m_should_flush); +adhoc_storage::access_type +adhoc_storage::ctx::access_type() const { + return m_access_type; } +std::uint32_t +adhoc_storage::ctx::nodes() const { + return m_nodes; +} -pfs_storage::pfs_storage(storage::type type, std::string id, - std::filesystem::path mount_point) - : storage(type, std::move(id)), m_ctx(std::move(mount_point)) {} +std::uint32_t +adhoc_storage::ctx::walltime() const { + return m_walltime; +} -pfs_storage::pfs_storage(storage::type type, std::string id, - ADM_pfs_context_t ctx) - : storage(type, std::move(id)), m_ctx(ctx) {} +bool +adhoc_storage::ctx::should_flush() const { + return m_should_flush; +} -ADM_storage_t -pfs_storage::to_rpc_type() const { +class adhoc_storage::impl { - // ADM_storage_create() copies the context internally, so it is fine - // to use a local variable address here as an argument - adm_pfs_context ctx{.c_mount = m_ctx.m_mount_point.c_str()}; +public: + explicit impl(adhoc_storage::ctx ctx) : m_ctx(std::move(ctx)) {} + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; - return ADM_storage_create(m_id.c_str(), - static_cast(m_type), - reinterpret_cast(&ctx)); + adhoc_storage::ctx + context() const { + return m_ctx; + } + +private: + adhoc_storage::ctx m_ctx; +}; + + +adhoc_storage::adhoc_storage(enum storage::type type, std::string id, + execution_mode exec_mode, access_type access_type, + std::uint32_t nodes, std::uint32_t walltime, + bool should_flush) + : storage(type, std::move(id)), + m_pimpl(std::make_unique(adhoc_storage::ctx{ + exec_mode, access_type, nodes, walltime, should_flush})) {} + +adhoc_storage::adhoc_storage(enum storage::type type, std::string id, + ADM_adhoc_context_t ctx) + : storage(type, std::move(id)), + m_pimpl(std::make_unique(adhoc_storage::ctx{ctx})) {} + +std::shared_ptr +adhoc_storage::context() const { + return std::make_shared(m_pimpl->context()); } +adhoc_storage::~adhoc_storage() = default; -pfs_storage::context::context(std::filesystem::path mount_point) +pfs_storage::ctx::ctx(std::filesystem::path mount_point) : m_mount_point(std::move(mount_point)) {} -pfs_storage::context::context(ADM_pfs_context_t ctx) : context(ctx->c_mount) {} +pfs_storage::ctx::ctx(ADM_pfs_context_t ctx) : pfs_storage::ctx(ctx->c_mount) {} -ADM_pfs_context_t -pfs_storage::context::to_rpc_type() const { - return ADM_pfs_context_create(m_mount_point.c_str()); +std::filesystem::path +pfs_storage::ctx::mount_point() const { + return m_mount_point; } +class pfs_storage::impl { -job_requirements::job_requirements(std::vector inputs, - std::vector outputs) - : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} +public: + explicit impl(pfs_storage::ctx ctx) : m_ctx(std::move(ctx)) {} + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; -job_requirements::job_requirements(std::vector inputs, - std::vector outputs, - std::unique_ptr storage) - : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), - m_storage(std::move(storage)) {} + pfs_storage::ctx + context() const { + return m_ctx; + } -job_requirements::job_requirements(ADM_job_requirements_t reqs) { - m_inputs.reserve(reqs->r_inputs->l_length); +private: + pfs_storage::ctx m_ctx; +}; - for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { - m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); - } +pfs_storage::pfs_storage(enum storage::type type, std::string id, + std::filesystem::path mount_point) + : storage(type, std::move(id)), + m_pimpl(std::make_unique( + pfs_storage::ctx{std::move(mount_point)})) {} - m_outputs.reserve(reqs->r_outputs->l_length); +pfs_storage::pfs_storage(enum storage::type type, std::string id, + ADM_pfs_context_t ctx) + : storage(type, std::move(id)), + m_pimpl(std::make_unique(pfs_storage::ctx{ctx})) {} - for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { - m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); - } +pfs_storage::~pfs_storage() = default; - if(reqs->r_storage) { +std::shared_ptr +pfs_storage::context() const { + return std::make_shared(m_pimpl->context()); +} + +class job_requirements::impl { + +public: + impl(std::vector inputs, + std::vector outputs) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)) {} - switch(reqs->r_storage->s_type) { - - case ADM_STORAGE_GEKKOFS: - case ADM_STORAGE_DATACLAY: - case ADM_STORAGE_EXPAND: - case ADM_STORAGE_HERCULES: - m_storage = std::make_unique( - static_cast(reqs->r_storage->s_type), - reqs->r_storage->s_id, reqs->r_storage->s_adhoc_ctx); - break; - case ADM_STORAGE_LUSTRE: - case ADM_STORAGE_GPFS: - m_storage = std::make_unique( - static_cast(reqs->r_storage->s_type), - reqs->r_storage->s_id, reqs->r_storage->s_pfs_ctx); - break; + impl(std::vector inputs, + std::vector outputs, + std::unique_ptr storage) + : m_inputs(std::move(inputs)), m_outputs(std::move(outputs)), + m_storage(std::move(storage)) {} + + explicit impl(ADM_job_requirements_t reqs) { + m_inputs.reserve(reqs->r_inputs->l_length); + + for(size_t i = 0; i < reqs->r_inputs->l_length; ++i) { + m_inputs.emplace_back(reqs->r_inputs->l_datasets[i].d_id); } - } -} -ADM_job_requirements_t -job_requirements::to_rpc_type() const { - using scord::utils::c_ptr; - using scord::utils::c_ptr_vector; - using dataset_vector = c_ptr_vector; + m_outputs.reserve(reqs->r_outputs->l_length); - dataset_vector inputs; - inputs.reserve(m_inputs.size()); + for(size_t i = 0; i < reqs->r_outputs->l_length; ++i) { + m_outputs.emplace_back(reqs->r_outputs->l_datasets[i].d_id); + } - for(const auto& in : m_inputs) { - inputs.emplace_back(ADM_dataset_create(in.m_id.c_str())); + if(reqs->r_storage) { + + switch(reqs->r_storage->s_type) { + + case ADM_STORAGE_GEKKOFS: + case ADM_STORAGE_DATACLAY: + case ADM_STORAGE_EXPAND: + case ADM_STORAGE_HERCULES: + m_storage = std::make_unique( + static_cast( + reqs->r_storage->s_type), + reqs->r_storage->s_id, + reqs->r_storage->s_adhoc_ctx); + break; + case ADM_STORAGE_LUSTRE: + case ADM_STORAGE_GPFS: + m_storage = std::make_unique( + static_cast( + reqs->r_storage->s_type), + reqs->r_storage->s_id, reqs->r_storage->s_pfs_ctx); + break; + } + } } - dataset_vector outputs; - outputs.reserve(m_outputs.size()); + impl(const impl& rhs) = default; + impl(impl&& rhs) = default; + impl& + operator=(const impl& other) noexcept = default; + impl& + operator=(impl&&) noexcept = default; + + std::vector + inputs() const { + return m_inputs; + } - for(const auto& out : m_outputs) { - outputs.emplace_back(ADM_dataset_create(out.m_id.c_str())); + std::vector + outputs() const { + return m_outputs; } - return ADM_job_requirements_create( - inputs.data(), inputs.size(), outputs.data(), outputs.size(), - m_storage ? m_storage->to_rpc_type() : nullptr); + std::shared_ptr + storage() const { + return m_storage; + } + +private: + std::vector m_inputs; + std::vector m_outputs; + std::shared_ptr m_storage; +}; + + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs) + : m_pimpl(std::make_unique(std::move(inputs), std::move(outputs))) {} + +job_requirements::job_requirements(std::vector inputs, + std::vector outputs, + std::unique_ptr storage) + : m_pimpl(std::make_unique(std::move(inputs), std::move(outputs), + std::move(storage))) {} + +job_requirements::job_requirements(ADM_job_requirements_t reqs) + : m_pimpl(std::make_unique(reqs)) {} + +job_requirements::job_requirements(const job_requirements& other) noexcept + : m_pimpl(std::make_unique(*other.m_pimpl)) {} + +job_requirements::job_requirements(job_requirements&&) noexcept = default; + +job_requirements& +job_requirements::operator=(const job_requirements& other) noexcept { + this->m_pimpl = std::make_unique(*other.m_pimpl); + return *this; +} + +job_requirements& +job_requirements::operator=(job_requirements&&) noexcept = default; + +job_requirements::~job_requirements() = default; + +std::vector +job_requirements::inputs() const { + return m_pimpl->inputs(); +} + +std::vector +job_requirements::outputs() const { + return m_pimpl->outputs(); +} + +std::shared_ptr +job_requirements::storage() const { + return m_pimpl->storage(); } -- GitLab From 514da2b4cf3ed93d75d04637e2db3cfe9acfa51d Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 21 Jul 2022 11:57:07 +0200 Subject: [PATCH 15/25] Add formatting functions for C++ types --- src/lib/admire_types.hpp | 235 +++++++++++++++++++++++++++++++++++++ src/lib/detail/impl.cpp | 2 +- src/scord/rpc_handlers.cpp | 18 ++- 3 files changed, 251 insertions(+), 4 deletions(-) diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index 8fe103d6..64845978 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -255,4 +255,239 @@ private: } // namespace admire + +//////////////////////////////////////////////////////////////////////////////// +// Formatting functions +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::job& j, FormatContext& ctx) const { + return formatter::format( + fmt::format("id: {}", j.id()), ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::dataset& d, FormatContext& ctx) const { + return formatter::format("\"" + d.id() + "\"", ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const enum admire::storage::type& t, FormatContext& ctx) const { + + using admire::storage; + std::string_view name = "unknown"; + + switch(t) { + case storage::type::gekkofs: + name = "ADM_STORAGE_GEKKOFS"; + break; + case storage::type::dataclay: + name = "ADM_STORAGE_DATACLAY"; + break; + case storage::type::expand: + name = "ADM_STORAGE_EXPAND"; + break; + case storage::type::hercules: + name = "ADM_STORAGE_HERCULES"; + break; + case storage::type::lustre: + name = "ADM_STORAGE_LUSTRE"; + break; + case storage::type::gpfs: + name = "ADM_STORAGE_GPFS"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::execution_mode& exec_mode, + FormatContext& ctx) const { + + using execution_mode = admire::adhoc_storage::execution_mode; + + std::string_view name = "unknown"; + + switch(exec_mode) { + case execution_mode::in_job_shared: + name = "IN_JOB_SHARED"; + break; + case execution_mode::in_job_dedicated: + name = "IN_JOB_DEDICATED"; + break; + case execution_mode::separate_new: + name = "SEPARATE_NEW"; + break; + case execution_mode::separate_existing: + name = "SEPARATE_EXISTING"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::access_type& type, + FormatContext& ctx) const { + + using access_type = admire::adhoc_storage::access_type; + + std::string_view name = "unknown"; + + switch(type) { + case access_type::read_only: + name = "RDONLY"; + break; + case access_type::write_only: + name = "WRONLY"; + break; + case access_type::read_write: + name = "RDWR"; + break; + } + + return formatter::format(name, ctx); + } +}; + +template <> +struct fmt::formatter> + : formatter { + // parse is inherited from formatter. + template + auto + format(const std::shared_ptr& s, + FormatContext& ctx) const { + + if(!s) { + return formatter::format("NULL", ctx); + } + + switch(s->type()) { + case admire::storage::type::gekkofs: + case admire::storage::type::dataclay: + case admire::storage::type::expand: + case admire::storage::type::hercules: + return formatter::format( + fmt::format("{}", + *(dynamic_cast( + s.get()))), + ctx); + case admire::storage::type::lustre: + case admire::storage::type::gpfs: + return formatter::format( + fmt::format("{}", *(dynamic_cast( + s.get()))), + ctx); + default: + return formatter::format("unknown", ctx); + } + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage& s, FormatContext& ctx) const { + + const auto pctx = std::dynamic_pointer_cast( + s.context()); + + const auto str = + fmt::format("{{type: {}, id: {}, context: {}}}", s.type(), + std::quoted(s.id()), + (pctx ? fmt::format("{}", *pctx) : "NULL")); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter + : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::adhoc_storage::ctx& c, FormatContext& ctx) const { + + const auto str = + fmt::format("{{execution_mode: {}, access_type: {}, " + "nodes: {}, walltime: {}, should_flush: {}}}", + c.exec_mode(), c.access_type(), c.nodes(), + c.walltime(), c.should_flush()); + + return formatter::format(str, ctx); + } +}; + + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::pfs_storage& s, FormatContext& ctx) const { + + const auto pctx = std::dynamic_pointer_cast( + s.context()); + const auto str = fmt::format( + "{{context: {}}}", (pctx ? fmt::format("{}", *pctx) : "NULL")); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::pfs_storage::ctx& c, FormatContext& ctx) const { + const auto str = fmt::format("{{mount_point: {}}}", c.mount_point()); + return formatter::format(str, ctx); + } +}; + +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::job_requirements& r, FormatContext& ctx) const { + return formatter::format( + fmt::format("inputs: [{}], outputs: [{}], storage: {}", + fmt::join(r.inputs(), ", "), + fmt::join(r.outputs(), ", "), r.storage()), + ctx); + } +}; + #endif // SCORD_ADMIRE_TYPES_HPP diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 402bebd4..d608b661 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -174,7 +174,7 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { auto endp = rpc_client.lookup(srv.m_address); - LOGGER_INFO("ADM_register_job(...)"); + LOGGER_INFO("RPC ({}): {{{}}}", "ADM_register_job", reqs); ADM_register_job_in_t in{*preqs}; ADM_register_job_out_t out; diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index fa3daf8f..8edccb3a 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -24,8 +24,17 @@ #include #include +#include #include "rpc_handlers.hpp" +struct remote_procedure { + static std::uint64_t + new_id() { + static std::atomic_uint64_t current_id; + return current_id++; + } +}; + static void ADM_ping(hg_handle_t h) { @@ -54,11 +63,14 @@ ADM_register_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job_requirements reqs(&in.reqs); - LOGGER_INFO("ADM_register_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}): {{{}}}", id, __FUNCTION__, reqs); - out.ret = 0; + out.ret = ADM_SUCCESS; + + LOGGER_INFO("RPC ID {} ({}) = {}", id, __FUNCTION__, out.ret); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 72acff03076b01c3d2d614dab0b102f1a25e4b32 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Mon, 18 Jul 2022 09:38:40 +0200 Subject: [PATCH 16/25] Update examples with API changes --- examples/c/ADM_register_job.c | 28 +++++++++++++++++++++------- examples/cxx/ADM_register_job.cpp | 28 +++++++++++++++++++++++----- examples/cxx/ADM_remove_job.cpp | 2 +- examples/cxx/ADM_update_job.cpp | 24 +++++++++++++++++++----- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/examples/c/ADM_register_job.c b/examples/c/ADM_register_job.c index b1b9926c..7c53dceb 100644 --- a/examples/c/ADM_register_job.c +++ b/examples/c/ADM_register_job.c @@ -1,5 +1,6 @@ #include #include +#include #include #define NINPUTS 10 @@ -8,7 +9,7 @@ int main(int argc, char* argv[]) { - if(argc != 3) { + if(argc != 2) { fprintf(stderr, "ERROR: no location provided\n"); fprintf(stderr, "Usage: ADM_register_job \n"); exit(EXIT_FAILURE); @@ -17,14 +18,13 @@ main(int argc, char* argv[]) { int exit_status = EXIT_SUCCESS; ADM_server_t server = ADM_server_create("tcp", argv[1]); - ADM_job_t job; ADM_dataset_t inputs[NINPUTS]; for(int i = 0; i < NINPUTS; ++i) { const char* pattern = "input-dataset-%d"; size_t n = snprintf(NULL, 0, pattern, i); - char* id = (char*) malloc(n + 1); + char* id = (char*) alloca(n + 1); snprintf(id, n + 1, pattern, i); inputs[i] = ADM_dataset_create(id); } @@ -34,13 +34,22 @@ main(int argc, char* argv[]) { for(int i = 0; i < NOUTPUTS; ++i) { const char* pattern = "output-dataset-%d"; size_t n = snprintf(NULL, 0, pattern, i); - char* id = (char*) malloc(n + 1); + char* id = (char*) alloca(n + 1); snprintf(id, n + 1, pattern, i); outputs[i] = ADM_dataset_create(id); } - ADM_job_requirements_t reqs = ADM_job_requirements_create( - inputs, NINPUTS, outputs, NOUTPUTS, NULL); + ADM_adhoc_context_t ctx = ADM_adhoc_context_create( + ADM_ADHOC_MODE_SEPARATE_NEW, ADM_ADHOC_ACCESS_RDWR, 42, 100, false); + assert(ctx); + + ADM_storage_t st = ADM_storage_create("foobar", ADM_STORAGE_GEKKOFS, ctx); + assert(st); + + ADM_job_requirements_t reqs = + ADM_job_requirements_create(inputs, NINPUTS, outputs, NOUTPUTS, st); + assert(reqs); + ADM_return_t ret = ADM_register_job(server, reqs, &job); if(ret != ADM_SUCCESS) { @@ -54,7 +63,6 @@ main(int argc, char* argv[]) { "successfully\n"); cleanup: - for(int i = 0; i < NINPUTS; ++i) { ADM_dataset_destroy(inputs[i]); } @@ -63,6 +71,12 @@ cleanup: ADM_dataset_destroy(outputs[i]); } + ADM_storage_destroy(st); + + ADM_adhoc_context_destroy(ctx); + + ADM_job_requirements_destroy(reqs); + ADM_server_destroy(server); exit(exit_status); } diff --git a/examples/cxx/ADM_register_job.cpp b/examples/cxx/ADM_register_job.cpp index 5001058b..cd31c15c 100644 --- a/examples/cxx/ADM_register_job.cpp +++ b/examples/cxx/ADM_register_job.cpp @@ -1,22 +1,40 @@ #include #include +#define NINPUTS 10 +#define NOUTPUTS 5 int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_register_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\n"); + fmt::print(stderr, "Usage: ADM_register_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - ADM_job_requirements_t reqs{}; + std::vector inputs; + inputs.reserve(NINPUTS); + for(int i = 0; i < NINPUTS; ++i) { + inputs.emplace_back(fmt::format("input-dataset-{}", i)); + } - try { + std::vector outputs; + outputs.reserve(NOUTPUTS); + for(int i = 0; i < NOUTPUTS; ++i) { + outputs.emplace_back(fmt::format("output-dataset-{}", i)); + } + auto p = std::make_unique( + admire::storage::type::gekkofs, "foobar", + admire::adhoc_storage::execution_mode::separate_new, + admire::adhoc_storage::access_type::read_write, 42, 100, false); + + admire::job_requirements reqs(inputs, outputs, std::move(p)); + + try { [[maybe_unused]] const auto job = admire::register_job(server, reqs); // do something with job diff --git a/examples/cxx/ADM_remove_job.cpp b/examples/cxx/ADM_remove_job.cpp index fc037a10..4c2090c8 100644 --- a/examples/cxx/ADM_remove_job.cpp +++ b/examples/cxx/ADM_remove_job.cpp @@ -13,7 +13,7 @@ main(int argc, char* argv[]) { admire::server server{"tcp", argv[1]}; - ADM_job_t job{}; + admire::job job{42}; ADM_return_t ret = ADM_SUCCESS; try { diff --git a/examples/cxx/ADM_update_job.cpp b/examples/cxx/ADM_update_job.cpp index 5b579eb4..d034b1de 100644 --- a/examples/cxx/ADM_update_job.cpp +++ b/examples/cxx/ADM_update_job.cpp @@ -1,20 +1,34 @@ #include #include +#define NINPUTS 10 +#define NOUTPUTS 5 int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_update_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\n"); + fmt::print(stderr, "Usage: ADM_update_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; - ADM_job_t job{}; - ADM_job_requirements_t reqs{}; + std::vector inputs; + inputs.reserve(NINPUTS); + for(int i = 0; i < NINPUTS; ++i) { + inputs.emplace_back(fmt::format("input-dataset-{}", i)); + } + + std::vector outputs; + outputs.reserve(NOUTPUTS); + for(int i = 0; i < NOUTPUTS; ++i) { + outputs.emplace_back(fmt::format("output-dataset-{}", i)); + } + + admire::job job{42}; + admire::job_requirements reqs{inputs, outputs}; ADM_return_t ret = ADM_SUCCESS; try { -- GitLab From ac777e3a40d57834f3e6e6a9207189297332a8ff Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 21 Jul 2022 17:45:37 +0200 Subject: [PATCH 17/25] Cleanup network/proto/rpc_types.h --- src/common/network/proto/rpc_types.h | 49 ++++++++++++---------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/common/network/proto/rpc_types.h b/src/common/network/proto/rpc_types.h index dd4ef22c..937f17bf 100644 --- a/src/common/network/proto/rpc_types.h +++ b/src/common/network/proto/rpc_types.h @@ -25,7 +25,7 @@ #ifndef SCORD_PROTO_TYPES_HPP #define SCORD_PROTO_TYPES_HPP -#include +#include // NOLINT #include #include #include @@ -46,7 +46,7 @@ typedef struct adm_node { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_node, + adm_node, // NOLINT ((hg_const_string_t) (n_hostname)) ); // clang-format on @@ -57,7 +57,7 @@ typedef struct adm_dataset { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_dataset, + adm_dataset, // NOLINT ((hg_const_string_t) (d_id)) ); // clang-format on @@ -68,7 +68,7 @@ typedef struct adm_job { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_job, + adm_job, // NOLINT ((hg_uint64_t) (j_id)) ); // clang-format on @@ -86,7 +86,7 @@ struct adm_qos_entity { }; }; -// TODO: union decoder +// TODO: encoder/decoder struct adm_qos_limit { ADM_qos_entity_t l_entity; @@ -94,16 +94,7 @@ struct adm_qos_limit { uint64_t l_value; }; -#if 0 -// clang-format off -MERCURY_GEN_STRUCT_PROC( - adm_qos_limit, - ((adm_qos_entity) (l_entity)) - ((int) (l_class)) - ((hg_uint64_t) (l_value)) -); -// clang-format on -#endif +// TODO: encoder/decoder typedef struct adm_transfer { // TODO: undefined for now @@ -112,8 +103,8 @@ typedef struct adm_transfer { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_transfer, - ((hg_int32_t) (placeholder)) + adm_transfer, // NOLINT + ((hg_int32_t) (placeholder)) ); // clang-format on @@ -124,7 +115,7 @@ typedef struct adm_dataset_info { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_dataset_info, + adm_dataset_info, // NOLINT ((hg_int32_t) (placeholder)) ); // clang-format on @@ -144,12 +135,12 @@ typedef struct adm_adhoc_context { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_adhoc_context, + adm_adhoc_context, // NOLINT ((hg_int32_t) (c_mode)) - ((hg_int32_t) (c_access)) - ((hg_uint32_t) (c_nodes)) - ((hg_uint32_t) (c_walltime)) - ((hg_bool_t) (c_should_bg_flush)) + ((hg_int32_t) (c_access)) + ((hg_uint32_t) (c_nodes)) + ((hg_uint32_t) (c_walltime)) + ((hg_bool_t) (c_should_bg_flush)) ) // clang-format on @@ -160,12 +151,11 @@ typedef struct adm_pfs_context { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_pfs_context, + adm_pfs_context, // NOLINT ((hg_const_string_t) (c_mount)) ); // clang-format on -// TODO: union decoder typedef struct adm_storage { const char* s_id; ADM_storage_type_t s_type; @@ -185,7 +175,7 @@ typedef struct adm_storage_resources { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_storage_resources, + adm_storage_resources, // NOLINT ((hg_int32_t) (placeholder)) ); // clang-format on @@ -197,7 +187,7 @@ typedef struct adm_data_operation { // clang-format off MERCURY_GEN_STRUCT_PROC( - adm_data_operation, + adm_data_operation, // NOLINT ((hg_int32_t) (placeholder)) ); // clang-format on @@ -242,7 +232,10 @@ MERCURY_GEN_STRUCT_PROC( // clang-format off /// ADM_register_job -MERCURY_GEN_PROC(ADM_register_job_in_t, ((adm_job_requirements) (reqs))) +MERCURY_GEN_PROC( + ADM_register_job_in_t, + ((adm_job_requirements) (reqs)) +); MERCURY_GEN_PROC( ADM_register_job_out_t, -- GitLab From 9bd144ae2f911eb95326ae0d3738f617811e3ef6 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 21 Jul 2022 18:02:38 +0200 Subject: [PATCH 18/25] Rename src/common/network to src/common/net --- src/common/CMakeLists.txt | 3 +-- src/common/{network => net}/CMakeLists.txt | 0 src/common/{network => net}/detail/address.hpp | 0 src/common/{network => net}/engine.hpp | 0 src/common/{network => net}/proto/CMakeLists.txt | 1 - src/common/{network => net}/proto/rpc_types.c | 0 src/common/{network => net}/proto/rpc_types.h | 0 src/common/{network => net}/server.cpp | 0 src/common/{network => net}/server.hpp | 0 src/lib/admire.cpp | 4 ++-- src/lib/admire.hpp | 2 +- src/lib/c_wrapper.cpp | 2 +- src/lib/detail/impl.cpp | 4 ++-- src/lib/types.cpp | 2 +- src/scord-ctl/rpc_handlers.cpp | 2 +- src/scord-ctl/scord-ctl.cpp | 4 ++-- src/scord/rpc_handlers.cpp | 2 +- src/scord/scord.cpp | 4 ++-- 18 files changed, 14 insertions(+), 16 deletions(-) rename src/common/{network => net}/CMakeLists.txt (100%) rename src/common/{network => net}/detail/address.hpp (100%) rename src/common/{network => net}/engine.hpp (100%) rename src/common/{network => net}/proto/CMakeLists.txt (99%) rename src/common/{network => net}/proto/rpc_types.c (100%) rename src/common/{network => net}/proto/rpc_types.h (100%) rename src/common/{network => net}/server.cpp (100%) rename src/common/{network => net}/server.hpp (100%) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 65d9daea..92460cc9 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -37,7 +37,7 @@ add_subdirectory(logger) target_include_directories(_logger INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::logger ALIAS _logger) -add_subdirectory(network) +add_subdirectory(net) target_include_directories(_network_engine INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::engine ALIAS _network_engine) @@ -49,4 +49,3 @@ add_library(common::network::rpc_server ALIAS _rpc_server) target_include_directories(_rpc_types INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(common::network::rpc_types ALIAS _rpc_types) - diff --git a/src/common/network/CMakeLists.txt b/src/common/net/CMakeLists.txt similarity index 100% rename from src/common/network/CMakeLists.txt rename to src/common/net/CMakeLists.txt diff --git a/src/common/network/detail/address.hpp b/src/common/net/detail/address.hpp similarity index 100% rename from src/common/network/detail/address.hpp rename to src/common/net/detail/address.hpp diff --git a/src/common/network/engine.hpp b/src/common/net/engine.hpp similarity index 100% rename from src/common/network/engine.hpp rename to src/common/net/engine.hpp diff --git a/src/common/network/proto/CMakeLists.txt b/src/common/net/proto/CMakeLists.txt similarity index 99% rename from src/common/network/proto/CMakeLists.txt rename to src/common/net/proto/CMakeLists.txt index cbe8f47b..f7697d3e 100644 --- a/src/common/network/proto/CMakeLists.txt +++ b/src/common/net/proto/CMakeLists.txt @@ -34,4 +34,3 @@ target_sources( ) target_link_libraries(_rpc_types PRIVATE Mercury::Mercury Margo::Margo) - diff --git a/src/common/network/proto/rpc_types.c b/src/common/net/proto/rpc_types.c similarity index 100% rename from src/common/network/proto/rpc_types.c rename to src/common/net/proto/rpc_types.c diff --git a/src/common/network/proto/rpc_types.h b/src/common/net/proto/rpc_types.h similarity index 100% rename from src/common/network/proto/rpc_types.h rename to src/common/net/proto/rpc_types.h diff --git a/src/common/network/server.cpp b/src/common/net/server.cpp similarity index 100% rename from src/common/network/server.cpp rename to src/common/net/server.cpp diff --git a/src/common/network/server.hpp b/src/common/net/server.hpp similarity index 100% rename from src/common/network/server.hpp rename to src/common/net/server.hpp diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 6555b862..54c9f899 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -23,8 +23,8 @@ *****************************************************************************/ #include -#include -#include +#include +#include #include #include #include "detail/impl.hpp" diff --git a/src/lib/admire.hpp b/src/lib/admire.hpp index 04dfb599..9aacc72a 100644 --- a/src/lib/admire.hpp +++ b/src/lib/admire.hpp @@ -26,7 +26,7 @@ #include #include #include "admire_types.hpp" -#include "network/proto/rpc_types.h" +#include "net/proto/rpc_types.h" #ifndef SCORD_ADMIRE_HPP #define SCORD_ADMIRE_HPP diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index e0cf7fc5..9fa83146 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "admire_types.hpp" #include "admire_types.h" diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index d608b661..d3f4a3da 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -23,8 +23,8 @@ *****************************************************************************/ #include -#include -#include +#include +#include #include #include "impl.hpp" diff --git a/src/lib/types.cpp b/src/lib/types.cpp index 67cfa13d..ba9f0813 100644 --- a/src/lib/types.cpp +++ b/src/lib/types.cpp @@ -23,7 +23,7 @@ *****************************************************************************/ #include -#include +#include #include #include #include diff --git a/src/scord-ctl/rpc_handlers.cpp b/src/scord-ctl/rpc_handlers.cpp index 71115a4a..74f349af 100644 --- a/src/scord-ctl/rpc_handlers.cpp +++ b/src/scord-ctl/rpc_handlers.cpp @@ -23,7 +23,7 @@ *****************************************************************************/ #include -#include +#include #include "rpc_handlers.hpp" static void diff --git a/src/scord-ctl/scord-ctl.cpp b/src/scord-ctl/scord-ctl.cpp index bd83e9bb..834f25a1 100644 --- a/src/scord-ctl/scord-ctl.cpp +++ b/src/scord-ctl/scord-ctl.cpp @@ -32,8 +32,8 @@ #include #include -#include -#include +#include +#include #include #include "rpc_handlers.hpp" diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 8edccb3a..0e7b208d 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -23,7 +23,7 @@ *****************************************************************************/ #include -#include +#include #include #include "rpc_handlers.hpp" diff --git a/src/scord/scord.cpp b/src/scord/scord.cpp index d5b60932..48c3d6d6 100644 --- a/src/scord/scord.cpp +++ b/src/scord/scord.cpp @@ -32,8 +32,8 @@ #include #include -#include -#include +#include +#include #include #include "rpc_handlers.hpp" -- GitLab From c227c3585e936c58505fa2364db389cd7bfcbc4f Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 10:49:11 +0200 Subject: [PATCH 19/25] Add specific types to enable converting between RPC and API types This commit adds two generic templated types (managed_rpc_type and unmanaged_rpc_type) that simplify the lifetime management of any C-types created by Margo RPCs. They also offer conversion functions that allow converting between C RPC types and C++ API types. Both types internally create and store pointers to the C-structures required (or produced) by the RPC engine, but differ in how they manage these structures: - The `managed_rpc_type` template internally manages the lifetime of the C underlying object and ensures that its destruction function will be called when the destructor for `managed_rpc_type` is called. - The `unmanaged_rpc_type` template only creates the C underlying object, but does not destroy it. This is useful when conversions are needed but the underlying data will be automatically destroyed by Margo. Specific conversions are implemented as template specializations. For example, `template <> struct admire::managed_rpc_type` allows converting from an `admire::job` instance to a newly-created `ADM_job_t` via its `get()` function. On the other hand, `template <> struct admire::managed_rpc_type` allows converting from an existing `ADM_job_t` to an `admire::job` instance, also via its `get()` function. --- src/lib/admire_types.hpp | 168 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index 64845978..dfcd951f 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -253,9 +253,177 @@ private: std::unique_ptr m_pimpl; }; +template +struct managed_rpc_type; + +template +struct unmanaged_rpc_type; + } // namespace admire +//////////////////////////////////////////////////////////////////////////////// +// Specializations for conversion types +//////////////////////////////////////////////////////////////////////////////// + +template <> +struct admire::managed_rpc_type { + + template + using managed_ptr = scord::utils::c_ptr; + + explicit managed_rpc_type(const admire::adhoc_storage::ctx& ctx) + : m_adhoc_context(ADM_adhoc_context_create( + static_cast(ctx.exec_mode()), + static_cast(ctx.access_type()), + ctx.nodes(), ctx.walltime(), ctx.should_flush())) {} + + ADM_adhoc_context_t + get() const { + return m_adhoc_context.get(); + } + + managed_ptr m_adhoc_context; +}; + + +template <> +struct admire::managed_rpc_type { + + template + using rpc_storage_ptr = scord::utils::c_ptr; + + template + using managed_ptr = scord::utils::c_ptr; + + explicit managed_rpc_type(const admire::adhoc_storage& st) + : m_adhoc_context(*std::static_pointer_cast( + st.context())), + m_storage(ADM_storage_create( + st.id().c_str(), static_cast(st.type()), + m_adhoc_context.get())) {} + + ADM_storage_t + get() const { + return m_storage.get(); + } + + managed_rpc_type m_adhoc_context; + rpc_storage_ptr m_storage; +}; + +template <> +struct admire::managed_rpc_type> { + + template + using managed_ptr_vector = scord::utils::c_ptr_vector; + + explicit managed_rpc_type(const std::vector& datasets) { + m_datasets.reserve(datasets.size()); + + for(const auto& d : datasets) { + m_datasets.emplace_back(ADM_dataset_create(d.id().c_str())); + } + } + + const ADM_dataset_t* + data() const { + return m_datasets.data(); + } + + ADM_dataset_t* + data() { + return m_datasets.data(); + } + + std::size_t + size() const { + return m_datasets.size(); + } + + managed_ptr_vector m_datasets; +}; + +template <> +struct admire::managed_rpc_type { + + template + using rpc_requirements_ptr = scord::utils::c_ptr; + + explicit managed_rpc_type(const admire::job_requirements& reqs) + : m_inputs(reqs.inputs()), m_outputs(reqs.outputs()), + m_storage(*std::dynamic_pointer_cast( + reqs.storage())), + m_reqs(ADM_job_requirements_create(m_inputs.data(), m_inputs.size(), + m_outputs.data(), m_outputs.size(), + m_storage.get())) {} + + ADM_job_requirements_t + get() const { + return m_reqs.get(); + } + + managed_rpc_type> m_inputs; + managed_rpc_type> m_outputs; + managed_rpc_type m_storage; + rpc_requirements_ptr + m_reqs; +}; + +// forward declarations +ADM_job_t +ADM_job_create(uint64_t id); +ADM_return_t +ADM_job_destroy(ADM_job_t job); + +template <> +struct admire::managed_rpc_type { + + template + using rpc_job_ptr = scord::utils::c_ptr; + + explicit managed_rpc_type(const admire::job& j) + : m_job(ADM_job_create(j.id())) {} + + ADM_job_t + get() const { + return m_job.get(); + } + + rpc_job_ptr m_job; +}; + +template <> +struct admire::managed_rpc_type { + + template + using rpc_job_ptr = scord::utils::c_ptr; + + explicit managed_rpc_type(ADM_job_t job) : m_job(job) {} + + admire::job + get() const { + return admire::job(m_job.get()); + } + + rpc_job_ptr m_job; +}; + +template <> +struct admire::unmanaged_rpc_type { + + explicit unmanaged_rpc_type(const admire::job& j) + : m_job(ADM_job_create(j.id())) {} + + ADM_job_t + get() const { + return m_job; + } + + ADM_job_t m_job; +}; + + //////////////////////////////////////////////////////////////////////////////// // Formatting functions //////////////////////////////////////////////////////////////////////////////// -- GitLab From 337e9dab0915f4bff2ff70cf7c3d5ce236dfb1bd Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Fri, 22 Jul 2022 12:20:09 +0200 Subject: [PATCH 20/25] Use conversion types in RPC submission/handling code --- src/lib/admire_types.hpp | 3 --- src/lib/c_wrapper.cpp | 8 +------- src/lib/detail/impl.cpp | 35 ++++++++++++++++++----------------- src/scord/rpc_handlers.cpp | 10 ++++++++-- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index dfcd951f..ab33fa67 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -71,9 +71,6 @@ struct job { job_id id() const; - [[nodiscard]] ADM_job_t - to_ctype() const; - private: class impl; std::unique_ptr m_pimpl; diff --git a/src/lib/c_wrapper.cpp b/src/lib/c_wrapper.cpp index 9fa83146..d0cdacf3 100644 --- a/src/lib/c_wrapper.cpp +++ b/src/lib/c_wrapper.cpp @@ -54,13 +54,7 @@ ADM_register_job(ADM_server_t server, ADM_job_requirements_t reqs, return rv.error(); } - const auto jh = ADM_job_create(rv->m_id); - - if(!jh) { - return ADM_EOTHER; - } - - *job = jh; + *job = admire::unmanaged_rpc_type{*rv}.get(); return ADM_SUCCESS; } diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index d3f4a3da..2e9472e7 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "impl.hpp" void @@ -150,9 +150,9 @@ namespace admire::detail { admire::error_code ping(const server& srv) { - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("ADM_ping()"); endp.call("ADM_ping"); @@ -161,33 +161,34 @@ ping(const server& srv) { return ADM_SUCCESS; } - tl::expected register_job(const admire::server& srv, const admire::job_requirements& reqs) { - using scord::utils::c_ptr; - using job_requirements_ptr = - c_ptr; - const auto preqs = job_requirements_ptr{reqs.to_rpc_type()}; - - scord::network::rpc_client rpc_client{srv.m_protocol, rpc_registration_cb}; + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - auto endp = rpc_client.lookup(srv.m_address); + auto endp = rpc_client.lookup(srv.address()); LOGGER_INFO("RPC ({}): {{{}}}", "ADM_register_job", reqs); - ADM_register_job_in_t in{*preqs}; + auto rpc_reqs = managed_rpc_type{reqs}; + + ADM_register_job_in_t in{*rpc_reqs.get()}; ADM_register_job_out_t out; endp.call("ADM_register_job", &in, &out); - if(out.ret < 0) { - LOGGER_ERROR("ADM_register_job() = {}", out.ret); - return tl::make_unexpected(static_cast(out.ret)); + if(out.retval < 0) { + LOGGER_ERROR("RPC ({}) = {}", "ADM_register_job", out.retval); + return tl::make_unexpected(static_cast(out.retval)); } - LOGGER_INFO("ADM_register_job() = {}", ADM_SUCCESS); - return admire::job{42}; + const auto rpc_job = managed_rpc_type{out.job}; + const admire::job job = rpc_job.get(); + + LOGGER_INFO("RPC ({}) = {{{}, job: {{{}}}}}", "ADM_register_job", + ADM_SUCCESS, job.id()); + + return job; } } // namespace admire::detail diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 0e7b208d..f74031dc 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -68,9 +68,15 @@ ADM_register_job(hg_handle_t h) { const auto id = remote_procedure::new_id(); LOGGER_INFO("RPC ID {} ({}): {{{}}}", id, __FUNCTION__, reqs); - out.ret = ADM_SUCCESS; + const auto job = admire::job{42}; - LOGGER_INFO("RPC ID {} ({}) = {}", id, __FUNCTION__, out.ret); + const auto rpc_job = admire::unmanaged_rpc_type{job}; + + out.retval = ADM_SUCCESS; + out.job = rpc_job.get(); + + LOGGER_INFO("RPC ID {} ({}) = {{{}, job: {{{}}}}}", id, __FUNCTION__, + out.retval, job); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 4baa84163367376fd3ea3c91f9c795a456d7a84a Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 15:42:19 +0200 Subject: [PATCH 21/25] admire::error_code is now a public type and has a formatting function --- src/lib/admire_types.hpp | 34 ++++++++++++++++++++++++++++++++++ src/lib/detail/impl.hpp | 4 ---- src/scord/rpc_handlers.cpp | 7 ++++--- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index ab33fa67..84274271 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -35,6 +35,8 @@ namespace admire { +using error_code = ADM_return_t; + using job_id = std::uint64_t; struct server { @@ -425,6 +427,38 @@ struct admire::unmanaged_rpc_type { // Formatting functions //////////////////////////////////////////////////////////////////////////////// +template <> +struct fmt::formatter : formatter { + // parse is inherited from formatter. + template + auto + format(const admire::error_code& ec, FormatContext& ctx) const { + std::string_view name = "unknown"; + + switch(ec) { + case ADM_SUCCESS: + name = "ADM_SUCCESS"; + break; + case ADM_ESNAFU: + name = "ADM_ESNAFU"; + break; + case ADM_EBADARGS: + name = "ADM_EBADARGS"; + break; + case ADM_ENOMEM: + name = "ADM_ENOMEM"; + break; + case ADM_EOTHER: + name = "ADM_EOTHER"; + break; + default: + break; + } + + return formatter::format(name, ctx); + } +}; + template <> struct fmt::formatter : formatter { // parse is inherited from formatter. diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index 327f1661..aecbdf26 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -29,10 +29,6 @@ #include #include -namespace admire { -using error_code = ADM_return_t; -} // namespace admire - namespace admire::detail { admire::error_code diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index f74031dc..8c235484 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -71,12 +71,13 @@ ADM_register_job(hg_handle_t h) { const auto job = admire::job{42}; const auto rpc_job = admire::unmanaged_rpc_type{job}; + admire::error_code rv = ADM_SUCCESS; - out.retval = ADM_SUCCESS; + out.retval = rv; out.job = rpc_job.get(); - LOGGER_INFO("RPC ID {} ({}) = {{{}, job: {{{}}}}}", id, __FUNCTION__, - out.retval, job); + LOGGER_INFO("RPC ID {} ({}) = {{{}, job: {{{}}}}}", id, __FUNCTION__, rv, + job); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 8b558cf832af9f3df39f76cf4109b1117fa5e44f Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 16:31:37 +0200 Subject: [PATCH 22/25] Improve logging output for ADM_register_job --- src/lib/detail/impl.cpp | 7 ++++--- src/scord/rpc_handlers.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 2e9472e7..fd5a82c4 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -168,7 +168,8 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { auto endp = rpc_client.lookup(srv.address()); - LOGGER_INFO("RPC ({}): {{{}}}", "ADM_register_job", reqs); + LOGGER_INFO("RPC (ADM_{}) => {{job_requirements: {{{}}}}}", __FUNCTION__, + reqs); auto rpc_reqs = managed_rpc_type{reqs}; @@ -178,14 +179,14 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { endp.call("ADM_register_job", &in, &out); if(out.retval < 0) { - LOGGER_ERROR("RPC ({}) = {}", "ADM_register_job", out.retval); + LOGGER_ERROR("RPC (ADM_{}) <= {}", __FUNCTION__, out.retval); return tl::make_unexpected(static_cast(out.retval)); } const auto rpc_job = managed_rpc_type{out.job}; const admire::job job = rpc_job.get(); - LOGGER_INFO("RPC ({}) = {{{}, job: {{{}}}}}", "ADM_register_job", + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}, job: {{{}}}}}", __FUNCTION__, ADM_SUCCESS, job.id()); return job; diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 8c235484..9c96e3e1 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -66,7 +66,8 @@ ADM_register_job(hg_handle_t h) { const admire::job_requirements reqs(&in.reqs); const auto id = remote_procedure::new_id(); - LOGGER_INFO("RPC ID {} ({}): {{{}}}", id, __FUNCTION__, reqs); + LOGGER_INFO("RPC ID {} ({}) <= {{job_requirements: {{{}}}}}", id, + __FUNCTION__, reqs); const auto job = admire::job{42}; @@ -76,8 +77,8 @@ ADM_register_job(hg_handle_t h) { out.retval = rv; out.job = rpc_job.get(); - LOGGER_INFO("RPC ID {} ({}) = {{{}, job: {{{}}}}}", id, __FUNCTION__, rv, - job); + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}, job: {{{}}}}}", id, + __FUNCTION__, rv, job); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 6d8f90e90c89aa8e14b586d08eff37fdec471454 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 16:31:13 +0200 Subject: [PATCH 23/25] Update ADM_update_job RPC implementation --- examples/cxx/ADM_update_job.cpp | 7 ++++++- src/common/net/proto/rpc_types.h | 11 +++++++++-- src/lib/admire.cpp | 23 +---------------------- src/lib/detail/impl.cpp | 30 ++++++++++++++++++++++++++++++ src/lib/detail/impl.hpp | 3 +++ src/scord/rpc_handlers.cpp | 12 +++++++++--- 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/examples/cxx/ADM_update_job.cpp b/examples/cxx/ADM_update_job.cpp index d034b1de..a82a2dae 100644 --- a/examples/cxx/ADM_update_job.cpp +++ b/examples/cxx/ADM_update_job.cpp @@ -27,8 +27,13 @@ main(int argc, char* argv[]) { outputs.emplace_back(fmt::format("output-dataset-{}", i)); } + auto p = std::make_unique( + admire::storage::type::gekkofs, "foobar", + admire::adhoc_storage::execution_mode::separate_new, + admire::adhoc_storage::access_type::read_write, 42, 100, false); + admire::job job{42}; - admire::job_requirements reqs{inputs, outputs}; + admire::job_requirements reqs{inputs, outputs, std::move(p)}; ADM_return_t ret = ADM_SUCCESS; try { diff --git a/src/common/net/proto/rpc_types.h b/src/common/net/proto/rpc_types.h index 937f17bf..38ecc1bc 100644 --- a/src/common/net/proto/rpc_types.h +++ b/src/common/net/proto/rpc_types.h @@ -244,9 +244,16 @@ MERCURY_GEN_PROC( ); /// ADM_update_job -MERCURY_GEN_PROC(ADM_update_job_in_t, ((int32_t) (reqs))) +MERCURY_GEN_PROC( + ADM_update_job_in_t, + ((ADM_job_t) (job)) + ((adm_job_requirements) (reqs)) +); -MERCURY_GEN_PROC(ADM_update_job_out_t, ((int32_t) (ret))) +MERCURY_GEN_PROC( + ADM_update_job_out_t, + ((int32_t) (retval)) +); /// ADM_remove_job MERCURY_GEN_PROC(ADM_remove_job_in_t, ((int32_t) (reqs))) diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 54c9f899..de2fcdcb 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -197,28 +197,7 @@ register_job(const server& srv, const job_requirements& reqs) { ADM_return_t update_job(const server& srv, const job& job, const job_requirements& reqs) { - (void) srv; - (void) job; - (void) reqs; - - scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - - auto endp = rpc_client.lookup(srv.address()); - - LOGGER_INFO("ADM_update_job(...)"); - - ADM_update_job_in_t in{}; - ADM_update_job_out_t out; - - endp.call("ADM_update_job", &in, &out); - - if(out.ret < 0) { - LOGGER_ERROR("ADM_update_job() = {}", out.ret); - return static_cast(out.ret); - } - - LOGGER_INFO("ADM_update_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; + return detail::update_job(srv, job, reqs); } ADM_return_t diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index fd5a82c4..9ea0461d 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -192,4 +192,34 @@ register_job(const admire::server& srv, const admire::job_requirements& reqs) { return job; } +admire::error_code +update_job(const server& srv, const job& job, const job_requirements& reqs) { + + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.address()); + + LOGGER_INFO("RPC ({}): {{job: {{{}}}, job_requirements: {{{}}}}}", + "ADM_update_job", job, reqs); + + const auto rpc_job = managed_rpc_type{job}; + const auto rpc_reqs = managed_rpc_type{reqs}; + + ADM_update_job_in_t in{rpc_job.get(), *rpc_reqs.get()}; + ADM_update_job_out_t out; + + endp.call("ADM_update_job", &in, &out); + + + if(out.retval < 0) { + const auto retval = static_cast(out.retval); + LOGGER_ERROR("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, + retval); + return retval; + } + + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, ADM_SUCCESS); + return ADM_SUCCESS; +} + } // namespace admire::detail diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index aecbdf26..b3262d8b 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -37,6 +37,9 @@ ping(const server& srv); tl::expected register_job(const server& srv, const job_requirements& reqs); +admire::error_code +update_job(const server& srv, const job& job, const job_requirements& reqs); + } // namespace admire::detail #endif // SCORD_ADMIRE_IMPL_HPP diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 9c96e3e1..109c64da 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -106,11 +106,17 @@ ADM_update_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job job(in.job); + const admire::job_requirements reqs(&in.reqs); - LOGGER_INFO("ADM_update_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}) <= {{job: {{{}}}, job_requirements: {{{}}}}}", + id, __FUNCTION__, job, reqs); - out.ret = 0; + admire::error_code rv = ADM_SUCCESS; + out.retval = rv; + + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}}}", id, __FUNCTION__, rv); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 66f4402ac714dd5d861bd2ade87320573c7f50ce Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 17:04:44 +0200 Subject: [PATCH 24/25] Update ADM_remove_job RPC implementation --- examples/cxx/ADM_remove_job.cpp | 20 +++++++------------- src/common/net/proto/rpc_types.h | 10 ++++++++-- src/lib/admire.cpp | 22 +--------------------- src/lib/detail/impl.cpp | 27 +++++++++++++++++++++++++++ src/lib/detail/impl.hpp | 3 +++ src/scord/rpc_handlers.cpp | 10 +++++++--- 6 files changed, 53 insertions(+), 39 deletions(-) diff --git a/examples/cxx/ADM_remove_job.cpp b/examples/cxx/ADM_remove_job.cpp index 4c2090c8..55261e99 100644 --- a/examples/cxx/ADM_remove_job.cpp +++ b/examples/cxx/ADM_remove_job.cpp @@ -5,30 +5,24 @@ int main(int argc, char* argv[]) { - if(argc != 3) { - fmt::print(stderr, "ERROR: no location provided\n"); - fmt::print(stderr, "Usage: ADM_remove_job \n"); + if(argc != 2) { + fmt::print(stderr, "ERROR: no server address provided\n"); + fmt::print(stderr, "Usage: ADM_remove_job \n"); exit(EXIT_FAILURE); } admire::server server{"tcp", argv[1]}; admire::job job{42}; - ADM_return_t ret = ADM_SUCCESS; try { - ret = admire::remove_job(server, job); + [[maybe_unused]] const auto ret = admire::remove_job(server, job); + fmt::print(stdout, "ADM_remove_job() remote procedure completed " + "successfully\n"); + exit(EXIT_SUCCESS); } catch(const std::exception& e) { - fmt::print(stderr, "FATAL: ADM_remove_job() failed: {}\n", e.what()); - exit(EXIT_FAILURE); - } - - if(ret != ADM_SUCCESS) { fmt::print(stdout, "ADM_remove_job() remote procedure not completed " "successfully\n"); exit(EXIT_FAILURE); } - - fmt::print(stdout, "ADM_remove_job() remote procedure completed " - "successfully\n"); } diff --git a/src/common/net/proto/rpc_types.h b/src/common/net/proto/rpc_types.h index 38ecc1bc..2e1139f0 100644 --- a/src/common/net/proto/rpc_types.h +++ b/src/common/net/proto/rpc_types.h @@ -256,9 +256,15 @@ MERCURY_GEN_PROC( ); /// ADM_remove_job -MERCURY_GEN_PROC(ADM_remove_job_in_t, ((int32_t) (reqs))) +MERCURY_GEN_PROC( + ADM_remove_job_in_t, + ((ADM_job_t) (job)) +); -MERCURY_GEN_PROC(ADM_remove_job_out_t, ((int32_t) (ret))) +MERCURY_GEN_PROC( + ADM_remove_job_out_t, + ((int32_t) (retval)) +); /// ADM_register_adhoc_storage MERCURY_GEN_PROC(ADM_register_adhoc_storage_in_t, ((int32_t) (reqs))) diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index de2fcdcb..9a2f74a4 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -202,27 +202,7 @@ update_job(const server& srv, const job& job, const job_requirements& reqs) { ADM_return_t remove_job(const server& srv, const job& job) { - (void) srv; - (void) job; - - scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; - - auto endp = rpc_client.lookup(srv.address()); - - LOGGER_INFO("ADM_remove_job(...)"); - - ADM_remove_job_in_t in{}; - ADM_remove_job_out_t out; - - endp.call("ADM_remove_job", &in, &out); - - if(out.ret < 0) { - LOGGER_ERROR("ADM_remove_job() = {}", out.ret); - return static_cast(out.ret); - } - - LOGGER_INFO("ADM_remove_job() = {}", ADM_SUCCESS); - return ADM_SUCCESS; + return detail::remove_job(srv, job); } ADM_return_t diff --git a/src/lib/detail/impl.cpp b/src/lib/detail/impl.cpp index 9ea0461d..b6e7d15a 100644 --- a/src/lib/detail/impl.cpp +++ b/src/lib/detail/impl.cpp @@ -222,4 +222,31 @@ update_job(const server& srv, const job& job, const job_requirements& reqs) { return ADM_SUCCESS; } +admire::error_code +remove_job(const server& srv, const job& job) { + + scord::network::rpc_client rpc_client{srv.protocol(), rpc_registration_cb}; + + auto endp = rpc_client.lookup(srv.address()); + + LOGGER_INFO("RPC (ADM_{}) => {{job: {}}}", __FUNCTION__, job); + + const auto rpc_job = managed_rpc_type{job}; + + ADM_remove_job_in_t in{rpc_job.get()}; + ADM_remove_job_out_t out; + + endp.call("ADM_remove_job", &in, &out); + + if(out.retval < 0) { + const auto retval = static_cast(out.retval); + LOGGER_ERROR("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, + retval); +return retval; + } + + LOGGER_INFO("RPC (ADM_{}) <= {{retval: {}}}", __FUNCTION__, ADM_SUCCESS); + return ADM_SUCCESS; +} + } // namespace admire::detail diff --git a/src/lib/detail/impl.hpp b/src/lib/detail/impl.hpp index b3262d8b..a047192b 100644 --- a/src/lib/detail/impl.hpp +++ b/src/lib/detail/impl.hpp @@ -40,6 +40,9 @@ register_job(const server& srv, const job_requirements& reqs); admire::error_code update_job(const server& srv, const job& job, const job_requirements& reqs); +admire::error_code +remove_job(const server& srv, const job& job); + } // namespace admire::detail #endif // SCORD_ADMIRE_IMPL_HPP diff --git a/src/scord/rpc_handlers.cpp b/src/scord/rpc_handlers.cpp index 109c64da..68677cc8 100644 --- a/src/scord/rpc_handlers.cpp +++ b/src/scord/rpc_handlers.cpp @@ -144,11 +144,15 @@ ADM_remove_job(hg_handle_t h) { ret = margo_get_input(h, &in); assert(ret == HG_SUCCESS); - out.ret = -1; + const admire::job job(in.job); - LOGGER_INFO("ADM_remove_job()"); + const auto id = remote_procedure::new_id(); + LOGGER_INFO("RPC ID {} ({}) <= {{job: {{{}}}", id, __FUNCTION__, job); - out.ret = 0; + admire::error_code rv = ADM_SUCCESS; + out.retval = rv; + + LOGGER_INFO("RPC ID {} ({}) => {{retval: {}}}", id, __FUNCTION__, rv); ret = margo_respond(h, &out); assert(ret == HG_SUCCESS); -- GitLab From 2478cf004fa31027e1aee0dfdd97ee5db13f92f1 Mon Sep 17 00:00:00 2001 From: Alberto Miranda Date: Thu, 28 Jul 2022 17:13:04 +0200 Subject: [PATCH 25/25] Rename c_ptr to ctype_ptr --- src/common/utils/CMakeLists.txt | 2 +- src/common/utils/{c_ptr.hpp => ctype_ptr.hpp} | 10 +++++----- src/lib/admire.cpp | 2 +- src/lib/admire_types.hpp | 16 ++++++++-------- src/lib/types.cpp | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) rename src/common/utils/{c_ptr.hpp => ctype_ptr.hpp} (94%) diff --git a/src/common/utils/CMakeLists.txt b/src/common/utils/CMakeLists.txt index 6f35c658..c183f012 100644 --- a/src/common/utils/CMakeLists.txt +++ b/src/common/utils/CMakeLists.txt @@ -26,4 +26,4 @@ add_library(_utils STATIC) set_property(TARGET _utils PROPERTY POSITION_INDEPENDENT_CODE ON) -target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp c_ptr.hpp) +target_sources(_utils PRIVATE utils.hpp utils.cpp signal_listener.hpp ctype_ptr.hpp) diff --git a/src/common/utils/c_ptr.hpp b/src/common/utils/ctype_ptr.hpp similarity index 94% rename from src/common/utils/c_ptr.hpp rename to src/common/utils/ctype_ptr.hpp index 7a4a4f03..830e6da8 100644 --- a/src/common/utils/c_ptr.hpp +++ b/src/common/utils/ctype_ptr.hpp @@ -43,7 +43,7 @@ struct deleter { }; template -using c_ptr = +using ctype_ptr = std::unique_ptr::type, deleter::type, fn>>; @@ -53,11 +53,11 @@ using c_ptr = // available). Can also be used to directly pass an array of C pointers to C // APIs by means of the data() function. template -struct c_ptr_vector { +struct ctype_ptr_vector { - c_ptr_vector() = default; + ctype_ptr_vector() = default; - ~c_ptr_vector() = default; + ~ctype_ptr_vector() = default; constexpr void reserve(size_t n) { @@ -87,7 +87,7 @@ struct c_ptr_vector { return m_data.size(); } - std::vector> m_data{}; + std::vector> m_data{}; std::vector m_addrs{}; }; diff --git a/src/lib/admire.cpp b/src/lib/admire.cpp index 9a2f74a4..76c29476 100644 --- a/src/lib/admire.cpp +++ b/src/lib/admire.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "detail/impl.hpp" diff --git a/src/lib/admire_types.hpp b/src/lib/admire_types.hpp index 84274271..16b9525e 100644 --- a/src/lib/admire_types.hpp +++ b/src/lib/admire_types.hpp @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "admire_types.h" namespace admire { @@ -269,7 +269,7 @@ template <> struct admire::managed_rpc_type { template - using managed_ptr = scord::utils::c_ptr; + using managed_ptr = scord::utils::ctype_ptr; explicit managed_rpc_type(const admire::adhoc_storage::ctx& ctx) : m_adhoc_context(ADM_adhoc_context_create( @@ -290,10 +290,10 @@ template <> struct admire::managed_rpc_type { template - using rpc_storage_ptr = scord::utils::c_ptr; + using rpc_storage_ptr = scord::utils::ctype_ptr; template - using managed_ptr = scord::utils::c_ptr; + using managed_ptr = scord::utils::ctype_ptr; explicit managed_rpc_type(const admire::adhoc_storage& st) : m_adhoc_context(*std::static_pointer_cast( @@ -315,7 +315,7 @@ template <> struct admire::managed_rpc_type> { template - using managed_ptr_vector = scord::utils::c_ptr_vector; + using managed_ptr_vector = scord::utils::ctype_ptr_vector; explicit managed_rpc_type(const std::vector& datasets) { m_datasets.reserve(datasets.size()); @@ -347,7 +347,7 @@ template <> struct admire::managed_rpc_type { template - using rpc_requirements_ptr = scord::utils::c_ptr; + using rpc_requirements_ptr = scord::utils::ctype_ptr; explicit managed_rpc_type(const admire::job_requirements& reqs) : m_inputs(reqs.inputs()), m_outputs(reqs.outputs()), @@ -379,7 +379,7 @@ template <> struct admire::managed_rpc_type { template - using rpc_job_ptr = scord::utils::c_ptr; + using rpc_job_ptr = scord::utils::ctype_ptr; explicit managed_rpc_type(const admire::job& j) : m_job(ADM_job_create(j.id())) {} @@ -396,7 +396,7 @@ template <> struct admire::managed_rpc_type { template - using rpc_job_ptr = scord::utils::c_ptr; + using rpc_job_ptr = scord::utils::ctype_ptr; explicit managed_rpc_type(ADM_job_t job) : m_job(job) {} diff --git a/src/lib/types.cpp b/src/lib/types.cpp index ba9f0813..9be36b09 100644 --- a/src/lib/types.cpp +++ b/src/lib/types.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "admire_types.hpp" -- GitLab