blob: dd712414f2e152b2002058ff0a6e44e05a6327f7 [file] [log] [blame]
#ifndef PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_PERSISTENT_STORAGE_IMPL_H_
#define PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_PERSISTENT_STORAGE_IMPL_H_
#include <cstdint>
#include <string>
#include <vector>
#include "persistent_storage.h"
#include "safepower_agent_config.pb.h"
#include "state_persistence.pb.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
namespace persistent_storage {
constexpr std::uintmax_t kMaxFileSize = 16384; // 16 k
constexpr absl::string_view kDefaultPath =
"/var/google/gPowerD/SavedActions";
constexpr uint32_t kProtoKeepNumber = 10;
constexpr absl::string_view kfileNamePrefix = "savedactions";
class PersistentStorageManagerImpl
: public safepower_agent::PersistentStorageManager {
public:
explicit PersistentStorageManagerImpl(
const safepower_agent_config::PersistentStorageConfig& config =
safepower_agent_config::PersistentStorageConfig::default_instance());
~PersistentStorageManagerImpl() override = default;
// Writes a delta to the saved actions to persistent storage.
absl::Status WriteSavedActionsChange(
const safepower_agent_persistence_proto::SavedActions& actions) override;
absl::Status WriteSavedActionsChange(
const safepower_agent_persistence_proto::SavedActions& actions,
absl::string_view dir_path);
// Reads all saved actions from persistent storage.
absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
ReadSavedActions() override;
absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
ReadSavedActions(absl::string_view dir_path);
absl::Status InitializeSavedActions() override;
private:
struct FlightRecordHash {
std::size_t operator()(
const borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest&
flight_record) const {
return absl::HashOf(std::make_pair(flight_record.flight_name(),
flight_record.step_id()));
}
};
struct FlightRecordEq {
bool operator()(
const borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest& lhs,
const borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest& rhs)
const {
return lhs.flight_name() == rhs.flight_name() &&
lhs.step_id() == rhs.step_id();
}
};
absl::Status ConvertAppendToMap(
absl::flat_hash_map<
borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest,
safepower_agent_persistence_proto::SavedAction, FlightRecordHash,
FlightRecordEq>& map,
const safepower_agent_persistence_proto::SavedActions& saved_actions);
// keep the most recent protos is called when the size of the saved files is
// larger then the kmaxFileSize. In the event of large protos we will always
// have at least kProtoKeepNumber of messages. That garuantees was more
// important then miniziains the file size. From a design perspective it would
// be ideal if kMaxFileSize was reached at 2*kProtoKeepNumber, but that is not
// necessary.
absl::Status keepMostRecentProtos(
absl::flat_hash_map<
borg_mgmt::node_proxy::safepower::utils::FlightRecordRequest,
safepower_agent_persistence_proto::SavedAction, FlightRecordHash,
FlightRecordEq>& map);
absl::StatusOr<uint64_t> findLargestFileId(
absl::Span<const std::string> files);
absl::StatusOr<std::vector<std::string> > listFiles(
absl::string_view file_path);
absl::Status deleteAllFilesExceptLargest(absl::string_view file_path);
std::string MakeFileName(absl::string_view file_path, uint64_t file_id);
absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
CompressLogs(const safepower_agent_persistence_proto::SavedActions&
saved_actions);
std::string dir_path_{kDefaultPath};
std::uintmax_t max_file_size_ = kMaxFileSize;
uint32_t proto_keep_number_ = kProtoKeepNumber;
};
} // namespace persistent_storage
#endif // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_PERSISTENT_STORAGE_IMPL_H_