blob: 636537b7dbb765b6199dce05b3e421d9d6f1b522 [file]
#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 <optional>
#include <string>
#include <vector>
#include "flight_record.h"
#include "persistent_storage.h"
#include "safepower_agent_config.pb.h"
#include "state_persistence.pb.h"
#include "utils.pb.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/hash/hash.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.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_LOCKS_EXCLUDED(mu_);
// Reads all saved actions from persistent storage.
absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
ReadSavedActions() override ABSL_LOCKS_EXCLUDED(mu_);
absl::Status InitializeSavedActions() override ABSL_LOCKS_EXCLUDED(mu_);
private:
absl::Status ConvertAppendToMap(
absl::flat_hash_map<safepower_agent::FlightRecordWrapper,
safepower_agent_persistence_proto::SavedAction>& 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<safepower_agent::FlightRecordWrapper,
safepower_agent_persistence_proto::SavedAction>& map)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
std::optional<uint64_t> findLargestFileId(absl::Span<const std::string> files)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
absl::StatusOr<std::vector<std::string> > listFiles(
absl::string_view file_path) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
struct ActiveFileInfo {
uint64_t id = 0;
int64_t sequence_number = 0;
bool exists = false;
safepower_agent_persistence_proto::SavedActions proto;
};
absl::StatusOr<ActiveFileInfo> GetActiveFileInfo()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
absl::StatusOr<ActiveFileInfo> GetFileInfo(uint64_t id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
absl::StatusOr<safepower_agent_persistence_proto::SavedActions>
ReadProtoForId(uint64_t file_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
absl::Status DeleteOldFiles() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
std::string MakeFileName(uint64_t file_id);
std::string MakeFilePath(absl::string_view dir_path, uint64_t file_id);
absl::StatusOr<safepower_agent_persistence_proto::SavedActions> CompressLogs(
const safepower_agent_persistence_proto::SavedActions& saved_actions,
bool prune = false) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
std::string dir_path_ ABSL_GUARDED_BY(mu_){kDefaultPath};
std::uintmax_t max_file_size_ ABSL_GUARDED_BY(mu_) = kMaxFileSize;
uint32_t proto_keep_number_ ABSL_GUARDED_BY(mu_) = kProtoKeepNumber;
absl::Mutex mu_;
};
} // namespace persistent_storage
#endif // PRODUCTION_BORG_MGMT_NODE_PROXY_SAFEPOWER_SAFEPOWER_AGENT_PERSISTENT_STORAGE_IMPL_H_