Verified Commit b38815c3 authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Update API

- Add `transfer_state` enum with appropriate values for a transfer
  current status.
- Add `transfer_status` class with functions `state()`, `done()`,
  `failed()` and `error()` to retrieve a transfer's current status and
  its associated error condition in case of failure.
- Extend the `transfer` class with functions `wait()`, and `wait_for()`,
  to wait for the completion of a transfer request.
- Add new error codes: `no_such_transfer` and `transfer_in_progress`.
- Add new formatters: `transfer_state` and `std::optional<T>`.
- Add new API function: `transfer_dataset` as a convenience function to
  request the transfer of a single dataset.
parent da0fdcfa
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ target_link_libraries(cargo PRIVATE
        MPI::MPI_CXX
        Boost::serialization
        Boost::mpi
        net::rpc_client
)

## Install library + targets ###################################################
+106 −8
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include <string>
#include <vector>
#include <chrono>
#include <cargo/error.hpp>

namespace cargo {
@@ -85,28 +86,111 @@ private:
};


/**
 * The status of a Cargo transfer
 */
enum class transfer_state { pending, running, completed, failed };

class transfer_status;

/**
 * A transfer handler
 */
class transfer {

public:
    transfer() noexcept = default;
    explicit transfer(transfer_id id) noexcept;
    friend transfer
    transfer_datasets(const server& srv, const std::vector<dataset>& sources,
                      const std::vector<dataset>& targets);

    explicit transfer(transfer_id id, server srv) noexcept;

    [[nodiscard]] transfer_id
    id() const noexcept;

    template <typename Archive>
    void
    serialize(Archive& ar) {
        ar & m_id;
    }
public:
    /**
     * Get the current status of the associated transfer.
     *
     * @return A `transfer_status` object containing detailed information about
     * the transfer status.
     */
    [[nodiscard]] transfer_status
    status() const;

    /**
     * Wait for the associated transfer to complete.
     *
     * @return A `transfer_status` object containing detailed information about
     * the transfer status.
     */
    [[nodiscard]] transfer_status
    wait() const;

    /**
     * Wait for the associated transfer to complete or for a timeout to occur.
     * @param timeout The maximum amount of time to wait for the transfer to
     * complete.
     * @return A `transfer_status` object containing detailed information about
     * the transfer status.
     */
    [[nodiscard]] transfer_status
    wait_for(const std::chrono::nanoseconds& timeout) const;

private:
    transfer_id m_id;
    server m_srv;
};

/**
 * Detailed status information for a transfer
 */
class transfer_status {

    friend transfer_status
    transfer::status() const;

    transfer_status(transfer_state status, error_code error) noexcept;

public:
    /**
     * Get the current status of the associated transfer.
     *
     * @return A `transfer_state` enum value representing the current status.
     */
    [[nodiscard]] transfer_state
    state() const noexcept;

    /**
     * Check whether the transfer has completed.
     *
     * @return true if the transfer has completed, false otherwise.
     */
    [[nodiscard]] bool
    done() const noexcept;

    /**
     * Check whether the transfer has failed.
     *
     * @return true if the transfer has failed, false otherwise.
     */
    [[nodiscard]] bool
    failed() const noexcept;

    /**
     * Retrieve the error code associated with a failed transfer.
     *
     * @return An error code describing a transfer failure or
     * `error_code::success` if the transfer succeeded.
     * If the transfer has not yet completed,
     * `error_code::transfer_in_progress` is returned.
     */
    [[nodiscard]] error_code
    error() const;

private:
    transfer_state m_state;
    error_code m_error;
};

/**
 * Request the transfer of a dataset collection.
@@ -120,6 +204,20 @@ transfer
transfer_datasets(const server& srv, const std::vector<dataset>& sources,
                  const std::vector<dataset>& targets);

/**
 * Request the transfer of a single dataset.
 * This function is a convenience wrapper around the previous one.
 * It takes a single source and a single target dataset.
 *
 * @param srv The Cargo server that should execute the transfer.
 * @param source The input dataset that should be transferred.
 * @param target The output dataset that should be generated.
 * @return A transfer
 */
transfer
transfer_dataset(const server& srv, const dataset& source,
                 const dataset& target);

} // namespace cargo

#endif // CARGO_HPP
+9 −1
Original line number Diff line number Diff line
@@ -41,13 +41,17 @@ class error_code {
    enum class error_value : std::uint32_t {
        success = 0,
        snafu = 1,
        not_implemented = 2
        not_implemented = 2,
        no_such_transfer = 3,
        transfer_in_progress = 4,
    };

public:
    static const error_code success;
    static const error_code snafu;
    static const error_code not_implemented;
    static const error_code no_such_transfer;
    static const error_code transfer_in_progress;

    constexpr error_code() : error_code(error_value::success) {}
    constexpr explicit error_code(error_value v)
@@ -91,6 +95,10 @@ private:
constexpr error_code error_code::success{error_value::success};
constexpr error_code error_code::snafu{error_value::snafu};
constexpr error_code error_code::not_implemented{error_value::not_implemented};
constexpr error_code error_code::no_such_transfer{
        error_value::no_such_transfer};
constexpr error_code error_code::transfer_in_progress{
        error_value::transfer_in_progress};

static constexpr cargo::error_code
make_system_error(std::uint32_t ec) {
+8 −0
Original line number Diff line number Diff line
@@ -277,6 +277,10 @@ error_code::name() const {
            return "CARGO_SNAFU";
        case error_value::not_implemented:
            return "CARGO_NOT_IMPLEMENTED";
        case error_value::no_such_transfer:
            return "CARGO_NO_SUCH_TRANSFER";
        case error_value::transfer_in_progress:
            return "CARGO_TRANSFER_IN_PROGRESS";
        default:
            return "CARGO_UNKNOWN_ERROR";
    }
@@ -294,6 +298,10 @@ error_code::message() const {
                    return "snafu";
                case error_value::not_implemented:
                    return "not implemented";
                case error_value::no_such_transfer:
                    return "no such transfer";
                case error_value::transfer_in_progress:
                    return "transfer in progress";
                default:
                    return "unknown error";
            }
+34 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include <iomanip>
#include <string_view>
#include <optional>
#include <fmt/format.h>
#include "cargo/error.hpp"

@@ -80,4 +81,37 @@ struct fmt::formatter<cargo::error_code> : formatter<std::string_view> {
    }
};

template <>
struct fmt::formatter<cargo::transfer_state> : formatter<std::string_view> {
    // parse is inherited from formatter<string_view>.
    template <typename FormatContext>
    auto
    format(const cargo::transfer_state& s, FormatContext& ctx) const {
        switch(s) {
            case cargo::transfer_state::pending:
                return formatter<std::string_view>::format("pending", ctx);
            case cargo::transfer_state::running:
                return formatter<std::string_view>::format("running", ctx);
            case cargo::transfer_state::completed:
                return formatter<std::string_view>::format("completed", ctx);
            case cargo::transfer_state::failed:
                return formatter<std::string_view>::format("failed", ctx);
            default:
                return formatter<std::string_view>::format("unknown", ctx);
        }
    }
};

template <typename T>
struct fmt::formatter<std::optional<T>> : formatter<std::string_view> {
    // parse is inherited from formatter<string_view>.
    template <typename FormatContext>
    auto
    format(const std::optional<T>& v, FormatContext& ctx) const {
        return formatter<std::string_view>::format(
                v ? fmt::format("{}", v.value()) : "none", ctx);
    }
};


#endif // CARGO_FMT_FORMATTERS_HPP
Loading