opencensus-cpp-shutdown-api.patch 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. diff --git a/opencensus/exporters/stats/prometheus/internal/prometheus_exporter.cc b/opencensus/exporters/stats/prometheus/internal/prometheus_exporter.cc
  2. index 3bb5962..706b9b4 100644
  3. --- a/opencensus/exporters/stats/prometheus/internal/prometheus_exporter.cc
  4. +++ b/opencensus/exporters/stats/prometheus/internal/prometheus_exporter.cc
  5. @@ -25,7 +25,7 @@ namespace opencensus {
  6. namespace exporters {
  7. namespace stats {
  8. -std::vector<prometheus::MetricFamily> PrometheusExporter::Collect() const {
  9. +std::vector<prometheus::MetricFamily> PrometheusExporter::Collect() {
  10. const auto data = opencensus::stats::StatsExporter::GetViewData();
  11. std::vector<prometheus::MetricFamily> output(data.size());
  12. for (int i = 0; i < data.size(); ++i) {
  13. diff --git a/opencensus/exporters/stats/prometheus/prometheus_exporter.h b/opencensus/exporters/stats/prometheus/prometheus_exporter.h
  14. index bbb285d..ab6471f 100644
  15. --- a/opencensus/exporters/stats/prometheus/prometheus_exporter.h
  16. +++ b/opencensus/exporters/stats/prometheus/prometheus_exporter.h
  17. @@ -41,7 +41,7 @@ namespace stats {
  18. // PrometheusExporter is thread-safe.
  19. class PrometheusExporter final : public ::prometheus::Collectable {
  20. public:
  21. - std::vector<prometheus::MetricFamily> Collect() const override;
  22. + std::vector<prometheus::MetricFamily> Collect() override;
  23. };
  24. } // namespace stats
  25. diff --git a/opencensus/stats/internal/delta_producer.cc b/opencensus/stats/internal/delta_producer.cc
  26. index 1d00504..7eb0d8a 100644
  27. --- a/opencensus/stats/internal/delta_producer.cc
  28. +++ b/opencensus/stats/internal/delta_producer.cc
  29. @@ -75,6 +75,20 @@ DeltaProducer* DeltaProducer::Get() {
  30. return global_delta_producer;
  31. }
  32. +void DeltaProducer::Shutdown() {
  33. + {
  34. + absl::MutexLock l(&mu_);
  35. + if (!thread_started_) {
  36. + return;
  37. + }
  38. + thread_started_ = false;
  39. + }
  40. + // Join loop thread when shutdown.
  41. + if (harvester_thread_.joinable()) {
  42. + harvester_thread_.join();
  43. + }
  44. +}
  45. +
  46. void DeltaProducer::AddMeasure() {
  47. delta_mu_.Lock();
  48. absl::MutexLock harvester_lock(&harvester_mu_);
  49. @@ -115,7 +129,10 @@ void DeltaProducer::Flush() {
  50. }
  51. DeltaProducer::DeltaProducer()
  52. - : harvester_thread_(&DeltaProducer::RunHarvesterLoop, this) {}
  53. + : harvester_thread_(&DeltaProducer::RunHarvesterLoop, this) {
  54. + absl::MutexLock l(&mu_);
  55. + thread_started_ = true;
  56. +}
  57. void DeltaProducer::SwapDeltas() {
  58. ABSL_ASSERT(last_delta_.delta().empty() && "Last delta was not consumed.");
  59. @@ -131,11 +148,19 @@ void DeltaProducer::RunHarvesterLoop() {
  60. absl::Time next_harvest_time = absl::Now() + harvest_interval_;
  61. while (true) {
  62. const absl::Time now = absl::Now();
  63. - absl::SleepFor(next_harvest_time - now);
  64. + absl::SleepFor(absl::Seconds(0.1));
  65. // Account for the possibility that the last harvest took longer than
  66. // harvest_interval_ and we are already past next_harvest_time.
  67. - next_harvest_time = std::max(next_harvest_time, now) + harvest_interval_;
  68. - Flush();
  69. + if (absl::Now() > next_harvest_time) {
  70. + next_harvest_time = std::max(next_harvest_time, now) + harvest_interval_;
  71. + Flush();
  72. + }
  73. + {
  74. + absl::MutexLock l(&mu_);
  75. + if (!thread_started_) {
  76. + break;
  77. + }
  78. + }
  79. }
  80. }
  81. diff --git a/opencensus/stats/internal/delta_producer.h b/opencensus/stats/internal/delta_producer.h
  82. index e565f6a..453b4ef 100644
  83. --- a/opencensus/stats/internal/delta_producer.h
  84. +++ b/opencensus/stats/internal/delta_producer.h
  85. @@ -71,6 +71,8 @@ class DeltaProducer final {
  86. // Returns a pointer to the singleton DeltaProducer.
  87. static DeltaProducer* Get();
  88. + void Shutdown();
  89. +
  90. // Adds a new Measure.
  91. void AddMeasure();
  92. @@ -124,6 +126,9 @@ class DeltaProducer final {
  93. // thread when calling a flush during harvesting.
  94. Delta last_delta_ ABSL_GUARDED_BY(harvester_mu_);
  95. std::thread harvester_thread_ ABSL_GUARDED_BY(harvester_mu_);
  96. +
  97. + mutable absl::Mutex mu_;
  98. + bool thread_started_ GUARDED_BY(mu_) = false;
  99. };
  100. } // namespace stats
  101. diff --git a/opencensus/stats/internal/stats_exporter.cc b/opencensus/stats/internal/stats_exporter.cc
  102. index 7de96d6..f9cac57 100644
  103. --- a/opencensus/stats/internal/stats_exporter.cc
  104. +++ b/opencensus/stats/internal/stats_exporter.cc
  105. @@ -95,25 +95,57 @@ void StatsExporterImpl::ClearHandlersForTesting() {
  106. }
  107. void StatsExporterImpl::StartExportThread() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
  108. - t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
  109. thread_started_ = true;
  110. + t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
  111. +}
  112. +
  113. +void StatsExporterImpl::Shutdown() {
  114. + {
  115. + absl::MutexLock l(&mu_);
  116. + if (!thread_started_) {
  117. + return;
  118. + }
  119. + thread_started_ = false;
  120. + }
  121. + // Join loop thread when shutdown.
  122. + if (t_.joinable()) {
  123. + t_.join();
  124. + }
  125. }
  126. void StatsExporterImpl::RunWorkerLoop() {
  127. absl::Time next_export_time = GetNextExportTime();
  128. while (true) {
  129. // SleepFor() returns immediately when given a negative duration.
  130. - absl::SleepFor(next_export_time - absl::Now());
  131. + absl::SleepFor(absl::Seconds(0.1));
  132. // In case the last export took longer than the export interval, we
  133. // calculate the next time from now.
  134. - next_export_time = GetNextExportTime();
  135. - Export();
  136. + if (absl::Now() > next_export_time) {
  137. + next_export_time = GetNextExportTime();
  138. + Export();
  139. + }
  140. + {
  141. + absl::MutexLock l(&mu_);
  142. + if (!thread_started_) {
  143. + break;
  144. + }
  145. + }
  146. }
  147. }
  148. // StatsExporter
  149. // -------------
  150. +void StatsExporter::Shutdown() {
  151. + StatsExporterImpl::Get()->Shutdown();
  152. + StatsExporterImpl::Get()->ClearHandlersForTesting();
  153. +}
  154. +
  155. +void StatsExporter::ExportNow() {
  156. + DeltaProducer::Get()->Flush();
  157. + StatsExporterImpl::Get()->Export();
  158. +}
  159. +
  160. // static
  161. void StatsExporter::SetInterval(absl::Duration interval) {
  162. StatsExporterImpl::Get()->SetInterval(interval);
  163. diff --git a/opencensus/stats/internal/stats_exporter_impl.h b/opencensus/stats/internal/stats_exporter_impl.h
  164. index abbd13e..823471e 100644
  165. --- a/opencensus/stats/internal/stats_exporter_impl.h
  166. +++ b/opencensus/stats/internal/stats_exporter_impl.h
  167. @@ -34,6 +34,7 @@ class StatsExporterImpl {
  168. public:
  169. static StatsExporterImpl* Get();
  170. void SetInterval(absl::Duration interval);
  171. + void Shutdown();
  172. absl::Time GetNextExportTime() const;
  173. void AddView(const ViewDescriptor& view);
  174. void RemoveView(absl::string_view name);
  175. diff --git a/opencensus/stats/stats_exporter.h b/opencensus/stats/stats_exporter.h
  176. index 6756858..228069b 100644
  177. --- a/opencensus/stats/stats_exporter.h
  178. +++ b/opencensus/stats/stats_exporter.h
  179. @@ -44,6 +44,8 @@ class StatsExporter final {
  180. // Removes the view with 'name' from the registry, if one is registered.
  181. static void RemoveView(absl::string_view name);
  182. + static void Shutdown();
  183. + static void ExportNow();
  184. // StatsExporter::Handler is the interface for push exporters that export
  185. // recorded data for registered views. The exporter should provide a static