blob: 3dc0844def0befab09a0d30b688934c328fcff66 [file] [log] [blame]
#include "tlbmc/hal/shared_mem/server.h"
#include <cstdint>
#include <filesystem> // NOLINT
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include "absl/base/no_destructor.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "tlbmc/hal/shared_mem/metrics.h"
#include "tlbmc/hal/shared_mem/segment_manager.h"
#include "tlbmc/hal/shared_mem/sensors.h"
namespace milotic_tlbmc {
void SharedMemoryServer::Initialize() { return Initialize(""); }
void SharedMemoryServer::SetUpInstanceForUnitTest() {
// Remove the shared memory object and the initialized file to ensure a clean
// state for unit tests.
if (!boost::interprocess::shared_memory_object::remove("TlbmcSharedMemory")) {
LOG(WARNING) << "Shared memory object not removed successfully.";
} else {
LOG(INFO) << "Shared memory object removed successfully.";
}
if (!std::filesystem::remove("/tmp/tlbmc/tlbmc_shared_memory")) {
LOG(WARNING) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory "
"was not removed successfully.";
} else {
LOG(INFO) << "Shared memory flag file /tmp/tlbmc/tlbmc_shared_memory was "
"removed.";
}
GetInstance("/tmp/tlbmc/tlbmc_shared_memory");
}
void SharedMemoryServer::Initialize(const std::string& initialized_file_path) {
SharedMemoryServer::GetInstance(initialized_file_path);
}
IpcServer& SharedMemoryServer::GetInstance(
const std::string& initialized_file_path) {
static absl::NoDestructor<SharedMemoryServer> instance(
Token(), initialized_file_path,
initialized_file_path.empty()
? SegmentManager::Create()
: SegmentManager::Create(initialized_file_path));
return *instance;
}
IpcServer& SharedMemoryServer::GetInstance() { return GetInstance(""); }
SharedMemoryServer::SharedMemoryServer(
Token token, const std::string& initialized_file_path,
std::unique_ptr<SegmentManager> segment_manager)
: initialized_file_path_(std::string{initialized_file_path}),
segment_manager_(std::move(segment_manager)),
metrics_(segment_manager_ == nullptr
? nullptr
: segment_manager_->GetOrCreateMetrics()) {
if (segment_manager_ == nullptr) {
LOG(FATAL) << "SharedMemoryServer segment_manager is nullptr. This should "
"never happen in server side. Check the initialization log.";
}
}
SharedMemoryServer::SharedMemoryServer(
const std::string& initialized_file_path,
std::unique_ptr<SegmentManager> segment_manager)
: SharedMemoryServer(Token(), initialized_file_path,
std::move(segment_manager)) {}
IpcSensor* SharedMemoryServer::GetSensor(const std::string& sensor_name) {
absl::MutexLock lock(&sensors_mutex_);
auto it = sensors_.find(sensor_name);
if (it != sensors_.end()) {
return it->second;
}
DLOG(INFO) << "SharedMemoryServer segment_manager: "
<< segment_manager_.get();
IpcSensor* sensor = segment_manager_->GetOrCreateSensor(sensor_name.c_str());
DLOG(INFO) << "SharedMemoryServer sensor for " << sensor_name << ": "
<< sensor;
sensors_[sensor_name] = sensor;
return sensor;
}
absl::StatusOr<std::pair<float, uint64_t>> SharedMemoryServer::ReadSensorValue(
const std::string& sensor_name) {
IpcSensor* sensor = GetSensor(sensor_name);
if (sensor == nullptr) {
return absl::InternalError(
"Failed to get sensor. This normally should not happen.");
}
std::pair<float, uint64_t> value = sensor->GetValue();
// If the sensor value is not updated by the client, the value will be set to
// infinity and the timestamp will be 0.
if (value.first == std::numeric_limits<float>::infinity() ||
value.second == 0) {
return absl::UnavailableError(
"Sensor value is still invalid due to no update from client.");
}
return value;
}
// copybara:strip_begin(g3-shared-libs)
void SharedMemoryServer::UpdateMetricsRequestCount(bool is_tlbmc_request) {
if (metrics_ == nullptr) {
return;
}
metrics_->UpdateMetricsRequestCount(is_tlbmc_request);
}
void SharedMemoryServer::UpdateMetricsResponse(absl::Duration response_time,
int status_code,
std::string_view resource_url) {
if (metrics_ == nullptr) {
return;
}
metrics_->UpdateMetricsResponse(response_time, status_code, resource_url);
}
// copybara:strip_end
} // namespace milotic_tlbmc