Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
291 lines
9.6 KiB
Go
291 lines
9.6 KiB
Go
package storage
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/splitio/go-split-commons/v7/dtos"
|
|
"github.com/splitio/go-toolkit/v5/datastructures/set"
|
|
)
|
|
|
|
// SplitStorageProducer should be implemented by structs that offer writing splits in storage
|
|
type SplitStorageProducer interface {
|
|
ChangeNumber() (int64, error)
|
|
Update(toAdd []dtos.SplitDTO, toRemove []dtos.SplitDTO, changeNumber int64)
|
|
KillLocally(splitName string, defaultTreatment string, changeNumber int64)
|
|
SetChangeNumber(changeNumber int64) error
|
|
}
|
|
|
|
// SplitStorageConsumer should be implemented by structs that offer reading splits from storage
|
|
type SplitStorageConsumer interface {
|
|
ChangeNumber() (int64, error)
|
|
All() []dtos.SplitDTO
|
|
FetchMany(splitNames []string) map[string]*dtos.SplitDTO
|
|
SegmentNames() *set.ThreadUnsafeSet // Not in Spec
|
|
LargeSegmentNames() *set.ThreadUnsafeSet // Not in Spec
|
|
Split(splitName string) *dtos.SplitDTO
|
|
SplitNames() []string
|
|
TrafficTypeExists(trafficType string) bool
|
|
GetNamesByFlagSets(sets []string) map[string][]string
|
|
GetAllFlagSetNames() []string
|
|
}
|
|
|
|
// SegmentStorageProducer interface should be implemented by all structs that offer writing segments
|
|
type SegmentStorageProducer interface {
|
|
Update(name string, toAdd *set.ThreadUnsafeSet, toRemove *set.ThreadUnsafeSet, changeNumber int64) error
|
|
SetChangeNumber(segmentName string, till int64) error
|
|
}
|
|
|
|
// SegmentStorageConsumer interface should be implemented by all structs that ofer reading segments
|
|
type SegmentStorageConsumer interface {
|
|
ChangeNumber(segmentName string) (int64, error)
|
|
Keys(segmentName string) *set.ThreadUnsafeSet
|
|
SegmentContainsKey(segmentName string, key string) (bool, error)
|
|
SegmentKeysCount() int64
|
|
}
|
|
|
|
// ImpressionStorageProducer interface should be impemented by structs that accept incoming impressions
|
|
type ImpressionStorageProducer interface {
|
|
LogImpressions(impressions []dtos.Impression) error
|
|
}
|
|
|
|
// DataDropper interface is used by dependants who need to drop data from a collection
|
|
type DataDropper interface {
|
|
Drop(size int64) error
|
|
}
|
|
|
|
// ImpressionMultiSdkConsumer defines the methods required to consume impressions
|
|
// from a stored shared by many sdks
|
|
type ImpressionMultiSdkConsumer interface {
|
|
Count() int64
|
|
PopNRaw(int64) ([]string, int64, error)
|
|
PopNWithMetadata(n int64) ([]dtos.ImpressionQueueObject, error)
|
|
}
|
|
|
|
// EventMultiSdkConsumer defines the methods required to consume events
|
|
// from a stored shared by many sdks
|
|
type EventMultiSdkConsumer interface {
|
|
Count() int64
|
|
PopNRaw(int64) ([]string, int64, error)
|
|
PopNWithMetadata(n int64) ([]dtos.QueueStoredEventDTO, error)
|
|
}
|
|
|
|
// UniqueKeysMultiSdkConsumer defines the methods required to consume unique keys
|
|
// from a stored shared by many sdks
|
|
type UniqueKeysMultiSdkConsumer interface {
|
|
Count() int64
|
|
PopNRaw(int64) ([]string, int64, error)
|
|
}
|
|
|
|
// ImpressionStorageConsumer interface should be implemented by structs that offer popping impressions
|
|
type ImpressionStorageConsumer interface {
|
|
Empty() bool
|
|
PopN(n int64) ([]dtos.Impression, error)
|
|
}
|
|
|
|
// EventStorageProducer interface should be implemented by structs that accept incoming events
|
|
type EventStorageProducer interface {
|
|
Push(event dtos.EventDTO, size int) error
|
|
}
|
|
|
|
// EventStorageConsumer interface should be implemented by structs that offer popping impressions
|
|
type EventStorageConsumer interface {
|
|
Empty() bool
|
|
PopN(n int64) ([]dtos.EventDTO, error)
|
|
}
|
|
|
|
// TelemetryStorageProducer interface should be implemented by struct that accepts incoming telemetry
|
|
type TelemetryStorageProducer interface {
|
|
TelemetryConfigProducer
|
|
TelemetryEvaluationProducer
|
|
TelemetryRuntimeProducer
|
|
}
|
|
|
|
// TelemetryRedisProducer interface redis
|
|
type TelemetryRedisProducer interface {
|
|
TelemetryConfigProducer
|
|
TelemetryEvaluationProducer
|
|
}
|
|
|
|
// TelemetryConfigProducer interface for config data
|
|
type TelemetryConfigProducer interface {
|
|
RecordConfigData(configData dtos.Config) error
|
|
RecordNonReadyUsage()
|
|
RecordBURTimeout()
|
|
RecordUniqueKeys(uniques dtos.Uniques) error
|
|
}
|
|
|
|
// TelemetryEvaluationProducer for evaluation
|
|
type TelemetryEvaluationProducer interface {
|
|
RecordLatency(method string, latency time.Duration)
|
|
RecordException(method string)
|
|
}
|
|
|
|
// TelemetryRuntimeProducer for runtime stats
|
|
type TelemetryRuntimeProducer interface {
|
|
AddTag(tag string)
|
|
RecordImpressionsStats(dataType int, count int64)
|
|
RecordEventsStats(dataType int, count int64)
|
|
RecordSuccessfulSync(resource int, when time.Time)
|
|
RecordSyncError(resource int, status int)
|
|
RecordSyncLatency(resource int, latency time.Duration)
|
|
RecordAuthRejections()
|
|
RecordTokenRefreshes()
|
|
RecordStreamingEvent(streamingEvent *dtos.StreamingEvent)
|
|
RecordSessionLength(session int64)
|
|
RecordUpdatesFromSSE(updateType int)
|
|
}
|
|
|
|
// TelemetryStorageConsumer interface should be implemented by structs that offer popping telemetry
|
|
type TelemetryStorageConsumer interface {
|
|
TelemetryConfigConsumer
|
|
TelemetryEvaluationConsumer
|
|
TelemetryRuntimeConsumer
|
|
}
|
|
|
|
// TelemetryConfigConsumer interface for config data
|
|
type TelemetryConfigConsumer interface {
|
|
GetNonReadyUsages() int64
|
|
GetBURTimeouts() int64
|
|
}
|
|
|
|
// TelemetryEvaluationConsumer for evaluation
|
|
type TelemetryEvaluationConsumer interface {
|
|
PopLatencies() dtos.MethodLatencies
|
|
PopExceptions() dtos.MethodExceptions
|
|
}
|
|
|
|
// TelemetryRuntimeConsumer for runtime stats
|
|
type TelemetryRuntimeConsumer interface {
|
|
GetImpressionsStats(dataType int) int64
|
|
GetEventsStats(dataType int) int64
|
|
GetLastSynchronization() dtos.LastSynchronization
|
|
PopHTTPErrors() dtos.HTTPErrors
|
|
PopHTTPLatencies() dtos.HTTPLatencies
|
|
PopAuthRejections() int64
|
|
PopTokenRefreshes() int64
|
|
PopStreamingEvents() []dtos.StreamingEvent
|
|
PopTags() []string
|
|
GetSessionLength() int64
|
|
PopUpdatesFromSSE() dtos.UpdatesFromSSE
|
|
}
|
|
|
|
// TelemetryPeeker interface
|
|
type TelemetryPeeker interface {
|
|
PeekHTTPLatencies(resource int) []int64
|
|
PeekHTTPErrors(resource int) map[int]int
|
|
}
|
|
|
|
// ImpressionsCountProducer interface
|
|
type ImpressionsCountProducer interface {
|
|
RecordImpressionsCount(impressions dtos.ImpressionsCountDTO) error
|
|
}
|
|
|
|
// ImpressionsCountProducer interface
|
|
type ImpressionsCountConsumer interface {
|
|
GetImpressionsCount() (*dtos.ImpressionsCountDTO, error)
|
|
}
|
|
|
|
type ImpressionsCountStorage interface {
|
|
ImpressionsCountConsumer
|
|
ImpressionsCountProducer
|
|
}
|
|
|
|
// --- Wide Interfaces
|
|
|
|
// SplitStorage wraps consumer & producer interfaces
|
|
// Note: Since go's interface composition does not (yet) support interface method overlap,
|
|
// extracting a common subset (.ChangeNumber()), embedding it in Both consumer & Producer,
|
|
// and then having a wide interface that embeds both (diamond composition), results in a compilation error.
|
|
// The only workaround so far is to explicitly define all the methods that make up the composed interface
|
|
type SplitStorage interface {
|
|
ChangeNumber() (int64, error)
|
|
Update(toAdd []dtos.SplitDTO, toRemove []dtos.SplitDTO, changeNumber int64)
|
|
KillLocally(splitName string, defaultTreatment string, changeNumber int64)
|
|
SetChangeNumber(changeNumber int64) error
|
|
All() []dtos.SplitDTO
|
|
FetchMany(splitNames []string) map[string]*dtos.SplitDTO
|
|
SegmentNames() *set.ThreadUnsafeSet // Not in Spec
|
|
LargeSegmentNames() *set.ThreadUnsafeSet // Not in Spec
|
|
Split(splitName string) *dtos.SplitDTO
|
|
SplitNames() []string
|
|
TrafficTypeExists(trafficType string) bool
|
|
GetNamesByFlagSets(sets []string) map[string][]string
|
|
GetAllFlagSetNames() []string
|
|
}
|
|
|
|
// SegmentStorage wraps consumer and producer interfaces
|
|
type SegmentStorage interface {
|
|
SegmentStorageProducer
|
|
SegmentStorageConsumer
|
|
}
|
|
|
|
// ImpressionStorage wraps consumer & producer interfaces
|
|
type ImpressionStorage interface {
|
|
ImpressionStorageConsumer
|
|
ImpressionStorageProducer
|
|
ImpressionMultiSdkConsumer
|
|
}
|
|
|
|
// EventsStorage wraps consumer and producer interfaces
|
|
type EventsStorage interface {
|
|
EventStorageConsumer
|
|
EventStorageProducer
|
|
}
|
|
|
|
// TelemetryStorage wraps consumer and producer interfaces
|
|
type TelemetryStorage interface {
|
|
TelemetryStorageConsumer
|
|
TelemetryStorageProducer
|
|
}
|
|
|
|
// Filter interfaces
|
|
type Filter interface {
|
|
Add(data string)
|
|
Contains(data string) bool
|
|
Clear()
|
|
}
|
|
|
|
// LargeSegmentStorageProducer interface should be implemented by all structs that offer writing large segments
|
|
type LargeSegmentStorageProducer interface {
|
|
SetChangeNumber(name string, till int64)
|
|
Update(name string, userKeys []string, till int64)
|
|
}
|
|
|
|
// SegmentStorageConsumer interface should be implemented by all structs that ofer reading large segments
|
|
type LargeSegmentStorageConsumer interface {
|
|
ChangeNumber(name string) int64
|
|
Count() int
|
|
LargeSegmentsForUser(userKey string) []string
|
|
IsInLargeSegment(name string, key string) (bool, error)
|
|
TotalKeys(name string) int
|
|
}
|
|
|
|
// LargeSegmentsStorage defines the interface for a per-user large segments storage
|
|
type LargeSegmentsStorage interface {
|
|
LargeSegmentStorageProducer
|
|
LargeSegmentStorageConsumer
|
|
}
|
|
|
|
// RuleBasedSegmentStorageProducer interface should be implemented by all structs that offer writing rule-based segments
|
|
type RuleBasedSegmentStorageProducer interface {
|
|
SetChangeNumber(till int64) error
|
|
Update(toAdd []dtos.RuleBasedSegmentDTO, toRemove []dtos.RuleBasedSegmentDTO, till int64)
|
|
Clear()
|
|
}
|
|
|
|
// RuleBasedStorageConsumer interface should be implemented by all structs that ofer reading rule-based segments
|
|
type RuleBasedSegmentStorageConsumer interface {
|
|
ChangeNumber() int64
|
|
All() []dtos.RuleBasedSegmentDTO
|
|
RuleBasedSegmentNames() []string
|
|
Contains(ruleBasedSegmentNames []string) bool
|
|
GetSegments() *set.ThreadUnsafeSet
|
|
GetRuleBasedSegmentByName(name string) (*dtos.RuleBasedSegmentDTO, error)
|
|
}
|
|
|
|
// RuleBasedSegmentsStorage defines the interface for a per-user rule-based segments storage
|
|
type RuleBasedSegmentsStorage interface {
|
|
RuleBasedSegmentStorageProducer
|
|
RuleBasedSegmentStorageConsumer
|
|
}
|