MCPcopy Create free account
hub / github.com/apache/brpc / Index

Method Index

src/brpc/span.cpp:692–805  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

690}
691
692leveldb::Status SpanDB::Index(std::shared_ptr<const Span> span, std::string* value_buf) {
693 leveldb::WriteOptions options;
694 options.sync = false;
695
696 leveldb::Status st;
697
698 // NOTE: Writing into time_db before id_db so that if the second write
699 // fails, the entry in time_db will be finally removed when it's out
700 // of time window.
701
702 const int64_t start_time = span->GetStartRealTimeUs();
703 const int64_t latency_us = span->GetEndRealTimeUs() - start_time;
704 // if latency_us < FLAGS_rpcz_save_span_min_latency_us, don't save this span
705 if (latency_us < FLAGS_rpcz_save_span_min_latency_us) {
706 return leveldb::Status::OK();
707 }
708 BriefSpan brief;
709 brief.set_trace_id(span->trace_id());
710 brief.set_span_id(span->span_id());
711 brief.set_log_id(span->log_id());
712 brief.set_type(span->type());
713 brief.set_error_code(span->error_code());
714 brief.set_request_size(span->request_size());
715 brief.set_response_size(span->response_size());
716 brief.set_start_real_us(start_time);
717 brief.set_latency_us(latency_us);
718 brief.set_full_method_name(span->full_method_name());
719 if (!brief.SerializeToString(value_buf)) {
720 return leveldb::Status::InvalidArgument(
721 leveldb::Slice("Fail to serialize BriefSpan"));
722 }
723 // We need to make the time monotonic otherwise if older entries are
724 // overwritten by newer ones, entries in id_db associated with the older
725 // entries are not evicted. Surely we can call DB::Get() before Put(), but
726 // that would be too slow due to the storage model of leveldb. One feasible
727 // method is to maintain recent window of keys to time_db, when there's a
728 // conflict before Put(), try key+1us until an unused time is found. The
729 // window could be 5~10s. However this method needs a std::map(slow) or
730 // hashmap+queue(more memory: remember that we're just a framework), and
731 // this method can't guarantee no duplication when real time goes back
732 // significantly.
733 // Since the time to this method is ALMOST in ascending order, we use a
734 // very simple strategy: if the time is not greater than last-time, set
735 // it to be last-time + 1us. This works when time goes back because the
736 // real time is at least 1000000 / FLAGS_rpcz_max_span_per_second times faster
737 // and it will finally catch up with our time key. (provided the flag
738 // is less than 1000000).
739 int64_t time_key = start_time;
740 if (time_key <= g_last_time_key) {
741 time_key = g_last_time_key + 1;
742 }
743 g_last_time_key = time_key;
744 uint32_t time_data[2];
745 ToBigEndian(time_key, time_data);
746 st = time_db->Put(options,
747 leveldb::Slice((char*)time_data, sizeof(time_data)),
748 leveldb::Slice(value_buf->data(), value_buf->size()));
749 if (!st.ok()) {

Callers 1

dump_to_dbMethod · 0.80

Calls 15

ToBigEndianFunction · 0.85
Span2ProtoFunction · 0.85
GetStartRealTimeUsMethod · 0.80
GetEndRealTimeUsMethod · 0.80
set_error_codeMethod · 0.80
set_request_sizeMethod · 0.80
request_sizeMethod · 0.80
set_response_sizeMethod · 0.80
response_sizeMethod · 0.80
okMethod · 0.80
is_activeMethod · 0.80
trace_idMethod · 0.45

Tested by

no test coverage detected