SharedStorage/client.cpp
2025-04-27 16:32:10 +00:00

188 lines
6.0 KiB
C++

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <iostream>
#include <cstring>
#include <thread>
#include <chrono>
#include <sys/stat.h>
#include "core/SharedCommandQueue.h"
#include "utils/hash/Hash128.h"
// int main()
// {
// constexpr const char* shm_name = "/shm_rates1";
// constexpr size_t shm_size = sizeof(usub::core::SharedCommandQueue);
//
// int shm_fd = shm_open(shm_name, O_RDWR, 0600);
// if (shm_fd == -1)
// {
// perror("shm_open failed");
// return 1;
// }
//
// void* ptr = mmap(nullptr, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
// if (ptr == MAP_FAILED)
// {
// perror("mmap failed");
// close(shm_fd);
// return 1;
// }
//
// auto* queue = static_cast<usub::core::SharedCommandQueue*>(ptr);
// std::cout << "[CLIENT] Connected to shared memory.\n";
//
// size_t head = queue->head().load(std::memory_order_relaxed);
// size_t next_head = (head + 1) % queue->capacity();
// while (next_head == queue->tail().load(std::memory_order_acquire))
// {
// std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait
// }
//
// usub::core::Command* slot = &queue->raw_buffer()[head];
//
// // заполняем slot
// slot->op = usub::core::OperationType::PUT;
// slot->key = usub::utils::compute_hash128("test_key", 9);
// const char* put_value = "test_value";
// slot->value_size = std::strlen(put_value);
// std::memcpy(slot->value, put_value, slot->value_size);
// slot->response_size = 0;
// slot->response_ready.store(0, std::memory_order_relaxed);
//
// slot->ready.store(1, std::memory_order_release);
//
// // обновляем head
// queue->head().store(next_head, std::memory_order_release);
//
// std::cout << "[CLIENT] PUT command sent.\n";
//
// // Ожидание, можно реализовать FIND аналогично.
//
// munmap(ptr, shm_size);
// close(shm_fd);
//
// return 0;
// }
int main()
{
constexpr const char* shm_name = "/shm_rates1";
constexpr size_t capacity = 1024; // или то, что реально
size_t shm_size = usub::core::SharedCommandQueue::calculate_shm_size(capacity);
int shm_fd = shm_open(shm_name, O_RDWR, 0600);
if (shm_fd == -1)
{
perror("shm_open failed");
return 1;
}
// struct stat statbuf;
// if (fstat(shm_fd, &statbuf) == -1)
// {
// perror("fstat failed");
// close(shm_fd);
// return 1;
// }
// void* ptr = mmap(nullptr, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
void* ptr = mmap(nullptr, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED)
{
perror("mmap failed");
close(shm_fd);
return 1;
}
auto* queue = static_cast<usub::core::SharedCommandQueue*>(ptr);
std::cout << "[CLIENT] Connected to shared memory.\n";
// -------------------
// PUT Command
// -------------------
{
std::cout << "1\n";
auto head = queue->head().load(std::memory_order_relaxed);
size_t next_head = (head + 1) % queue->capacity();
while (next_head == queue->tail().load(std::memory_order_acquire))
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
std::cout << "2\n";
usub::core::Command* slot = &queue->raw_buffer()[head];
std::cout << "queue = " << queue << '\n';
std::cout << "queue->capacity() = " << queue->capacity() << '\n';
std::cout << "head = " << head << '\n';
std::cout << "ptr to raw_buffer = " << static_cast<void*>(queue->raw_buffer()) << '\n';
std::cout << "ptr to slot = " << static_cast<void*>(&queue->raw_buffer()[head]) << '\n';
std::cout.flush();
slot->op = usub::core::OperationType::PUT;
slot->key = usub::utils::compute_hash128("test_key", 8); // исправил длину "test_key" = 8 символов
const char* put_value = "test_value";
slot->value_size = std::strlen(put_value);
std::cout << "3\n";
std::memcpy(slot->value, put_value, slot->value_size);
std::cout << "4\n";
slot->response_size = 0;
slot->response_ready.store(0, std::memory_order_relaxed);
slot->ready.store(1, std::memory_order_release);
queue->head().store(next_head, std::memory_order_release);
std::cout << "[CLIENT] PUT command sent.\n";
}
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // дать серверу время
// -------------------
// FIND Command
// -------------------
{
size_t head = queue->head().load(std::memory_order_relaxed);
size_t next_head = (head + 1) % queue->capacity();
while (next_head == queue->tail().load(std::memory_order_acquire))
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
usub::core::Command* slot = &queue->raw_buffer()[head];
slot->op = usub::core::OperationType::FIND;
slot->key = usub::utils::compute_hash128("test_key", 8);
slot->value_size = 0;
slot->response_size = 0;
slot->response_ready.store(0, std::memory_order_relaxed);
slot->ready.store(1, std::memory_order_release);
queue->head().store(next_head, std::memory_order_release);
std::cout << "[CLIENT] FIND command sent.\n";
// Ожидание ответа
while (slot->response_ready.load(std::memory_order_acquire) == 0)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
if (slot->response_size > 0)
{
std::string result(reinterpret_cast<char*>(slot->response), slot->response_size);
std::cout << "[CLIENT] FIND result: " << result << "\n";
}
else
{
std::cout << "[CLIENT] FIND result: not found\n";
}
}
munmap(ptr, shm_size);
close(shm_fd);
return 0;
}