yalantinglibs/include/ylt/standalone/cinatra/session_manager.hpp

106 lines
2.6 KiB
C++

#pragma once
#include <asio/steady_timer.hpp>
#include <atomic>
#include <chrono>
#include <string>
#include "session.hpp"
#include "ylt/coro_io/coro_io.hpp"
namespace cinatra {
class session_manager {
public:
static session_manager &get() {
static session_manager instance;
return instance;
}
std::string generate_session_id() {
auto tp = std::chrono::high_resolution_clock::now();
auto nano = tp.time_since_epoch().count();
id_++;
return std::to_string(nano).append(std::to_string(id_));
}
std::shared_ptr<session> get_session(const std::string &session_id) {
std::unique_lock<std::mutex> lock(mtx_);
std::shared_ptr<session> new_session = nullptr;
auto iter = map_.find(session_id);
if (iter != map_.end()) {
return iter->second;
}
else {
new_session =
std::make_shared<session>(session_id, session_timeout_, true);
map_.insert({session_id, new_session});
}
return new_session;
}
void remove_expire_session() {
std::unique_lock<std::mutex> lock(mtx_);
auto now = std::time(nullptr);
for (auto it = map_.begin(); it != map_.end();) {
if (it->second->get_time_stamp() <= now)
it = map_.erase(it);
else
++it;
}
}
bool check_session_existence(const std::string &session_id) {
std::unique_lock<std::mutex> lock(mtx_);
return map_.find(session_id) != map_.end();
}
void start_check_session_timer() {
check_session_timer_.expires_after(check_session_duration_);
check_session_timer_.async_wait([this](auto ec) {
if (ec || stop_timer_) {
return;
}
remove_expire_session();
start_check_session_timer();
});
}
void set_check_session_duration(auto duration) {
check_session_duration_ = duration;
start_check_session_timer();
}
void stop_timer() {
stop_timer_ = true;
std::error_code ec;
check_session_timer_.cancel(ec);
}
private:
session_manager()
: check_session_timer_(
coro_io::get_global_executor()->get_asio_executor()) {
start_check_session_timer();
};
session_manager(const session_manager &) = delete;
session_manager(session_manager &&) = delete;
std::atomic_int64_t id_ = 0;
std::unordered_map<std::string, std::shared_ptr<session>> map_;
std::mutex mtx_;
// session_timeout_ should be no less than 0
std::size_t session_timeout_ = 86400;
std::atomic<bool> stop_timer_ = false;
asio::steady_timer check_session_timer_;
std::chrono::steady_clock::duration check_session_duration_ =
std::chrono::seconds(15);
};
} // namespace cinatra