opencensus-cpp-shutdown-api.patch 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. diff --git opencensus/stats/internal/delta_producer.cc opencensus/stats/internal/delta_producer.cc
  2. index c61b4d9..b3e4ef2 100644
  3. --- opencensus/stats/internal/delta_producer.cc
  4. +++ opencensus/stats/internal/delta_producer.cc
  5. @@ -75,6 +75,20 @@ DeltaProducer* DeltaProducer::Get() {
  6. return global_delta_producer;
  7. }
  8. +void DeltaProducer::Shutdown() {
  9. + {
  10. + absl::MutexLock l(&mu_);
  11. + if (!thread_started_) {
  12. + return;
  13. + }
  14. + thread_started_ = false;
  15. + }
  16. + // Join loop thread when shutdown.
  17. + if (harvester_thread_.joinable()) {
  18. + harvester_thread_.join();
  19. + }
  20. +}
  21. +
  22. void DeltaProducer::AddMeasure() {
  23. delta_mu_.Lock();
  24. absl::MutexLock harvester_lock(&harvester_mu_);
  25. @@ -115,7 +129,10 @@ void DeltaProducer::Flush() {
  26. }
  27. DeltaProducer::DeltaProducer()
  28. - : harvester_thread_(&DeltaProducer::RunHarvesterLoop, this) {}
  29. + : harvester_thread_(&DeltaProducer::RunHarvesterLoop, this) {
  30. + absl::MutexLock l(&mu_);
  31. + thread_started_ = true;
  32. +}
  33. void DeltaProducer::SwapDeltas() {
  34. ABSL_ASSERT(last_delta_.delta().empty() && "Last delta was not consumed.");
  35. @@ -131,11 +148,19 @@ void DeltaProducer::RunHarvesterLoop() {
  36. absl::Time next_harvest_time = absl::Now() + harvest_interval_;
  37. while (true) {
  38. const absl::Time now = absl::Now();
  39. - absl::SleepFor(next_harvest_time - now);
  40. + absl::SleepFor(absl::Seconds(0.1));
  41. // Account for the possibility that the last harvest took longer than
  42. // harvest_interval_ and we are already past next_harvest_time.
  43. - next_harvest_time = std::max(next_harvest_time, now) + harvest_interval_;
  44. - Flush();
  45. + if (absl::Now() > next_harvest_time) {
  46. + next_harvest_time = std::max(next_harvest_time, now) + harvest_interval_;
  47. + Flush();
  48. + }
  49. + {
  50. + absl::MutexLock l(&mu_);
  51. + if (!thread_started_) {
  52. + break;
  53. + }
  54. + }
  55. }
  56. }
  57. diff --git opencensus/stats/internal/delta_producer.h opencensus/stats/internal/delta_producer.h
  58. index 2cff522..c8e2e95 100644
  59. --- opencensus/stats/internal/delta_producer.h
  60. +++ opencensus/stats/internal/delta_producer.h
  61. @@ -71,6 +71,8 @@ class DeltaProducer final {
  62. // Returns a pointer to the singleton DeltaProducer.
  63. static DeltaProducer* Get();
  64. + void Shutdown();
  65. +
  66. // Adds a new Measure.
  67. void AddMeasure();
  68. @@ -122,6 +124,9 @@ class DeltaProducer final {
  69. // thread when calling a flush during harvesting.
  70. Delta last_delta_ GUARDED_BY(harvester_mu_);
  71. std::thread harvester_thread_ GUARDED_BY(harvester_mu_);
  72. +
  73. + mutable absl::Mutex mu_;
  74. + bool thread_started_ GUARDED_BY(mu_) = false;
  75. };
  76. } // namespace stats
  77. diff --git opencensus/stats/internal/stats_exporter.cc opencensus/stats/internal/stats_exporter.cc
  78. index 43ddbc7..37b4ae1 100644
  79. --- opencensus/stats/internal/stats_exporter.cc
  80. +++ opencensus/stats/internal/stats_exporter.cc
  81. @@ -95,25 +95,52 @@ void StatsExporterImpl::ClearHandlersForTesting() {
  82. }
  83. void StatsExporterImpl::StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
  84. - t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
  85. thread_started_ = true;
  86. + t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this);
  87. +}
  88. +
  89. +void StatsExporterImpl::Shutdown() {
  90. + {
  91. + absl::MutexLock l(&mu_);
  92. + if (!thread_started_) {
  93. + return;
  94. + }
  95. + thread_started_ = false;
  96. + }
  97. + // Join loop thread when shutdown.
  98. + if (t_.joinable()) {
  99. + t_.join();
  100. + }
  101. }
  102. void StatsExporterImpl::RunWorkerLoop() {
  103. absl::Time next_export_time = GetNextExportTime();
  104. while (true) {
  105. // SleepFor() returns immediately when given a negative duration.
  106. - absl::SleepFor(next_export_time - absl::Now());
  107. + absl::SleepFor(absl::Seconds(0.1));
  108. // In case the last export took longer than the export interval, we
  109. // calculate the next time from now.
  110. - next_export_time = GetNextExportTime();
  111. - Export();
  112. + if (absl::Now() > next_export_time) {
  113. + next_export_time = GetNextExportTime();
  114. + Export();
  115. + }
  116. + {
  117. + absl::MutexLock l(&mu_);
  118. + if (!thread_started_) {
  119. + break;
  120. + }
  121. + }
  122. }
  123. }
  124. // StatsExporter
  125. // -------------
  126. +void StatsExporter::Shutdown() {
  127. + StatsExporterImpl::Get()->Shutdown();
  128. + StatsExporterImpl::Get()->ClearHandlersForTesting();
  129. +}
  130. +
  131. // static
  132. void StatsExporter::SetInterval(absl::Duration interval) {
  133. StatsExporterImpl::Get()->SetInterval(interval);
  134. diff --git opencensus/stats/internal/stats_exporter_impl.h opencensus/stats/internal/stats_exporter_impl.h
  135. index 11ae3c4..ebe9c4d 100644
  136. --- opencensus/stats/internal/stats_exporter_impl.h
  137. +++ opencensus/stats/internal/stats_exporter_impl.h
  138. @@ -34,6 +34,7 @@ class StatsExporterImpl {
  139. public:
  140. static StatsExporterImpl* Get();
  141. void SetInterval(absl::Duration interval);
  142. + void Shutdown();
  143. absl::Time GetNextExportTime() const;
  144. void AddView(const ViewDescriptor& view);
  145. void RemoveView(absl::string_view name);
  146. diff --git opencensus/stats/stats_exporter.h opencensus/stats/stats_exporter.h
  147. index 6756858..65e0262 100644
  148. --- opencensus/stats/stats_exporter.h
  149. +++ opencensus/stats/stats_exporter.h
  150. @@ -45,6 +45,8 @@ class StatsExporter final {
  151. // Removes the view with 'name' from the registry, if one is registered.
  152. static void RemoveView(absl::string_view name);
  153. + static void Shutdown();
  154. +
  155. // StatsExporter::Handler is the interface for push exporters that export
  156. // recorded data for registered views. The exporter should provide a static
  157. // Register() method that takes any arguments needed by the exporter (e.g. a