Skip to content
Open
2 changes: 1 addition & 1 deletion BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@rules_foreign_cc//tools/build_defs:configure.bzl", "configure_make")
load("@rules_foreign_cc//foreign_cc:configure.bzl", "configure_make")
# load("@rules_foreign_cc//tools/build_defs:make.bzl", "make")

configure_make(
Expand Down
9 changes: 6 additions & 3 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Rule repository
http_archive(
name = "rules_foreign_cc",
strip_prefix = "rules_foreign_cc-master",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/master.zip",
strip_prefix = "rules_foreign_cc-main",
#url = "https://github.com/bazelbuild/rules_foreign_cc/archive/master.zip",
url = "https://github.com/shiyi23/sentinel-cpp/raw/master/rules_foreign_cc-main.zip",
)

load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")
#load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")

load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")

rules_foreign_cc_dependencies()

Expand Down
Binary file added rules_foreign_cc-main.zip
Binary file not shown.
7 changes: 3 additions & 4 deletions sentinel-core/log/block/block_log_task.cc
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#include "sentinel-core/log/block/block_log_task.h"
#include "block_log_task.h"

#include <iostream>
#include <memory>
#include <thread>

#include "sentinel-core/log/logger.h"
#include "sentinel-core/utils/time_utils.h"

#include "absl/strings/str_format.h"
#include "absl/time/time.h"
#include "logger.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "statistic_time_utils.h"

using namespace Sentinel::Utils;

Expand Down
5 changes: 4 additions & 1 deletion sentinel-core/statistic/base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,14 @@ cc_library(
name = "leap_array_lib",
srcs = [
"leap_array.h",
"statistic_time_utils.h",
"statistic_time_utils.cc",
],
copts = DEFAULT_COPTS,
deps = [
":window_wrap_lib",
"//sentinel-core/log:logger_lib",
#"//sentinel-core/utils:utils_lib"
#"//sentinel-core/log:logger_lib",
]
)

Expand Down
2 changes: 1 addition & 1 deletion sentinel-core/statistic/base/bucket_leap_array.cc
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "sentinel-core/statistic/base/bucket_leap_array.h"
#include "bucket_leap_array.h"

namespace Sentinel {
namespace Stat {
Expand Down
4 changes: 2 additions & 2 deletions sentinel-core/statistic/base/bucket_leap_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <memory>

#include "sentinel-core/statistic/base/leap_array.h"
#include "sentinel-core/statistic/base/metric_bucket.h"
#include "leap_array.h"
#include "metric_bucket.h"

namespace Sentinel {
namespace Stat {
Expand Down
13 changes: 6 additions & 7 deletions sentinel-core/statistic/base/leap_array.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
#include <mutex>
#include <vector>

#include "sentinel-core/log/logger.h"
#include "sentinel-core/statistic/base/window_wrap.h"
#include "sentinel-core/utils/time_utils.h"
#include "statistic_time_utils.h"
#include "window_wrap.h"

namespace Sentinel {
namespace Stat {
Expand Down Expand Up @@ -66,7 +65,7 @@ int32_t LeapArray<T>::IntervalInMs() const {

template <typename T>
WindowWrapSharedPtr<T> LeapArray<T>::CurrentWindow() {
return this->CurrentWindow(Utils::TimeUtils::CurrentTimeMillis().count());
return this->CurrentWindow(Statistic_Utils::TimeUtils::CurrentTimeMillis().count());
}

template <typename T>
Expand Down Expand Up @@ -119,7 +118,7 @@ int64_t LeapArray<T>::CalculateWindowStart(int64_t time_millis) const {
template <typename T>
bool LeapArray<T>::IsBucketDeprecated(
const WindowWrapSharedPtr<T>& wrap) const {
return this->IsBucketDeprecated(Utils::TimeUtils::CurrentTimeMillis().count(),
return this->IsBucketDeprecated(Statistic_Utils::TimeUtils::CurrentTimeMillis().count(),
wrap);
}

Expand All @@ -131,12 +130,12 @@ bool LeapArray<T>::IsBucketDeprecated(

template <typename T>
std::vector<WindowWrapSharedPtr<T>> LeapArray<T>::Buckets() const {
return this->Buckets(Utils::TimeUtils::CurrentTimeMillis().count());
return this->Buckets(Statistic_Utils::TimeUtils::CurrentTimeMillis().count());
}

template <typename T>
std::vector<std::shared_ptr<T>> LeapArray<T>::Values() const {
return this->Values(Utils::TimeUtils::CurrentTimeMillis().count());
return this->Values(Statistic_Utils::TimeUtils::CurrentTimeMillis().count());
}

template <typename T>
Expand Down
7 changes: 6 additions & 1 deletion sentinel-core/statistic/base/metric_bucket.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <memory>

#include "sentinel-core/common/constants.h"
#include "sentinel-core/statistic/base/metric_event.h"
#include "metric_event.h"

namespace Sentinel {
namespace Stat {
Expand All @@ -19,11 +19,16 @@ class MetricBucket {
void Add(const MetricEvent& event, int64_t n);
void AddRt(int64_t rt);

inline long get_writes() { return writes_.load();};
inline long get_reads() { return reads_.load();};

private:
const std::unique_ptr<std::atomic<int64_t>[]> counters_ =
std::make_unique<std::atomic<int64_t>[]>(
static_cast<int>(MetricEvent::Count));
long min_rt_;
std::atomic<long> writes_;
std::atomic<long> reads_;

void InitMinRt();
};
Expand Down
12 changes: 12 additions & 0 deletions sentinel-core/statistic/base/statistic_time_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "statistic_time_utils.h"

namespace Sentinel {
namespace Statistic_Utils {

std::chrono::milliseconds TimeUtils::CurrentTimeMillis() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
}

} // namespace Utils
} // namespace Sentinel
16 changes: 16 additions & 0 deletions sentinel-core/statistic/base/statistic_time_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <chrono>

namespace Sentinel {
namespace Statistic_Utils {

class TimeUtils {
public:
TimeUtils() = delete;

static std::chrono::milliseconds CurrentTimeMillis();
};

} // namespace Utils
} // namespace Sentinel
19 changes: 14 additions & 5 deletions sentinel-core/statistic/base/window_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ class WindowWrap {
int64_t BucketStart() const;
std::shared_ptr<T> Value() const;

void ResetTo(int64_t start_time);
inline void ResetTo(int64_t start_time)
{
bucket_start_ = start_time;
}
bool IsTimeInBucket(int64_t time_millis) const;

private:
Expand All @@ -44,12 +47,18 @@ std::shared_ptr<T> WindowWrap<T>::Value() const {
return value_;
}

template <typename T>
void WindowWrap<T>::ResetTo(int64_t start_time) {
this->bucket_start_ = start_time;
}
//template <typename T>
//void WindowWrap<T>::ResetTo(int64_t start_time) {
// this->bucket_start_ = start_time;
//}

template <typename T>
/**
* Check whether given timestamp is in current bucket.
*
* @param time_millis valid timestamp in ms
* @return true if the given time is in current bucket, otherwise false
* */
bool WindowWrap<T>::IsTimeInBucket(int64_t time_millis) const {
return bucket_start_ <= time_millis &&
time_millis < bucket_start_ + bucket_length_ms_;
Expand Down
3 changes: 2 additions & 1 deletion sentinel-core/statistic/node/statistic_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ bool StatisticNode::IsNodeInTime(const MetricItemSharedPtr& item,
}

std::unordered_map<long, MetricItemSharedPtr> StatisticNode::Metrics() {
int64_t cur_time = Utils::TimeUtils::CurrentTimeMillis().count();
using Sentinel::Statistic_Utils;
int64_t cur_time = Sentinel::Statistic_Utils::TimeUtils::CurrentTimeMillis().count();
cur_time = cur_time - cur_time % 1000;
std::unordered_map<long, MetricItemSharedPtr> map;
std::vector<MetricItemSharedPtr> items_of_second =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ std::shared_ptr<StatisticNodeVO> StatisticNodeVO::FromResourceNode(
vo->set_block_per_min(node->BlockCountInMinute());
vo->set_total_per_min(node->TotalCountInMinute());
vo->set_exception_per_min(node->ExceptionCountInMinute());
vo->set_timestamp(Utils::TimeUtils::CurrentTimeMillis().count());
vo->set_timestamp(Sentinel::Statistic_Utils::TimeUtils::CurrentTimeMillis().count());
return vo;
}

Expand Down
6 changes: 6 additions & 0 deletions sentinel-core/utils/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ cc_library(
"time_utils.cc",
],
copts = DEFAULT_COPTS,
deps = [
"//sentinel-core/statistic/base:leap_array_lib",
"//sentinel-core/statistic/base:bucket_leap_array_lib",
"//sentinel-core/statistic/base:metric_bucket_lib",
"//sentinel-core/statistic/base:window_wrap_lib",
]
)


Expand Down
137 changes: 136 additions & 1 deletion sentinel-core/utils/time_utils.cc
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
#include "sentinel-core/utils/time_utils.h"
#include "time_utils.h"

#include <iostream>

/**
* <p>Provides millisecond-level time of OS.</p>
* <p>
* Here we should see that not all the time TimeUtil should
* keep looping 1_000 times every second (Actually about 800/s due to some losses).
* <pre>
* * In idle conditions it just acts as System.currentTimeMillis();
* * In busy conditions (significantly more than 1_000/s) it keeps loop to reduce costs.
* </pre>
* For detail design and proposals please goto
* <a href="https://github.com/alibaba/Sentinel/issues/1702#issuecomment-692151160">https://github.com/alibaba/Sentinel/issues/1702</a>
* @author alibaba.com
* @author huangshiyi
* */

namespace Sentinel {
namespace Utils {
Expand All @@ -8,5 +25,123 @@ std::chrono::milliseconds TimeUtils::CurrentTimeMillis() {
std::chrono::system_clock::now().time_since_epoch());
}

TimeUtils::TimeUtils()
{
// statistics_ = new Stat::BucketLeapArray(3, 3000);
currentTimeMillis_ = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
std::thread t(&TimeUtils::Run, this);
t.detach();
}

void TimeUtils::Run()
{
while(true)
{
this->Check();
if(this->state_ == STATE::RUNNING)
{
this->currentTimeMillis_ = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
this->statistics_->CurrentWindow(currentTimeMillis_.count())->Value()->get_writes().fetch_add(1);
try {
usleep(1000);//1000 microseconds = 1ms
} catch (std::exception e)
{
throw e.what();
}
continue ;
}

if(this->state_ == STATE::IDLE)
{
try {
usleep(300000);//300000 micro seconds = 300 ms
} catch (std::exception e)
{
throw e.what();
}
continue ;
}

if(this->state_ == STATE::PREPARE)
{
//TODO:should print debug level log info here, but I don't have too much time now
std::cout << "TimeUtils switches to RUNNING" << std::endl;
this->currentTimeMillis_ = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
this->state_ = STATE::RUNNING;
}

}
}

void TimeUtils::Check()
{
std::chrono::milliseconds now = this->CurrentTime(true);
//every period
if(now - this->last_check_ < CHECK_INTERVAL_)
{
return ;
}
this->last_check_ = now;
std::pair<long, long> qps = this->get_current_qps(now);
if(this->state_ == STATE::IDLE && qps.first > HITS_UPPER_BOUNDARY_)
{
std::cout << "TimeUtil switches to PREPARE for better performance, "
"reads= << " << qps.first << "writes= << " << qps.second << std::endl;
this->state_ = STATE::PREPARE;
} else if(this->state_ == STATE::RUNNING && qps.first < HITS_LOWER_BOUNDARY_)
{
std::cout << "TimeUtil switches to IDLE due to not enough load, "
"reads= " << qps.first << "writes= " << qps.second <<std::endl;
this->state_ = STATE::IDLE;
}
}

std::pair<long, long> TimeUtils::get_current_qps(std::chrono::milliseconds now)
{
auto vec = this->statistics_->Buckets();
long reads = 0, writes = 0;
int cnt = 0;
for (auto const elem : vec)
{
if (elem->IsTimeInBucket(now.count()))
{
continue ;
}
++ cnt;
reads += elem->Value()->get_reads().load();
writes += elem->Value()->get_writes().load();
if (cnt < 1)
{
return std::make_pair(0,0);
}
}
return std::make_pair(reads/cnt, writes/cnt);
}

std::chrono::milliseconds TimeUtils::CurrentTime(bool inner_call)
{
auto now = this->currentTimeMillis_;
auto val = this->statistics_->CurrentWindow()->Value();
if(!inner_call)
{
//external call
val->get_reads().fetch_add(1);
}
if(this->state_ == STATE::IDLE || this->state_ == STATE::PREPARE)
{
now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch());
this->currentTimeMillis_ = now; //cache time
if(!inner_call)
{
val->get_writes().fetch_add(1);
}
}
return now;
}

} // namespace Utils
} // namespace Sentinel
Loading