2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Copyright 2013 The Prometheus Authors
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Licensed under the Apache License, Version 2.0 (the "License");
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// you may not use this file except in compliance with the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You may obtain a copy of the License at
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// http://www.apache.org/licenses/LICENSE-2.0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unless required by applicable law or agreed to in writing, software
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// distributed under the License is distributed on an "AS IS" BASIS,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See the License for the specific language governing permissions and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// limitations under the License.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  remote  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-05-29 16:51:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"math" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/go-kit/kit/log" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/go-kit/kit/log/level" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/gogo/protobuf/proto" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/golang/snappy" 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/opentracing/opentracing-go" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/opentracing/opentracing-go/ext" 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 17:00:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/client_golang/prometheus" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"go.uber.org/atomic" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/config" 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/pkg/labels" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/pkg/relabel" 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-24 04:28:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/prompb" 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-19 17:15:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/tsdb/record" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/prometheus/prometheus/tsdb/wal" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We track samples in/out and how long pushes take using an Exponentially
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Weighted Moving Average.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ewmaWeight           =  0.2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shardUpdateDuration  =  10  *  time . Second 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Allow 30% too many shards before scaling down.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shardToleranceFraction  =  0.3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  queueManagerMetrics  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reg  prometheus . Registerer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									succeededSamplesTotal  prometheus . Counter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									failedSamplesTotal     prometheus . Counter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									retriedSamplesTotal    prometheus . Counter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									droppedSamplesTotal    prometheus . Counter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									enqueueRetriesTotal    prometheus . Counter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sentBatchDuration      prometheus . Histogram 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 05:53:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									highestSentTimestamp   * maxTimestamp 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pendingSamples         prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shardCapacity          prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									numShards              prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									maxNumShards           prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									minNumShards           prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									desiredNumShards       prometheus . Gauge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesSent              prometheus . Counter 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-28 19:39:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									maxSamplesPerSend      prometheus . Gauge 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newQueueManagerMetrics ( r  prometheus . Registerer ,  rn ,  e  string )  * queueManagerMetrics  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m  :=  & queueManagerMetrics { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reg :  r , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									constLabels  :=  prometheus . Labels { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										remoteName :  rn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										endpoint :    e , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . succeededSamplesTotal  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "succeeded_samples_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Total number of samples successfully sent to remote storage." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . failedSamplesTotal  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "failed_samples_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Total number of samples which failed on send to remote storage, non-recoverable errors." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . retriedSamplesTotal  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "retried_samples_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Total number of samples which failed on send to remote storage but were retried because the send error was recoverable." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . droppedSamplesTotal  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "dropped_samples_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Total number of samples which were dropped after being read from the WAL before being sent via remote write." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . enqueueRetriesTotal  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "enqueue_retries_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Total number of times enqueue has failed because a shards queue was full." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . sentBatchDuration  =  prometheus . NewHistogram ( prometheus . HistogramOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "sent_batch_duration_seconds" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "Duration of sample batch send calls to the remote storage." , 
							 
						 
					
						
							
								
									
										
										
											
												increase the remote write bucket range (#7323)
* increase the remote write bucket range
Increase the range of remote write buckets to capture times above 10s for laggy scenarios
Buckets had been: {.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
Buckets are now: {0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512}
Signed-off-by: Bert Hartmann <berthartm@gmail.com>
* revert back to DefBuckets with addons to be backwards compatible
Signed-off-by: Bert Hartmann <berthartm@gmail.com>
* shuffle the buckets to maintain 2-2.5x increases
Signed-off-by: Bert Hartmann <berthartm@gmail.com>
											 
										 
										
											2020-06-05 03:54:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Buckets :      append ( prometheus . DefBuckets ,  25 ,  60 ,  120 ,  300 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 05:53:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									m . highestSentTimestamp  =  & maxTimestamp { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Gauge :  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :         "queue_highest_sent_timestamp_seconds" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Help :         "Timestamp from a WAL sample, the highest timestamp successfully sent by this queue, in seconds since epoch." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . pendingSamples  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "pending_samples" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The number of samples pending in the queues shards to be sent to the remote storage." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . shardCapacity  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "shard_capacity" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The capacity of each shard of the queue used for parallel sending to the remote storage." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . numShards  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "shards" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The number of shards used for parallel sending to the remote storage." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . maxNumShards  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "shards_max" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The maximum number of shards that the queue is allowed to run." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . minNumShards  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "shards_min" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The minimum number of shards that the queue is allowed to run." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . desiredNumShards  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "shards_desired" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The number of shards that the queues shard calculation wants to run based on the rate of samples in vs. samples out." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m . bytesSent  =  prometheus . NewCounter ( prometheus . CounterOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "sent_bytes_total" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The total number of bytes sent by the queue." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-28 19:39:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									m . maxSamplesPerSend  =  prometheus . NewGauge ( prometheus . GaugeOpts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Namespace :    namespace , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subsystem :    subsystem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Name :         "max_samples_per_send" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Help :         "The maximum number of samples to be sent, in a single request, to the remote storage." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConstLabels :  constLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 14:33:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  m 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( m  * queueManagerMetrics )  register ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  m . reg  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . MustRegister ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											m . succeededSamplesTotal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . failedSamplesTotal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . retriedSamplesTotal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . droppedSamplesTotal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . enqueueRetriesTotal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . sentBatchDuration , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											m . highestSentTimestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . pendingSamples , 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											m . shardCapacity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . numShards , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . maxNumShards , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . minNumShards , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . desiredNumShards , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m . bytesSent , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-28 19:39:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											m . maxSamplesPerSend , 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( m  * queueManagerMetrics )  unregister ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  m . reg  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . succeededSamplesTotal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . failedSamplesTotal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . retriedSamplesTotal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . droppedSamplesTotal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . enqueueRetriesTotal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . sentBatchDuration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . highestSentTimestamp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . pendingSamples ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . shardCapacity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . numShards ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . maxNumShards ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . minNumShards ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . desiredNumShards ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										m . reg . Unregister ( m . bytesSent ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-28 19:39:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										m . reg . Unregister ( m . maxSamplesPerSend ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// WriteClient defines an interface for sending a batch of samples to an
  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// external timeseries database.
  
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  WriteClient  interface  {  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Store stores the given samples in the remote storage.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Store ( context . Context ,  [ ] byte )  error 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 04:47:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Name uniquely identifies the remote storage.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									Name ( )  string 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 04:47:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Endpoint is the remote read or write endpoint for the storage client.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Endpoint ( )  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// QueueManager manages a queue of samples to be sent to the Storage
  
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// indicated by the provided WriteClient. Implements writeTo interface
  
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// used by WAL Watcher.
  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  QueueManager  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									lastSendTimestamp  atomic . Int64 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger          log . Logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									flushDeadline   time . Duration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg             config . QueueConfig 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									externalLabels  labels . Labels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									relabelConfigs  [ ] * relabel . Config 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-19 17:15:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									watcher         * wal . Watcher 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									clientMtx    sync . RWMutex 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									storeClient  WriteClient 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seriesMtx             sync . Mutex 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seriesLabels          map [ uint64 ] labels . Labels 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seriesSegmentIndexes  map [ uint64 ] int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									droppedSeries         map [ uint64 ] struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									shards       * shards 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									numShards    int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reshardChan  chan  int 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 20:48:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									quit         chan  struct { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wg           sync . WaitGroup 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-20 15:51:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									samplesIn ,  samplesDropped ,  samplesOut ,  samplesOutDuration  * ewmaRate 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									metrics               * queueManagerMetrics 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									interner              * pool 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 05:53:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									highestRecvTimestamp  * maxTimestamp 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewQueueManager builds a new QueueManager.
  
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NewQueueManager (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									metrics  * queueManagerMetrics , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									watcherMetrics  * wal . WatcherMetrics , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readerMetrics  * wal . LiveReaderMetrics , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger  log . Logger , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									walDir  string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									samplesIn  * ewmaRate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  config . QueueConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									externalLabels  labels . Labels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									relabelConfigs  [ ] * relabel . Config , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									client  WriteClient , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									flushDeadline  time . Duration , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									interner  * pool , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-16 05:53:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									highestRecvTimestamp  * maxTimestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  * QueueManager  {  
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  logger  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger  =  log . NewNopLogger ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 04:47:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger  =  log . With ( logger ,  remoteName ,  client . Name ( ) ,  endpoint ,  client . Endpoint ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t  :=  & QueueManager { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger :          logger , 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-23 22:03:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										flushDeadline :   flushDeadline , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										cfg :             cfg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										externalLabels :  externalLabels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										relabelConfigs :  relabelConfigs , 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										storeClient :     client , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seriesLabels :          make ( map [ uint64 ] labels . Labels ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										seriesSegmentIndexes :  make ( map [ uint64 ] int ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										droppedSeries :         make ( map [ uint64 ] struct { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-05 01:32:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										numShards :    cfg . MinShards , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										reshardChan :  make ( chan  int ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										quit :         make ( chan  struct { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										samplesIn :           samplesIn , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-20 15:51:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										samplesDropped :      newEWMARate ( ewmaWeight ,  shardUpdateDuration ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										samplesOut :          newEWMARate ( ewmaWeight ,  shardUpdateDuration ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesOutDuration :  newEWMARate ( ewmaWeight ,  shardUpdateDuration ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-04 05:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										metrics :               metrics , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										interner :              interner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										highestRecvTimestamp :  highestRecvTimestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 03:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-21 00:34:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . watcher  =  wal . NewWatcher ( watcherMetrics ,  readerMetrics ,  logger ,  client . Name ( ) ,  t ,  walDir ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-05 20:21:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . shards  =  t . newShards ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Append queues a sample to be sent to the remote storage. Blocks until all samples are
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// enqueued on their shards or a shutdown signal is received.
  
						 
					
						
							
								
									
										
										
										
											2019-09-19 17:15:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  Append ( samples  [ ] record . RefSample )  bool  {  
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								outer :  
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  samples  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . seriesMtx . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										lbls ,  ok  :=  t . seriesLabels [ s . Ref ] 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . metrics . droppedSamplesTotal . Inc ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-20 15:51:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . samplesDropped . incr ( 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  t . droppedSeries [ s . Ref ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-11 16:22:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												level . Info ( t . logger ) . Log ( "msg" ,  "Dropped sample for series that was not explicitly dropped via relabelling" ,  "ref" ,  s . Ref ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . seriesMtx . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . seriesMtx . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 20:48:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This will only loop if the queues are being resharded.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										backoff  :=  t . cfg . MinBackoff 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- t . quit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  t . shards . enqueue ( s . Ref ,  sample { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												labels :  lbls , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t :       s . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												v :       s . V , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue  outer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-18 20:48:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . metrics . enqueueRetriesTotal . Inc ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											time . Sleep ( time . Duration ( backoff ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											backoff  =  backoff  *  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  backoff  >  t . cfg . MaxBackoff  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												backoff  =  t . cfg . MaxBackoff 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Start the queue manager sending samples to the remote storage.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Does not block.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  Start ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-06-26 14:33:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Register and initialise some metrics.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . metrics . register ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . metrics . shardCapacity . Set ( float64 ( t . cfg . Capacity ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . metrics . maxNumShards . Set ( float64 ( t . cfg . MaxShards ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . metrics . minNumShards . Set ( float64 ( t . cfg . MinShards ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . metrics . desiredNumShards . Set ( float64 ( t . cfg . MinShards ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-28 19:39:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . metrics . maxSamplesPerSend . Set ( float64 ( t . cfg . MaxSamplesPerSend ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-23 16:49:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . shards . start ( t . numShards ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . watcher . Start ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . wg . Add ( 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  t . updateShardsLoop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  t . reshardLoop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Stop stops sending samples to the remote storage and waits for pending
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sends to complete.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  Stop ( )  {  
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Info ( t . logger ) . Log ( "msg" ,  "Stopping remote storage..." ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  level . Info ( t . logger ) . Log ( "msg" ,  "Remote storage stopped." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									close ( t . quit ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-16 18:25:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Wait for all QueueManager routines to end before stopping shards and WAL watcher. This
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is to ensure we don't end up executing a reshard and shards.stop() at the same time, which
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// causes a closed channel panic.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . shards . stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . watcher . Stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 18:02:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// On shutdown, release the strings in the labels from the intern pool.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . seriesMtx . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 18:02:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  labels  :=  range  t . seriesLabels  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . releaseLabels ( labels ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 18:02:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . seriesMtx . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . metrics . unregister ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// StoreSeries keeps track of which series we know about for lookups when sending samples to remote.
  
						 
					
						
							
								
									
										
										
										
											2019-09-19 17:15:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  StoreSeries ( series  [ ] record . RefSeries ,  index  int )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . seriesMtx . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  t . seriesMtx . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  series  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ls  :=  processExternalLabels ( s . Labels ,  t . externalLabels ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										lbls  :=  relabel . Process ( ls ,  t . relabelConfigs ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( lbls )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . droppedSeries [ s . Ref ]  =  struct { } { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . seriesSegmentIndexes [ s . Ref ]  =  index 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . internLabels ( lbls ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-12 07:44:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 18:02:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// We should not ever be replacing a series labels in the map, but just
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// in case we do we need to ensure we do not leak the replaced interned
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// strings.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  orig ,  ok  :=  t . seriesLabels [ s . Ref ] ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . releaseLabels ( orig ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-12 07:44:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . seriesLabels [ s . Ref ]  =  lbls 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SeriesReset is used when reading a checkpoint. WAL Watcher should have
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// stored series records with the checkpoints index number, so we can now
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// delete any ref ID's lower than that # from the two maps.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  SeriesReset ( index  int )  {  
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . seriesMtx . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  t . seriesMtx . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check for series that are in segments older than the checkpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that were not also present in the checkpoint.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k ,  v  :=  range  t . seriesSegmentIndexes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  v  <  index  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delete ( t . seriesSegmentIndexes ,  k ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . releaseLabels ( t . seriesLabels [ k ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-12 07:44:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											delete ( t . seriesLabels ,  k ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-14 01:23:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											delete ( t . droppedSeries ,  k ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SetClient updates the client used by a queue. Used when only client specific
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// fields are updated to avoid restarting the queue.
  
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  SetClient ( c  WriteClient )  {  
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . clientMtx . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . storeClient  =  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . clientMtx . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-24 21:41:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  client ( )  WriteClient  {  
						 
					
						
							
								
									
										
										
										
											2020-03-31 11:39:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . clientMtx . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  t . clientMtx . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  t . storeClient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  internLabels ( lbls  labels . Labels )  {  
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  l  :=  range  lbls  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										lbls [ i ] . Name  =  t . interner . intern ( l . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lbls [ i ] . Value  =  t . interner . intern ( l . Value ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-08 03:39:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  releaseLabels ( ls  labels . Labels )  {  
						 
					
						
							
								
									
										
										
										
											2019-03-12 07:44:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  l  :=  range  ls  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . interner . release ( l . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . interner . release ( l . Value ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-12 07:44:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 18:02:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// processExternalLabels merges externalLabels into ls. If ls contains
  
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// a label in externalLabels, the value in ls wins.
  
						 
					
						
							
								
									
										
										
										
											2019-11-19 03:53:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  processExternalLabels ( ls  labels . Labels ,  externalLabels  labels . Labels )  labels . Labels  {  
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									i ,  j ,  result  :=  0 ,  0 ,  make ( labels . Labels ,  0 ,  len ( ls ) + len ( externalLabels ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  <  len ( ls )  &&  j  <  len ( externalLabels )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ls [ i ] . Name  <  externalLabels [ j ] . Name  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											result  =  append ( result ,  labels . Label { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :   ls [ i ] . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Value :  ls [ i ] . Value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ls [ i ] . Name  >  externalLabels [ j ] . Name  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											result  =  append ( result ,  externalLabels [ j ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											j ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											result  =  append ( result ,  labels . Label { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :   ls [ i ] . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Value :  ls [ i ] . Value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											j ++ 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-09 00:29:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ;  i  <  len ( ls ) ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										result  =  append ( result ,  labels . Label { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :   ls [ i ] . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Value :  ls [ i ] . Value , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									result  =  append ( result ,  externalLabels [ j : ] ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  result 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  updateShardsLoop ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  t . wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 00:36:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ticker  :=  time . NewTicker ( shardUpdateDuration ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  ticker . Stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 00:36:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  <- ticker . C : 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											desiredShards  :=  t . calculateDesiredShards ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 06:20:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! t . shouldReshard ( desiredShards )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Resharding can take some time, and we want this loop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// to stay close to shardUpdateDuration.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  t . reshardChan  <-  desiredShards : 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-26 21:22:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												level . Info ( t . logger ) . Log ( "msg" ,  "Remote storage resharding" ,  "from" ,  t . numShards ,  "to" ,  desiredShards ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . numShards  =  desiredShards 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												level . Info ( t . logger ) . Log ( "msg" ,  "Currently resharding, skipping." ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  <- t . quit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 06:20:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// shouldReshard returns if resharding should occur
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  shouldReshard ( desiredShards  int )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  desiredShards  ==  t . numShards  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We shouldn't reshard if Prometheus hasn't been able to send to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// remote endpoint successfully within some period of time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									minSendTimestamp  :=  time . Now ( ) . Add ( - 2  *  time . Duration ( t . cfg . BatchSendDeadline ) ) . Unix ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									lsts  :=  t . lastSendTimestamp . Load ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-21 06:20:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  lsts  <  minSendTimestamp  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										level . Warn ( t . logger ) . Log ( "msg" ,  "Skipping resharding, last successful send was beyond threshold" ,  "lastSendTimestamp" ,  lsts ,  "minSendTimestamp" ,  minSendTimestamp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// calculateDesiredShards returns the number of desired shards, which will be
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the current QueueManager.numShards if resharding should not occur for reasons
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// outlined in this functions implementation. It is up to the caller to reshard, or not,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// based on the return value.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  calculateDesiredShards ( )  int  {  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . samplesOut . tick ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-20 15:51:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . samplesDropped . tick ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									t . samplesOutDuration . tick ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We use the number of incoming samples as a prediction of how much work we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// will need to do next iteration.  We add to this any pending samples
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// (received - send) so we can catch up with any backlog. We use the average
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// outgoing batch latency to work out how many shards we need.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										samplesInRate       =  t . samplesIn . rate ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesOutRate      =  t . samplesOut . rate ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesKeptRatio    =  samplesOutRate  /  ( t . samplesDropped . rate ( )  +  samplesOutRate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesOutDuration  =  t . samplesOutDuration . rate ( )  /  float64 ( time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesPendingRate  =  samplesInRate * samplesKeptRatio  -  samplesOutRate 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										highestSent         =  t . metrics . highestSentTimestamp . Get ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-25 02:44:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										highestRecv         =  t . highestRecvTimestamp . Get ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 01:30:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										delay               =  highestRecv  -  highestSent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										samplesPending      =  delay  *  samplesInRate  *  samplesKeptRatio 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  samplesOutRate  <=  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  t . numShards 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-24 02:03:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// When behind we will try to catch up on a proporation of samples per tick.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This works similarly to an integral accumulator in that pending samples
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is the result of the error integral.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  integralGain  =  0.1  /  float64 ( shardUpdateDuration / time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										timePerSample  =  samplesOutDuration  /  samplesOutRate 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-24 02:03:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										desiredShards  =  timePerSample  *  ( samplesInRate * samplesKeptRatio  +  integralGain * samplesPending ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t . metrics . desiredNumShards . Set ( desiredShards ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 23:24:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Debug ( t . logger ) . Log ( "msg" ,  "QueueManager.calculateDesiredShards" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"samplesInRate" ,  samplesInRate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"samplesOutRate" ,  samplesOutRate , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 03:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"samplesKeptRatio" ,  samplesKeptRatio , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"samplesPendingRate" ,  samplesPendingRate , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 03:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"samplesPending" ,  samplesPending , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"samplesOutDuration" ,  samplesOutDuration , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"timePerSample" ,  timePerSample , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"desiredShards" ,  desiredShards , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"highestSent" ,  highestSent , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 17:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"highestRecv" ,  highestRecv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Changes in the number of shards must be greater than shardToleranceFraction.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lowerBound  =  float64 ( t . numShards )  *  ( 1.  -  shardToleranceFraction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										upperBound  =  float64 ( t . numShards )  *  ( 1.  +  shardToleranceFraction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									level . Debug ( t . logger ) . Log ( "msg" ,  "QueueManager.updateShardsLoop" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"lowerBound" ,  lowerBound ,  "desiredShards" ,  desiredShards ,  "upperBound" ,  upperBound ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  lowerBound  <=  desiredShards  &&  desiredShards  <=  upperBound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  t . numShards 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									numShards  :=  int ( math . Ceil ( desiredShards ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-03 01:30:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Do not downshard if we are more than ten seconds back.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  numShards  <  t . numShards  &&  delay  >  10.0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										level . Debug ( t . logger ) . Log ( "msg" ,  "Not downsharding due to being too far behind" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  t . numShards 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  numShards  >  t . cfg . MaxShards  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										numShards  =  t . cfg . MaxShards 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-05 01:32:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  numShards  <  t . cfg . MinShards  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										numShards  =  t . cfg . MinShards 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-22 05:54:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  numShards 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  reshardLoop ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  t . wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  numShards  :=  <- t . reshardChan : 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// We start the newShards after we have stopped (the therefore completely
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// flushed) the oldShards, to guarantee we only every deliver samples in
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . shards . stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . shards . start ( numShards ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  <- t . quit : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( t  * QueueManager )  newShards ( )  * shards  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s  :=  & shards { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										qm :    t , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										done :  make ( chan  struct { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  sample  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									labels  labels . Labels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t       int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v       float64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  shards  struct  {  
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mtx  sync . RWMutex  // With the WAL, this is never actually contended.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									qm      * QueueManager 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									queues  [ ] chan  sample 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Emulate a wait group with a channel and an atomic int, as you
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// cannot select on a wait group.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 21:20:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									done     chan  struct { } 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									running  atomic . Int32 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Soft shutdown context will prevent new enqueues and deadlocks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									softShutdown  chan  struct { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Hard shutdown context is used to terminate outgoing HTTP connections
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// after giving them a chance to terminate.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 04:48:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hardShutdown           context . CancelFunc 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									droppedOnHardShutdown  atomic . Uint32 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// start the shards; must be called before any call to enqueue.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * shards )  start ( n  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mtx . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mtx . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 04:48:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . qm . metrics . pendingSamples . Set ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . qm . metrics . numShards . Set ( float64 ( n ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newQueues  :=  make ( [ ] chan  sample ,  n ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										newQueues [ i ]  =  make ( chan  sample ,  s . qm . cfg . Capacity ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . queues  =  newQueues 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  hardShutdownCtx  context . Context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hardShutdownCtx ,  s . hardShutdown  =  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . softShutdown  =  make ( chan  struct { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . running . Store ( int32 ( n ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . done  =  make ( chan  struct { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . droppedOnHardShutdown . Store ( 0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  s . runShard ( hardShutdownCtx ,  i ,  newQueues [ i ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// stop the shards; subsequent call to enqueue will return false.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * shards )  stop ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Attempt a clean shutdown, but only wait flushDeadline for all the shards
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-03 19:35:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// to cleanly exit.  As we're doing RPCs, enqueue can block indefinitely.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We must be able so call stop concurrently, hence we can only take the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// RLock here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mtx . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									close ( s . softShutdown ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mtx . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Enqueue should now be unblocked, so we can take the write lock.  This
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// also ensures we don't race with writes to the queues, and get a panic:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// send on closed channel.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . mtx . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mtx . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  queue  :=  range  s . queues  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( queue ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-31 23:41:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 21:20:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- s . done : 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 16:51:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- time . After ( s . qm . flushDeadline ) : 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-31 23:41:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 16:51:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 18:35:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Force an unclean shutdown.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . hardShutdown ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 16:51:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									<- s . done 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  dropped  :=  s . droppedOnHardShutdown . Load ( ) ;  dropped  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 04:48:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Error ( s . qm . logger ) . Log ( "msg" ,  "Failed to flush all samples on shutdown" ,  "count" ,  dropped ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// enqueue a sample.  If we are currently in the process of shutting down or resharding,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// will return false; in this case, you should back off and retry.
  
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * shards )  enqueue ( ref  uint64 ,  sample  sample )  bool  {  
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . mtx . RLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . mtx . RUnlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- s . softShutdown : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									shard  :=  uint64 ( ref )  %  uint64 ( len ( s . queues ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  <- s . softShutdown : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  s . queues [ shard ]  <-  sample : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 04:48:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s . qm . metrics . pendingSamples . Inc ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * shards )  runShard ( ctx  context . Context ,  shardID  int ,  queue  chan  sample )  {  
						 
					
						
							
								
									
										
										
										
											2018-02-01 21:20:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  s . running . Dec ( )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 21:20:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											close ( s . done ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									shardNum  :=  strconv . Itoa ( shardID ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Send batches of at most MaxSamplesPerSend samples to the remote storage.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If we have fewer samples than that, flush them out after a deadline
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// anyways.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										max             =  s . qm . cfg . MaxSamplesPerSend 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nPending        =  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pendingSamples  =  allocateTimeSeries ( max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf             [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:55:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									timer  :=  time . NewTimer ( time . Duration ( s . qm . cfg . BatchSendDeadline ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-12 22:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stop  :=  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 20:00:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! timer . Stop ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  <- timer . C : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-12 22:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-24 20:36:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-26 04:48:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// In this case we drop all samples in the buffer and the queue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Remove them from pending and mark them as failed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											droppedSamples  :=  nPending  +  len ( queue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s . qm . metrics . pendingSamples . Sub ( float64 ( droppedSamples ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s . qm . metrics . failedSamplesTotal . Add ( float64 ( droppedSamples ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											s . droppedOnHardShutdown . Add ( uint32 ( droppedSamples ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-29 16:51:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  sample ,  ok  :=  <- queue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  nPending  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													level . Debug ( s . qm . logger ) . Log ( "msg" ,  "Flushing samples to remote storage..." ,  "count" ,  nPending ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													s . sendSamples ( ctx ,  pendingSamples [ : nPending ] ,  & buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													s . qm . metrics . pendingSamples . Sub ( float64 ( nPending ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-12 02:45:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													level . Debug ( s . qm . logger ) . Log ( "msg" ,  "Done flushing." ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Number of pending samples is limited by the fact that sendSamples (via sendSamplesWithBackoff)
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// retries endlessly, so once we reach max samples, if we can never send to the endpoint we'll
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// stop reading from the queue. This makes it safe to reference pendingSamples by index.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pendingSamples [ nPending ] . Labels  =  labelsToLabelsProto ( sample . labels ,  pendingSamples [ nPending ] . Labels ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pendingSamples [ nPending ] . Samples [ 0 ] . Timestamp  =  sample . t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pendingSamples [ nPending ] . Samples [ 0 ] . Value  =  sample . v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nPending ++ 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  nPending  >=  max  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s . sendSamples ( ctx ,  pendingSamples ,  & buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nPending  =  0 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												s . qm . metrics . pendingSamples . Sub ( float64 ( max ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 20:00:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-12 22:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												stop ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:55:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timer . Reset ( time . Duration ( s . qm . cfg . BatchSendDeadline ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 20:00:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-24 20:36:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  <- timer . C : 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  nPending  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												level . Debug ( s . qm . logger ) . Log ( "msg" ,  "runShard timer ticked, sending samples" ,  "samples" ,  nPending ,  "shard" ,  shardNum ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s . sendSamples ( ctx ,  pendingSamples [ : nPending ] ,  & buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												s . qm . metrics . pendingSamples . Sub ( float64 ( nPending ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-10 11:51:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												nPending  =  0 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:55:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											timer . Reset ( time . Duration ( s . qm . cfg . BatchSendDeadline ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * shards )  sendSamples ( ctx  context . Context ,  samples  [ ] prompb . TimeSeries ,  buf  * [ ] byte )  {  
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									begin  :=  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  s . sendSamplesWithBackoff ( ctx ,  samples ,  buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 22:58:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										level . Error ( s . qm . logger ) . Log ( "msg" ,  "non-recoverable error" ,  "count" ,  len ( samples ) ,  "err" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-25 11:39:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s . qm . metrics . failedSamplesTotal . Add ( float64 ( len ( samples ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-08 17:51:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// These counters are used to calculate the dynamic sharding, and as such
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// should be maintained irrespective of success or failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . qm . samplesOut . incr ( int64 ( len ( samples ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . qm . samplesOutDuration . incr ( int64 ( time . Since ( begin ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 15:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . qm . lastSendTimestamp . Store ( time . Now ( ) . Unix ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sendSamples to the remote storage with backoff for recoverable errors.
  
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * shards )  sendSamplesWithBackoff ( ctx  context . Context ,  samples  [ ] prompb . TimeSeries ,  buf  * [ ] byte )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  highest ,  err  :=  buildWriteRequest ( samples ,  * buf ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 03:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Failing to build the write request is non-recoverable, since it will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// only error if marshaling the proto to bytes fails.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-02 03:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									backoff  :=  s . qm . cfg . MinBackoff 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqSize  :=  len ( * buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sampleCount  :=  len ( samples ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* buf  =  req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									try  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// An anonymous function allows us to defer the completion of our per-try spans
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// without causing a memory leak, and it has the nice effect of not propagating any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// parameters for sendSamplesWithBackoff/3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									attemptStore  :=  func ( )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span ,  ctx  :=  opentracing . StartSpanFromContext ( ctx ,  "Remote Send Batch" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  span . Finish ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span . SetTag ( "samples" ,  sampleCount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span . SetTag ( "request_size" ,  reqSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span . SetTag ( "try" ,  try ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span . SetTag ( "remote_name" ,  s . qm . storeClient . Name ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										span . SetTag ( "remote_url" ,  s . qm . storeClient . Endpoint ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										begin  :=  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  s . qm . client ( ) . Store ( ctx ,  * buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . qm . metrics . sentBatchDuration . Observe ( time . Since ( begin ) . Seconds ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											span . LogKV ( "error" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ext . Error . Set ( span ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ctx . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  attemptStore ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// If the error is unrecoverable, we should not retry.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-30 01:08:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  ok  :=  err . ( RecoverableError ) ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If we make it this far, we've encountered a recoverable error and will retry.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											s . qm . metrics . retriedSamplesTotal . Add ( float64 ( sampleCount ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											level . Warn ( s . qm . logger ) . Log ( "msg" ,  "Failed to send batch, retrying" ,  "err" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											time . Sleep ( time . Duration ( backoff ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											backoff  =  backoff  *  2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  backoff  >  s . qm . cfg . MaxBackoff  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												backoff  =  s . qm . cfg . MaxBackoff 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											try ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-01 23:21:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since we retry forever on recoverable errors, this needs to stay inside the loop.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . qm . metrics . succeededSamplesTotal . Add ( float64 ( sampleCount ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . qm . metrics . bytesSent . Add ( float64 ( reqSize ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . qm . metrics . highestSentTimestamp . Set ( float64 ( highest  /  1000 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  buildWriteRequest ( samples  [ ] prompb . TimeSeries ,  buf  [ ] byte )  ( [ ] byte ,  int64 ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  highest  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  ts  :=  range  samples  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// At the moment we only ever append a TimeSeries with a single sample in it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ts . Samples [ 0 ] . Timestamp  >  highest  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											highest  =  ts . Samples [ 0 ] . Timestamp 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req  :=  & prompb . WriteRequest { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Timeseries :  samples , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data ,  err  :=  proto . Marshal ( req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  highest ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-28 02:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// snappy uses len() to see if it needs to allocate a new slice. Make the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// buffer as long as possible.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  buf  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf  =  buf [ 0 : cap ( buf ) ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									compressed  :=  snappy . Encode ( buf ,  data ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-08 05:26:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  compressed ,  highest ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-10 17:44:13 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-08-13 00:22:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  allocateTimeSeries ( capacity  int )  [ ] prompb . TimeSeries  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timeseries  :=  make ( [ ] prompb . TimeSeries ,  capacity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We only ever send one sample per timeseries, so preallocate with length one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  range  timeseries  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										timeseries [ i ] . Samples  =  [ ] prompb . Sample { { } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  timeseries 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}