MM-34932: Bump dependencies (#17708)
https://mattermost.atlassian.net/browse/MM-34932 ```release-note NONE ```
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
fff09bf210
Коммит
3299a72adb
115
vendor/github.com/splitio/go-client/v6/splitio/client/client.go
сгенерированный
поставляемый
115
vendor/github.com/splitio/go-client/v6/splitio/client/client.go
сгенерированный
поставляемый
@@ -12,21 +12,30 @@ import (
|
||||
"github.com/splitio/go-split-commons/v3/dtos"
|
||||
"github.com/splitio/go-split-commons/v3/provisional"
|
||||
"github.com/splitio/go-split-commons/v3/storage"
|
||||
"github.com/splitio/go-split-commons/v3/util"
|
||||
"github.com/splitio/go-split-commons/v3/telemetry"
|
||||
"github.com/splitio/go-toolkit/v4/logging"
|
||||
)
|
||||
|
||||
const (
|
||||
treatment = "Treatment"
|
||||
treatments = "Treatments"
|
||||
treatmentWithConfig = "TreatmentWithConfig"
|
||||
treatmentsWithConfig = "TreatmentsWithConfig"
|
||||
)
|
||||
|
||||
// SplitClient is the entry-point of the split SDK.
|
||||
type SplitClient struct {
|
||||
logger logging.LoggerInterface
|
||||
evaluator evaluator.Interface
|
||||
impressions storage.ImpressionStorageProducer
|
||||
metrics storage.MetricsStorageProducer
|
||||
events storage.EventStorageProducer
|
||||
validator inputValidation
|
||||
factory *SplitFactory
|
||||
impressionListener *impressionlistener.WrapperImpressionListener
|
||||
impressionManager provisional.ImpressionManager
|
||||
logger logging.LoggerInterface
|
||||
evaluator evaluator.Interface
|
||||
impressions storage.ImpressionStorageProducer
|
||||
events storage.EventStorageProducer
|
||||
validator inputValidation
|
||||
factory *SplitFactory
|
||||
impressionListener *impressionlistener.WrapperImpressionListener
|
||||
impressionManager provisional.ImpressionManager
|
||||
initTelemetry storage.TelemetryConfigProducer
|
||||
evaluationTelemetry storage.TelemetryEvaluationProducer
|
||||
runtimeTelemetry storage.TelemetryRuntimeProducer
|
||||
}
|
||||
|
||||
// TreatmentResult struct that includes the Treatment evaluation with the corresponding Config
|
||||
@@ -36,17 +45,12 @@ type TreatmentResult struct {
|
||||
}
|
||||
|
||||
// getEvaluationResult calls evaluation for one particular split
|
||||
func (c *SplitClient) getEvaluationResult(
|
||||
matchingKey string,
|
||||
bucketingKey *string,
|
||||
feature string,
|
||||
attributes map[string]interface{},
|
||||
operation string,
|
||||
) *evaluator.Result {
|
||||
func (c *SplitClient) getEvaluationResult(matchingKey string, bucketingKey *string, feature string, attributes map[string]interface{}, operation string) *evaluator.Result {
|
||||
if c.isReady() {
|
||||
return c.evaluator.EvaluateFeature(matchingKey, bucketingKey, feature, attributes)
|
||||
}
|
||||
c.logger.Warning(operation + ": the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
c.initTelemetry.RecordNonReadyUsage()
|
||||
return &evaluator.Result{
|
||||
Treatment: evaluator.Control,
|
||||
Label: impressionlabels.ClientNotReady,
|
||||
@@ -55,17 +59,12 @@ func (c *SplitClient) getEvaluationResult(
|
||||
}
|
||||
|
||||
// getEvaluationsResult calls evaluation for multiple treatments at once
|
||||
func (c *SplitClient) getEvaluationsResult(
|
||||
matchingKey string,
|
||||
bucketingKey *string,
|
||||
features []string,
|
||||
attributes map[string]interface{},
|
||||
operation string,
|
||||
) evaluator.Results {
|
||||
func (c *SplitClient) getEvaluationsResult(matchingKey string, bucketingKey *string, features []string, attributes map[string]interface{}, operation string) evaluator.Results {
|
||||
if c.isReady() {
|
||||
return c.evaluator.EvaluateFeatures(matchingKey, bucketingKey, features, attributes)
|
||||
}
|
||||
c.logger.Warning(operation + ": the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
c.initTelemetry.RecordNonReadyUsage()
|
||||
result := evaluator.Results{
|
||||
EvaluationTimeNs: 0,
|
||||
Evaluations: make(map[string]evaluator.Result),
|
||||
@@ -81,14 +80,7 @@ func (c *SplitClient) getEvaluationsResult(
|
||||
}
|
||||
|
||||
// createImpression creates impression to be stored and used by listener
|
||||
func (c *SplitClient) createImpression(
|
||||
feature string,
|
||||
bucketingKey *string,
|
||||
evaluationLabel string,
|
||||
matchingKey string,
|
||||
treatment string,
|
||||
changeNumber int64,
|
||||
) dtos.Impression {
|
||||
func (c *SplitClient) createImpression(feature string, bucketingKey *string, evaluationLabel string, matchingKey string, treatment string, changeNumber int64) dtos.Impression {
|
||||
var label string
|
||||
if c.factory.cfg.LabelsEnabled {
|
||||
label = evaluationLabel
|
||||
@@ -126,23 +118,11 @@ func (c *SplitClient) storeData(impressions []dtos.Impression, attributes map[st
|
||||
}
|
||||
|
||||
// Store latency
|
||||
if c.metrics != nil {
|
||||
bucket := util.Bucket(evaluationTimeNs)
|
||||
c.metrics.IncLatency(metricsLabel, bucket)
|
||||
} else {
|
||||
c.logger.Warning("No metrics storage set in client. Not sending latencies!")
|
||||
}
|
||||
c.evaluationTelemetry.RecordLatency(metricsLabel, int64(telemetry.Bucket(evaluationTimeNs)))
|
||||
}
|
||||
|
||||
// doTreatmentCall retrieves treatments of an specific feature with configurations object if it is present
|
||||
// for a certain key and set of attributes
|
||||
func (c *SplitClient) doTreatmentCall(
|
||||
key interface{},
|
||||
feature string,
|
||||
attributes map[string]interface{},
|
||||
operation string,
|
||||
metricsLabel string,
|
||||
) (t TreatmentResult) {
|
||||
// doTreatmentCall retrieves treatments of an specific feature with configurations object if it is present for a certain key and set of attributes
|
||||
func (c *SplitClient) doTreatmentCall(key interface{}, feature string, attributes map[string]interface{}, operation string, metricsLabel string) (t TreatmentResult) {
|
||||
controlTreatment := TreatmentResult{
|
||||
Treatment: evaluator.Control,
|
||||
Config: nil,
|
||||
@@ -153,6 +133,7 @@ func (c *SplitClient) doTreatmentCall(
|
||||
if r := recover(); r != nil {
|
||||
// At this point we'll only trust that the logger isn't panicking trust
|
||||
// that the logger isn't panicking
|
||||
c.evaluationTelemetry.RecordException(metricsLabel)
|
||||
c.logger.Error(
|
||||
"SDK is panicking with the following error", r, "\n",
|
||||
string(debug.Stack()), "\n",
|
||||
@@ -200,13 +181,13 @@ func (c *SplitClient) doTreatmentCall(
|
||||
// Treatment implements the main functionality of split. Retrieve treatments of a specific feature
|
||||
// for a certain key and set of attributes
|
||||
func (c *SplitClient) Treatment(key interface{}, feature string, attributes map[string]interface{}) string {
|
||||
return c.doTreatmentCall(key, feature, attributes, "Treatment", "sdk.getTreatment").Treatment
|
||||
return c.doTreatmentCall(key, feature, attributes, treatment, telemetry.Treatment).Treatment
|
||||
}
|
||||
|
||||
// TreatmentWithConfig implements the main functionality of split. Retrieves the treatment of a specific feature with
|
||||
// the corresponding configuration if it is present
|
||||
func (c *SplitClient) TreatmentWithConfig(key interface{}, feature string, attributes map[string]interface{}) TreatmentResult {
|
||||
return c.doTreatmentCall(key, feature, attributes, "TreatmentWithConfig", "sdk.getTreatmentWithConfig")
|
||||
return c.doTreatmentCall(key, feature, attributes, treatmentWithConfig, telemetry.TreatmentWithConfig)
|
||||
}
|
||||
|
||||
// Generates control treatments
|
||||
@@ -225,15 +206,8 @@ func (c *SplitClient) generateControlTreatments(features []string, operation str
|
||||
return treatments
|
||||
}
|
||||
|
||||
// doTreatmentsCall retrieves treatments of an specific array of features with configurations object if it is present
|
||||
// for a certain key and set of attributes
|
||||
func (c *SplitClient) doTreatmentsCall(
|
||||
key interface{},
|
||||
features []string,
|
||||
attributes map[string]interface{},
|
||||
operation string,
|
||||
metricsLabel string,
|
||||
) (t map[string]TreatmentResult) {
|
||||
// doTreatmentsCall retrieves treatments of an specific array of features with configurations object if it is present for a certain key and set of attributes
|
||||
func (c *SplitClient) doTreatmentsCall(key interface{}, features []string, attributes map[string]interface{}, operation string, metricsLabel string) (t map[string]TreatmentResult) {
|
||||
treatments := make(map[string]TreatmentResult)
|
||||
|
||||
// Set up a guard deferred function to recover if the SDK starts panicking
|
||||
@@ -241,10 +215,11 @@ func (c *SplitClient) doTreatmentsCall(
|
||||
if r := recover(); r != nil {
|
||||
// At this point we'll only trust that the logger isn't panicking trust
|
||||
// that the logger isn't panicking
|
||||
c.evaluationTelemetry.RecordException(metricsLabel)
|
||||
c.logger.Error(
|
||||
"SDK is panicking with the following error", r, "\n",
|
||||
string(debug.Stack()), "\n")
|
||||
t = treatments
|
||||
t = c.generateControlTreatments(features, operation)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -290,17 +265,17 @@ func (c *SplitClient) doTreatmentsCall(
|
||||
|
||||
// Treatments evaluates multiple featers for a single user and set of attributes at once
|
||||
func (c *SplitClient) Treatments(key interface{}, features []string, attributes map[string]interface{}) map[string]string {
|
||||
treatments := map[string]string{}
|
||||
result := c.doTreatmentsCall(key, features, attributes, "Treatments", "sdk.getTreatments")
|
||||
treatmentsResult := map[string]string{}
|
||||
result := c.doTreatmentsCall(key, features, attributes, treatments, telemetry.Treatments)
|
||||
for feature, treatmentResult := range result {
|
||||
treatments[feature] = treatmentResult.Treatment
|
||||
treatmentsResult[feature] = treatmentResult.Treatment
|
||||
}
|
||||
return treatments
|
||||
return treatmentsResult
|
||||
}
|
||||
|
||||
// TreatmentsWithConfig evaluates multiple featers for a single user and set of attributes at once and returns configurations
|
||||
func (c *SplitClient) TreatmentsWithConfig(key interface{}, features []string, attributes map[string]interface{}) map[string]TreatmentResult {
|
||||
return c.doTreatmentsCall(key, features, attributes, "TreatmentsWithConfig", "sdk.getTreatmentsWithConfig")
|
||||
return c.doTreatmentsCall(key, features, attributes, treatmentsWithConfig, telemetry.TreatmentsWithConfig)
|
||||
}
|
||||
|
||||
// isDestroyed returns true if the client has been destroyed
|
||||
@@ -321,24 +296,17 @@ func (c *SplitClient) Destroy() {
|
||||
}
|
||||
|
||||
// Track an event and its custom value
|
||||
func (c *SplitClient) Track(
|
||||
key string,
|
||||
trafficType string,
|
||||
eventType string,
|
||||
value interface{},
|
||||
properties map[string]interface{},
|
||||
) (ret error) {
|
||||
|
||||
func (c *SplitClient) Track(key string, trafficType string, eventType string, value interface{}, properties map[string]interface{}) (ret error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// At this point we'll only trust that the logger isn't panicking
|
||||
c.evaluationTelemetry.RecordException(telemetry.Track)
|
||||
c.logger.Error(
|
||||
"SDK is panicking with the following error", r, "\n",
|
||||
string(debug.Stack()), "\n",
|
||||
)
|
||||
ret = errors.New("Track is panicking. Please check logs")
|
||||
}
|
||||
return
|
||||
}()
|
||||
|
||||
if c.isDestroyed() {
|
||||
@@ -348,6 +316,7 @@ func (c *SplitClient) Track(
|
||||
|
||||
if !c.isReady() {
|
||||
c.logger.Warning("Track: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
c.initTelemetry.RecordNonReadyUsage()
|
||||
}
|
||||
|
||||
key, trafficType, eventType, value, err := c.validator.ValidateTrackInputs(
|
||||
|
||||
207
vendor/github.com/splitio/go-client/v6/splitio/client/factory.go
сгенерированный
поставляемый
207
vendor/github.com/splitio/go-client/v6/splitio/client/factory.go
сгенерированный
поставляемый
@@ -18,20 +18,22 @@ import (
|
||||
config "github.com/splitio/go-split-commons/v3/conf"
|
||||
"github.com/splitio/go-split-commons/v3/dtos"
|
||||
"github.com/splitio/go-split-commons/v3/provisional"
|
||||
"github.com/splitio/go-split-commons/v3/service"
|
||||
"github.com/splitio/go-split-commons/v3/service/api"
|
||||
"github.com/splitio/go-split-commons/v3/service/local"
|
||||
"github.com/splitio/go-split-commons/v3/storage"
|
||||
"github.com/splitio/go-split-commons/v3/storage/mutexmap"
|
||||
"github.com/splitio/go-split-commons/v3/storage/mutexqueue"
|
||||
"github.com/splitio/go-split-commons/v3/storage/inmemory"
|
||||
"github.com/splitio/go-split-commons/v3/storage/inmemory/mutexmap"
|
||||
"github.com/splitio/go-split-commons/v3/storage/inmemory/mutexqueue"
|
||||
"github.com/splitio/go-split-commons/v3/storage/mocks"
|
||||
"github.com/splitio/go-split-commons/v3/storage/redis"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/event"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/impression"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/impressionscount"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/metric"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/segment"
|
||||
"github.com/splitio/go-split-commons/v3/synchronizer/worker/split"
|
||||
"github.com/splitio/go-split-commons/v3/tasks"
|
||||
"github.com/splitio/go-split-commons/v3/telemetry"
|
||||
"github.com/splitio/go-toolkit/v4/logging"
|
||||
)
|
||||
|
||||
@@ -44,15 +46,18 @@ const (
|
||||
)
|
||||
|
||||
type sdkStorages struct {
|
||||
splits storage.SplitStorageConsumer
|
||||
segments storage.SegmentStorageConsumer
|
||||
impressions storage.ImpressionStorageProducer
|
||||
events storage.EventStorageProducer
|
||||
telemetry storage.MetricsStorageProducer
|
||||
splits storage.SplitStorageConsumer
|
||||
segments storage.SegmentStorageConsumer
|
||||
impressions storage.ImpressionStorageProducer
|
||||
events storage.EventStorageProducer
|
||||
initTelemetry storage.TelemetryConfigProducer
|
||||
runtimeTelemetry storage.TelemetryRuntimeProducer
|
||||
evaluationTelemetry storage.TelemetryEvaluationProducer
|
||||
}
|
||||
|
||||
// SplitFactory struct is responsible for instantiating and storing instances of client and manager.
|
||||
type SplitFactory struct {
|
||||
startTime time.Time // Tracking startTime
|
||||
metadata dtos.Metadata
|
||||
storages sdkStorages
|
||||
apikey string
|
||||
@@ -64,6 +69,7 @@ type SplitFactory struct {
|
||||
impressionListener *impressionlistener.WrapperImpressionListener
|
||||
logger logging.LoggerInterface
|
||||
syncManager synchronizer.Manager
|
||||
telemetrySync telemetry.TelemetrySynchronizer // To execute SynchronizeInit
|
||||
impressionManager provisional.ImpressionManager
|
||||
}
|
||||
|
||||
@@ -73,25 +79,28 @@ func (f *SplitFactory) Client() *SplitClient {
|
||||
logger: f.logger,
|
||||
evaluator: evaluator.NewEvaluator(f.storages.splits, f.storages.segments, engine.NewEngine(f.logger), f.logger),
|
||||
impressions: f.storages.impressions,
|
||||
metrics: f.storages.telemetry,
|
||||
events: f.storages.events,
|
||||
validator: inputValidation{
|
||||
logger: f.logger,
|
||||
splitStorage: f.storages.splits,
|
||||
},
|
||||
factory: f,
|
||||
impressionListener: f.impressionListener,
|
||||
impressionManager: f.impressionManager,
|
||||
factory: f,
|
||||
impressionListener: f.impressionListener,
|
||||
impressionManager: f.impressionManager,
|
||||
initTelemetry: f.storages.initTelemetry, // For capturing NonReadyUsages
|
||||
runtimeTelemetry: f.storages.runtimeTelemetry, // For capturing runtime stats
|
||||
evaluationTelemetry: f.storages.evaluationTelemetry, // For capturing treatment stats
|
||||
}
|
||||
}
|
||||
|
||||
// Manager returns the split manager instantiated by the factory
|
||||
func (f *SplitFactory) Manager() *SplitManager {
|
||||
return &SplitManager{
|
||||
splitStorage: f.storages.splits,
|
||||
validator: inputValidation{logger: f.logger},
|
||||
logger: f.logger,
|
||||
factory: f,
|
||||
splitStorage: f.storages.splits,
|
||||
validator: inputValidation{logger: f.logger},
|
||||
logger: f.logger,
|
||||
factory: f,
|
||||
initTelemetry: f.storages.initTelemetry, // For capturing NonReadyUsages
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +119,7 @@ func (f *SplitFactory) initializationLocalhost(readyChannel chan int) {
|
||||
f.syncManager.Start()
|
||||
|
||||
<-readyChannel
|
||||
f.broadcastReadiness(sdkStatusReady)
|
||||
f.broadcastReadiness(sdkStatusReady, make([]string, 0))
|
||||
}
|
||||
|
||||
// initializates tasks for in-memory mode
|
||||
@@ -120,14 +129,51 @@ func (f *SplitFactory) initializationInMemory(readyChannel chan int) {
|
||||
switch msg {
|
||||
case synchronizer.Ready:
|
||||
// Broadcast ready status for SDK
|
||||
f.broadcastReadiness(sdkStatusReady)
|
||||
f.broadcastReadiness(sdkStatusReady, make([]string, 0))
|
||||
default:
|
||||
f.broadcastReadiness(sdkInitializationFailed)
|
||||
f.broadcastReadiness(sdkInitializationFailed, make([]string, 0))
|
||||
}
|
||||
}
|
||||
|
||||
// recordInitTelemetry In charge of recording init stats from redis and memory
|
||||
func (f *SplitFactory) recordInitTelemetry(tags []string) {
|
||||
if f.telemetrySync == nil {
|
||||
f.logger.Debug("Discarding init telemetry")
|
||||
return
|
||||
}
|
||||
f.logger.Debug("Sending init telemetry")
|
||||
f.telemetrySync.SynchronizeConfig(
|
||||
telemetry.InitConfig{
|
||||
AdvancedConfig: config.AdvancedConfig{
|
||||
HTTPTimeout: f.cfg.Advanced.HTTPTimeout,
|
||||
SegmentQueueSize: f.cfg.Advanced.SegmentQueueSize,
|
||||
SegmentWorkers: f.cfg.Advanced.SegmentWorkers,
|
||||
SdkURL: f.cfg.Advanced.SdkURL,
|
||||
EventsURL: f.cfg.Advanced.EventsURL,
|
||||
TelemetryServiceURL: f.cfg.Advanced.TelemetryServiceURL,
|
||||
EventsBulkSize: f.cfg.Advanced.EventsBulkSize,
|
||||
EventsQueueSize: f.cfg.Advanced.EventsQueueSize,
|
||||
ImpressionsQueueSize: f.cfg.Advanced.ImpressionsQueueSize,
|
||||
ImpressionsBulkSize: f.cfg.Advanced.ImpressionsBulkSize,
|
||||
StreamingEnabled: f.cfg.Advanced.StreamingEnabled,
|
||||
AuthServiceURL: f.cfg.Advanced.AuthServiceURL,
|
||||
StreamingServiceURL: f.cfg.Advanced.StreamingServiceURL,
|
||||
},
|
||||
TaskPeriods: config.TaskPeriods(f.cfg.TaskPeriods),
|
||||
ManagerConfig: config.ManagerConfig{
|
||||
OperationMode: f.cfg.OperationMode,
|
||||
ImpressionsMode: f.cfg.ImpressionsMode,
|
||||
ListenerEnabled: f.cfg.Advanced.ImpressionListener != nil,
|
||||
},
|
||||
},
|
||||
time.Now().UTC().Sub(f.startTime).Milliseconds(),
|
||||
getFactories(),
|
||||
tags,
|
||||
)
|
||||
}
|
||||
|
||||
// broadcastReadiness broadcasts message to all the subscriptors
|
||||
func (f *SplitFactory) broadcastReadiness(status int) {
|
||||
func (f *SplitFactory) broadcastReadiness(status int, tags []string) {
|
||||
f.mutex.Lock()
|
||||
defer f.mutex.Unlock()
|
||||
if f.status.Load() == sdkStatusInitializing && status == sdkStatusReady {
|
||||
@@ -136,6 +182,8 @@ func (f *SplitFactory) broadcastReadiness(status int) {
|
||||
for _, subscriptor := range f.readinessSubscriptors {
|
||||
subscriptor <- status
|
||||
}
|
||||
// At this point the SDK is ready for sending telemetry
|
||||
f.recordInitTelemetry(tags)
|
||||
}
|
||||
|
||||
// subscribes listener
|
||||
@@ -191,6 +239,7 @@ func (f *SplitFactory) BlockUntilReady(timer int) error {
|
||||
return errors.New("SDK Initialization failed")
|
||||
}
|
||||
case <-time.After(time.Second * time.Duration(timer)):
|
||||
f.storages.initTelemetry.RecordBURTimeout() // Records BURTimeout
|
||||
return fmt.Errorf("SDK Initialization: time of %d exceeded", timer)
|
||||
}
|
||||
|
||||
@@ -203,6 +252,9 @@ func (f *SplitFactory) Destroy() {
|
||||
removeInstanceFromTracker(f.apikey)
|
||||
}
|
||||
f.status.Store(sdkStatusDestroyed)
|
||||
if f.storages.runtimeTelemetry != nil {
|
||||
f.storages.runtimeTelemetry.RecordSessionLength(int64(time.Since(f.startTime) * time.Millisecond))
|
||||
}
|
||||
|
||||
if f.cfg.OperationMode == conf.RedisConsumer {
|
||||
return
|
||||
@@ -234,48 +286,43 @@ func setupInMemoryFactory(
|
||||
advanced.StreamingEnabled = false
|
||||
}
|
||||
|
||||
/*
|
||||
err := api.ValidateApikey(apikey, *advanced)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*/
|
||||
|
||||
inMememoryFullQueue := make(chan string, 2) // Size 2: So that it's able to accept one event from each resource simultaneously.
|
||||
splitsStorage := mutexmap.NewMMSplitStorage()
|
||||
segmentsStorage := mutexmap.NewMMSegmentStorage()
|
||||
impressionsStorage := mutexqueue.NewMQImpressionsStorage(cfg.Advanced.ImpressionsQueueSize, inMememoryFullQueue, logger)
|
||||
telemetryStorage := mutexmap.NewMMMetricsStorage()
|
||||
eventsStorage := mutexqueue.NewMQEventsStorage(cfg.Advanced.EventsQueueSize, inMememoryFullQueue, logger)
|
||||
metricsWrapper := storage.NewMetricWrapper(telemetryStorage, nil, logger)
|
||||
telemetryStorage, err := inmemory.NewTelemetryStorage()
|
||||
impressionsStorage := mutexqueue.NewMQImpressionsStorage(cfg.Advanced.ImpressionsQueueSize, inMememoryFullQueue, logger, telemetryStorage)
|
||||
eventsStorage := mutexqueue.NewMQEventsStorage(cfg.Advanced.EventsQueueSize, inMememoryFullQueue, logger, telemetryStorage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
managerConfig := config.ManagerConfig{
|
||||
ImpressionsMode: cfg.ImpressionsMode,
|
||||
OperationMode: cfg.OperationMode,
|
||||
ListenerEnabled: cfg.Advanced.ImpressionListener != nil,
|
||||
}
|
||||
splitAPI := service.NewSplitAPI(apikey, advanced, logger, metadata)
|
||||
splitAPI := api.NewSplitAPI(apikey, advanced, logger, metadata)
|
||||
workers := synchronizer.Workers{
|
||||
SplitFetcher: split.NewSplitFetcher(splitsStorage, splitAPI.SplitFetcher, metricsWrapper, logger),
|
||||
SegmentFetcher: segment.NewSegmentFetcher(splitsStorage, segmentsStorage, splitAPI.SegmentFetcher, metricsWrapper, logger),
|
||||
EventRecorder: event.NewEventRecorderSingle(eventsStorage, splitAPI.EventRecorder, metricsWrapper, logger, metadata),
|
||||
ImpressionRecorder: impression.NewRecorderSingle(impressionsStorage, splitAPI.ImpressionRecorder, metricsWrapper, logger, metadata, managerConfig),
|
||||
TelemetryRecorder: metric.NewRecorderSingle(telemetryStorage, splitAPI.MetricRecorder, metadata),
|
||||
SplitFetcher: split.NewSplitFetcher(splitsStorage, splitAPI.SplitFetcher, logger, telemetryStorage),
|
||||
SegmentFetcher: segment.NewSegmentFetcher(splitsStorage, segmentsStorage, splitAPI.SegmentFetcher, logger, telemetryStorage),
|
||||
EventRecorder: event.NewEventRecorderSingle(eventsStorage, splitAPI.EventRecorder, logger, metadata, telemetryStorage),
|
||||
ImpressionRecorder: impression.NewRecorderSingle(impressionsStorage, splitAPI.ImpressionRecorder, logger, metadata, managerConfig, telemetryStorage),
|
||||
TelemetryRecorder: telemetry.NewTelemetrySynchronizer(telemetryStorage, splitAPI.TelemetryRecorder, splitsStorage, segmentsStorage, logger, metadata, telemetryStorage),
|
||||
}
|
||||
splitTasks := synchronizer.SplitTasks{
|
||||
SplitSyncTask: tasks.NewFetchSplitsTask(workers.SplitFetcher, cfg.TaskPeriods.SplitSync, logger),
|
||||
SegmentSyncTask: tasks.NewFetchSegmentsTask(workers.SegmentFetcher, cfg.TaskPeriods.SegmentSync, advanced.SegmentWorkers, advanced.SegmentQueueSize, logger),
|
||||
EventSyncTask: tasks.NewRecordEventsTask(workers.EventRecorder, advanced.EventsBulkSize, cfg.TaskPeriods.EventsSync, logger),
|
||||
ImpressionSyncTask: tasks.NewRecordImpressionsTask(workers.ImpressionRecorder, cfg.TaskPeriods.ImpressionSync, logger, advanced.ImpressionsBulkSize),
|
||||
TelemetrySyncTask: tasks.NewRecordTelemetryTask(workers.TelemetryRecorder, cfg.TaskPeriods.LatencySync, logger),
|
||||
TelemetrySyncTask: tasks.NewRecordTelemetryTask(workers.TelemetryRecorder, cfg.TaskPeriods.TelemetrySync, logger),
|
||||
}
|
||||
var impressionsCounter *provisional.ImpressionsCounter
|
||||
if cfg.ImpressionsMode == config.ImpressionsModeOptimized {
|
||||
impressionsCounter = provisional.NewImpressionsCounter()
|
||||
workers.ImpressionsCountRecorder = impressionscount.NewRecorderSingle(impressionsCounter, splitAPI.ImpressionRecorder, metadata, logger)
|
||||
workers.ImpressionsCountRecorder = impressionscount.NewRecorderSingle(impressionsCounter, splitAPI.ImpressionRecorder, metadata, logger, telemetryStorage)
|
||||
splitTasks.ImpressionsCountSyncTask = tasks.NewRecordImpressionsCountTask(workers.ImpressionsCountRecorder, logger)
|
||||
}
|
||||
impressionManager, err := provisional.NewImpressionManager(managerConfig, impressionsCounter)
|
||||
impressionManager, err := provisional.NewImpressionManager(managerConfig, impressionsCounter, telemetryStorage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -289,6 +336,7 @@ func setupInMemoryFactory(
|
||||
)
|
||||
|
||||
readyChannel := make(chan int, 1)
|
||||
clientKey := apikey[len(apikey)-4:]
|
||||
syncManager, err := synchronizer.NewSynchronizerManager(
|
||||
syncImpl,
|
||||
logger,
|
||||
@@ -296,29 +344,37 @@ func setupInMemoryFactory(
|
||||
splitAPI.AuthClient,
|
||||
splitsStorage,
|
||||
readyChannel,
|
||||
telemetryStorage,
|
||||
metadata,
|
||||
&clientKey,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
splitFactory := SplitFactory{
|
||||
startTime: time.Now().UTC(),
|
||||
apikey: apikey,
|
||||
cfg: cfg,
|
||||
metadata: metadata,
|
||||
logger: logger,
|
||||
operationMode: conf.InMemoryStandAlone,
|
||||
storages: sdkStorages{
|
||||
splits: splitsStorage,
|
||||
events: eventsStorage,
|
||||
impressions: impressionsStorage,
|
||||
segments: segmentsStorage,
|
||||
telemetry: telemetryStorage,
|
||||
splits: splitsStorage,
|
||||
events: eventsStorage,
|
||||
impressions: impressionsStorage,
|
||||
segments: segmentsStorage,
|
||||
initTelemetry: telemetryStorage,
|
||||
evaluationTelemetry: telemetryStorage,
|
||||
runtimeTelemetry: telemetryStorage,
|
||||
},
|
||||
readinessSubscriptors: make(map[int]chan int),
|
||||
syncManager: syncManager,
|
||||
telemetrySync: workers.TelemetryRecorder,
|
||||
}
|
||||
splitFactory.status.Store(sdkStatusInitializing)
|
||||
splitFactory.impressionManager = impressionManager
|
||||
setFactory(splitFactory.apikey, splitFactory.logger)
|
||||
|
||||
go splitFactory.initializationInMemory(readyChannel)
|
||||
|
||||
@@ -332,15 +388,18 @@ func setupRedisFactory(apikey string, cfg *conf.SplitSdkConfig, logger logging.L
|
||||
return nil, err
|
||||
}
|
||||
|
||||
telemetryStorage := redis.NewTelemetryStorage(redisClient, logger, metadata)
|
||||
storages := sdkStorages{
|
||||
splits: redis.NewSplitStorage(redisClient, logger),
|
||||
segments: redis.NewSegmentStorage(redisClient, logger),
|
||||
impressions: redis.NewImpressionStorage(redisClient, metadata, logger),
|
||||
telemetry: redis.NewMetricsStorage(redisClient, metadata, logger),
|
||||
events: redis.NewEventsStorage(redisClient, metadata, logger),
|
||||
splits: redis.NewSplitStorage(redisClient, logger),
|
||||
segments: redis.NewSegmentStorage(redisClient, logger),
|
||||
impressions: redis.NewImpressionStorage(redisClient, metadata, logger),
|
||||
events: redis.NewEventsStorage(redisClient, metadata, logger),
|
||||
initTelemetry: telemetryStorage,
|
||||
evaluationTelemetry: telemetryStorage,
|
||||
}
|
||||
|
||||
factory := &SplitFactory{
|
||||
startTime: time.Now().UTC(),
|
||||
apikey: apikey,
|
||||
cfg: cfg,
|
||||
metadata: metadata,
|
||||
@@ -348,17 +407,23 @@ func setupRedisFactory(apikey string, cfg *conf.SplitSdkConfig, logger logging.L
|
||||
operationMode: conf.RedisConsumer,
|
||||
storages: storages,
|
||||
readinessSubscriptors: make(map[int]chan int),
|
||||
telemetrySync: telemetry.NewSynchronizerRedis(telemetryStorage, logger),
|
||||
}
|
||||
factory.status.Store(sdkStatusInitializing)
|
||||
impressionManager, err := provisional.NewImpressionManager(config.ManagerConfig{
|
||||
OperationMode: cfg.OperationMode,
|
||||
ImpressionsMode: cfg.ImpressionsMode,
|
||||
ListenerEnabled: cfg.Advanced.ImpressionListener != nil,
|
||||
}, nil)
|
||||
}, nil, mocks.MockTelemetryStorage{
|
||||
RecordSyncLatencyCall: func(resource int, latency int64) {},
|
||||
RecordImpressionsStatsCall: func(dataType int, count int64) {},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
factory.impressionManager = impressionManager
|
||||
factory.status.Store(sdkStatusReady)
|
||||
setFactory(factory.apikey, factory.logger)
|
||||
factory.broadcastReadiness(sdkStatusReady, make([]string, 0))
|
||||
return factory, nil
|
||||
}
|
||||
|
||||
@@ -369,17 +434,23 @@ func setupLocalhostFactory(
|
||||
metadata dtos.Metadata,
|
||||
) (*SplitFactory, error) {
|
||||
splitStorage := mutexmap.NewMMSplitStorage()
|
||||
telemetryStorage, err := inmemory.NewTelemetryStorage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
splitPeriod := cfg.TaskPeriods.SplitSync
|
||||
readyChannel := make(chan int, 1)
|
||||
|
||||
splitAPI := &service.SplitAPI{SplitFetcher: local.NewFileSplitFetcher(cfg.SplitFile, logger)}
|
||||
splitAPI := &api.SplitAPI{SplitFetcher: local.NewFileSplitFetcher(cfg.SplitFile, logger)}
|
||||
syncManager, err := synchronizer.NewSynchronizerManager(
|
||||
synchronizer.NewLocal(splitPeriod, splitAPI, splitStorage, logger),
|
||||
synchronizer.NewLocal(splitPeriod, splitAPI, splitStorage, logger, telemetryStorage),
|
||||
logger,
|
||||
config.AdvancedConfig{StreamingEnabled: false},
|
||||
nil,
|
||||
splitStorage,
|
||||
readyChannel,
|
||||
telemetryStorage,
|
||||
metadata,
|
||||
nil,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -387,16 +458,19 @@ func setupLocalhostFactory(
|
||||
}
|
||||
|
||||
splitFactory := &SplitFactory{
|
||||
apikey: apikey,
|
||||
cfg: cfg,
|
||||
metadata: metadata,
|
||||
logger: logger,
|
||||
startTime: time.Now().UTC(),
|
||||
apikey: apikey,
|
||||
cfg: cfg,
|
||||
metadata: metadata,
|
||||
logger: logger,
|
||||
storages: sdkStorages{
|
||||
splits: splitStorage,
|
||||
impressions: mutexqueue.NewMQImpressionsStorage(cfg.Advanced.ImpressionsQueueSize, make(chan string, 1), logger),
|
||||
telemetry: mutexmap.NewMMMetricsStorage(),
|
||||
events: mutexqueue.NewMQEventsStorage(cfg.Advanced.EventsQueueSize, make(chan string, 1), logger),
|
||||
segments: mutexmap.NewMMSegmentStorage(),
|
||||
splits: splitStorage,
|
||||
impressions: mutexqueue.NewMQImpressionsStorage(cfg.Advanced.ImpressionsQueueSize, make(chan string, 1), logger, telemetryStorage),
|
||||
events: mutexqueue.NewMQEventsStorage(cfg.Advanced.EventsQueueSize, make(chan string, 1), logger, telemetryStorage),
|
||||
segments: mutexmap.NewMMSegmentStorage(),
|
||||
initTelemetry: telemetryStorage,
|
||||
evaluationTelemetry: telemetryStorage,
|
||||
runtimeTelemetry: telemetryStorage,
|
||||
},
|
||||
readinessSubscriptors: make(map[int]chan int),
|
||||
syncManager: syncManager,
|
||||
@@ -407,11 +481,12 @@ func setupLocalhostFactory(
|
||||
OperationMode: cfg.OperationMode,
|
||||
ImpressionsMode: cfg.ImpressionsMode,
|
||||
ListenerEnabled: cfg.Advanced.ImpressionListener != nil,
|
||||
}, nil)
|
||||
}, nil, telemetryStorage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
splitFactory.impressionManager = impressionManager
|
||||
setFactory(splitFactory.apikey, splitFactory.logger)
|
||||
|
||||
// Call fetching tasks as goroutine
|
||||
go splitFactory.initializationLocalhost(readyChannel)
|
||||
|
||||
13
vendor/github.com/splitio/go-client/v6/splitio/client/factory_tracker.go
сгенерированный
поставляемый
13
vendor/github.com/splitio/go-client/v6/splitio/client/factory_tracker.go
сгенерированный
поставляемый
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// factoryInstances factory tracker instantiations
|
||||
var factoryInstances = make(map[string]int64)
|
||||
var mutex = &sync.Mutex{}
|
||||
var mutex = &sync.RWMutex{}
|
||||
|
||||
func setFactory(apikey string, logger logging.LoggerInterface) {
|
||||
mutex.Lock()
|
||||
@@ -67,6 +67,15 @@ func NewSplitFactory(apikey string, cfg *conf.SplitSdkConfig) (*SplitFactory, er
|
||||
}
|
||||
|
||||
splitFactory, err := newFactory(apikey, cfg, logger)
|
||||
setFactory(apikey, logger)
|
||||
return splitFactory, err
|
||||
}
|
||||
|
||||
func getFactories() map[string]int64 {
|
||||
toReturn := make(map[string]int64)
|
||||
mutex.RLock()
|
||||
defer mutex.RUnlock()
|
||||
for k, v := range factoryInstances {
|
||||
toReturn[k] = v
|
||||
}
|
||||
return toReturn
|
||||
}
|
||||
|
||||
18
vendor/github.com/splitio/go-client/v6/splitio/client/manager.go
сгенерированный
поставляемый
18
vendor/github.com/splitio/go-client/v6/splitio/client/manager.go
сгенерированный
поставляемый
@@ -10,10 +10,11 @@ import (
|
||||
|
||||
// SplitManager provides information of the currently stored splits
|
||||
type SplitManager struct {
|
||||
splitStorage storage.SplitStorageConsumer
|
||||
validator inputValidation
|
||||
logger logging.LoggerInterface
|
||||
factory *SplitFactory
|
||||
splitStorage storage.SplitStorageConsumer
|
||||
validator inputValidation
|
||||
logger logging.LoggerInterface
|
||||
factory *SplitFactory
|
||||
initTelemetry storage.TelemetryConfigProducer
|
||||
}
|
||||
|
||||
// SplitView is a partial representation of a currently stored split
|
||||
@@ -51,7 +52,8 @@ func (m *SplitManager) SplitNames() []string {
|
||||
}
|
||||
|
||||
if !m.isReady() {
|
||||
m.logger.Warning("splitNames: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.logger.Warning("SplitNames: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.initTelemetry.RecordNonReadyUsage()
|
||||
}
|
||||
|
||||
return m.splitStorage.SplitNames()
|
||||
@@ -65,7 +67,8 @@ func (m *SplitManager) Splits() []SplitView {
|
||||
}
|
||||
|
||||
if !m.isReady() {
|
||||
m.logger.Warning("splits: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.logger.Warning("Splits: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.initTelemetry.RecordNonReadyUsage()
|
||||
}
|
||||
|
||||
splitViews := make([]SplitView, 0)
|
||||
@@ -84,7 +87,8 @@ func (m *SplitManager) Split(feature string) *SplitView {
|
||||
}
|
||||
|
||||
if !m.isReady() {
|
||||
m.logger.Warning("split: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.logger.Warning("Split: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method")
|
||||
m.initTelemetry.RecordNonReadyUsage()
|
||||
}
|
||||
|
||||
err := m.validator.ValidateManagerInputs(feature)
|
||||
|
||||
1
vendor/github.com/splitio/go-client/v6/splitio/conf/defaults.go
сгенерированный
поставляемый
1
vendor/github.com/splitio/go-client/v6/splitio/conf/defaults.go
сгенерированный
поставляемый
@@ -3,6 +3,7 @@ package conf
|
||||
const (
|
||||
defaultHTTPTimeout = 30
|
||||
defaultTaskPeriod = 60
|
||||
defaultTelemetrySync = 3600
|
||||
defaultRedisHost = "localhost"
|
||||
defaultRedisPort = 6379
|
||||
defaultRedisDb = 0
|
||||
|
||||
21
vendor/github.com/splitio/go-client/v6/splitio/conf/sdkconf.go
сгенерированный
поставляемый
21
vendor/github.com/splitio/go-client/v6/splitio/conf/sdkconf.go
сгенерированный
поставляемый
@@ -67,6 +67,7 @@ type TaskPeriods struct {
|
||||
CounterSync int
|
||||
LatencySync int
|
||||
EventsSync int
|
||||
TelemetrySync int
|
||||
}
|
||||
|
||||
// AdvancedConfig exposes more configurable parameters that can be used to further tailor the sdk to the user's needs
|
||||
@@ -83,6 +84,7 @@ type AdvancedConfig struct {
|
||||
SdkURL string
|
||||
EventsURL string
|
||||
StreamingServiceURL string
|
||||
TelemetryServiceURL string
|
||||
EventsBulkSize int64
|
||||
EventsQueueSize int
|
||||
ImpressionsQueueSize int
|
||||
@@ -126,9 +128,10 @@ func Default() *SplitSdkConfig {
|
||||
Prefix: "",
|
||||
},
|
||||
TaskPeriods: TaskPeriods{
|
||||
GaugeSync: defaultTaskPeriod,
|
||||
CounterSync: defaultTaskPeriod,
|
||||
LatencySync: defaultTaskPeriod,
|
||||
GaugeSync: defaultTelemetrySync,
|
||||
CounterSync: defaultTelemetrySync,
|
||||
LatencySync: defaultTelemetrySync,
|
||||
TelemetrySync: defaultTelemetrySync,
|
||||
ImpressionSync: defaultImpressionSyncOptimized,
|
||||
SegmentSync: defaultTaskPeriod,
|
||||
SplitSync: defaultTaskPeriod,
|
||||
@@ -139,6 +142,7 @@ func Default() *SplitSdkConfig {
|
||||
EventsURL: "",
|
||||
SdkURL: "",
|
||||
StreamingServiceURL: "",
|
||||
TelemetryServiceURL: "",
|
||||
HTTPTimeout: 0,
|
||||
ImpressionListener: nil,
|
||||
SegmentQueueSize: 500,
|
||||
@@ -203,14 +207,8 @@ func validConfigRates(cfg *SplitSdkConfig) error {
|
||||
if cfg.TaskPeriods.EventsSync < minEventSync {
|
||||
return fmt.Errorf("EventsSync must be >= %d. Actual is: %d", minEventSync, cfg.TaskPeriods.EventsSync)
|
||||
}
|
||||
if cfg.TaskPeriods.LatencySync < minTelemetrySync {
|
||||
return fmt.Errorf("LatencySync must be >= %d. Actual is: %d", minTelemetrySync, cfg.TaskPeriods.LatencySync)
|
||||
}
|
||||
if cfg.TaskPeriods.GaugeSync < minTelemetrySync {
|
||||
return fmt.Errorf("GaugeSync must be >= %d. Actual is: %d", minTelemetrySync, cfg.TaskPeriods.GaugeSync)
|
||||
}
|
||||
if cfg.TaskPeriods.CounterSync < minTelemetrySync {
|
||||
return fmt.Errorf("CounterSync must be >= %d. Actual is: %d", minTelemetrySync, cfg.TaskPeriods.CounterSync)
|
||||
if cfg.TaskPeriods.TelemetrySync < minTelemetrySync {
|
||||
return fmt.Errorf("TelemetrySync must be >= %d. Actual is: %d", minTelemetrySync, cfg.TaskPeriods.TelemetrySync)
|
||||
}
|
||||
if cfg.Advanced.SegmentWorkers <= 0 {
|
||||
return errors.New("Number of workers for fetching segments MUST be greater than zero")
|
||||
@@ -248,6 +246,7 @@ func Normalize(apikey string, cfg *SplitSdkConfig) error {
|
||||
cfg.Advanced.SdkURL = cfg.SplitSyncProxyURL
|
||||
cfg.Advanced.EventsURL = cfg.SplitSyncProxyURL
|
||||
cfg.Advanced.StreamingServiceURL = cfg.SplitSyncProxyURL
|
||||
cfg.Advanced.TelemetryServiceURL = cfg.SplitSyncProxyURL
|
||||
}
|
||||
|
||||
if !cfg.IPAddressesEnabled {
|
||||
|
||||
3
vendor/github.com/splitio/go-client/v6/splitio/conf/util.go
сгенерированный
поставляемый
3
vendor/github.com/splitio/go-client/v6/splitio/conf/util.go
сгенерированный
поставляемый
@@ -42,6 +42,9 @@ func NormalizeSDKConf(sdkConfig AdvancedConfig) conf.AdvancedConfig {
|
||||
if strings.TrimSpace(sdkConfig.StreamingServiceURL) != "" {
|
||||
config.StreamingServiceURL = sdkConfig.StreamingServiceURL
|
||||
}
|
||||
if strings.TrimSpace(sdkConfig.TelemetryServiceURL) != "" {
|
||||
config.TelemetryServiceURL = sdkConfig.TelemetryServiceURL
|
||||
}
|
||||
config.StreamingEnabled = sdkConfig.StreamingEnabled
|
||||
|
||||
return config
|
||||
|
||||
2
vendor/github.com/splitio/go-client/v6/splitio/version.go
сгенерированный
поставляемый
2
vendor/github.com/splitio/go-client/v6/splitio/version.go
сгенерированный
поставляемый
@@ -1,4 +1,4 @@
|
||||
package splitio
|
||||
|
||||
// Version contains a string with the split sdk version
|
||||
const Version = "6.0.2"
|
||||
const Version = "6.1.0"
|
||||
|
||||
Ссылка в новой задаче
Block a user