mirror of
https://github.com/retailcrm/mg-transport-core.git
synced 2024-11-22 05:06:04 +03:00
name support & slight changes in business logic
This commit is contained in:
parent
7bff09f467
commit
1c6689583a
@ -12,6 +12,7 @@ const DefaultResetPeriod = time.Minute * 15
|
|||||||
// AtomicCounter is a default Counter implementation.
|
// AtomicCounter is a default Counter implementation.
|
||||||
// It uses atomics under the hood (hence the name) and can be configured with custom reset timeout and
|
// It uses atomics under the hood (hence the name) and can be configured with custom reset timeout and
|
||||||
type AtomicCounter struct {
|
type AtomicCounter struct {
|
||||||
|
name atomic.String
|
||||||
msg atomic.String
|
msg atomic.String
|
||||||
timestamp atomic.Time
|
timestamp atomic.Time
|
||||||
resetPeriod time.Duration
|
resetPeriod time.Duration
|
||||||
@ -23,16 +24,25 @@ type AtomicCounter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewAtomicCounterWithPeriod returns AtomicCounter configured with provided period.
|
// NewAtomicCounterWithPeriod returns AtomicCounter configured with provided period.
|
||||||
func NewAtomicCounterWithPeriod(resetPeriod time.Duration) Counter {
|
func NewAtomicCounterWithPeriod(name string, resetPeriod time.Duration) Counter {
|
||||||
c := &AtomicCounter{}
|
c := &AtomicCounter{}
|
||||||
|
c.SetName(name)
|
||||||
c.resetPeriod = resetPeriod
|
c.resetPeriod = resetPeriod
|
||||||
c.timestamp.Store(time.Now())
|
c.timestamp.Store(time.Now())
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAtomicCounter returns AtomicCounter with DefaultResetPeriod.
|
// NewAtomicCounter returns AtomicCounter with DefaultResetPeriod.
|
||||||
func NewAtomicCounter() Counter {
|
func NewAtomicCounter(name string) Counter {
|
||||||
return NewAtomicCounterWithPeriod(DefaultResetPeriod)
|
return NewAtomicCounterWithPeriod(name, DefaultResetPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AtomicCounter) Name() string {
|
||||||
|
return a.name.Load()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AtomicCounter) SetName(name string) {
|
||||||
|
a.name.Store(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AtomicCounter) HitSuccess() {
|
func (a *AtomicCounter) HitSuccess() {
|
||||||
|
@ -3,7 +3,8 @@ package health
|
|||||||
// Storage stores different instances of Counter. Implementation should be goroutine-safe.
|
// Storage stores different instances of Counter. Implementation should be goroutine-safe.
|
||||||
type Storage interface {
|
type Storage interface {
|
||||||
// Get counter by its ID. The counter will be instantiated automatically if necessary.
|
// Get counter by its ID. The counter will be instantiated automatically if necessary.
|
||||||
Get(id int) Counter
|
// Name here is not used to identify the counter in the storage.
|
||||||
|
Get(id int, name string) Counter
|
||||||
// Remove counter if it exists.
|
// Remove counter if it exists.
|
||||||
Remove(id int)
|
Remove(id int)
|
||||||
// Process will iterate over counters and call Processor on each of them.
|
// Process will iterate over counters and call Processor on each of them.
|
||||||
@ -15,6 +16,10 @@ type Storage interface {
|
|||||||
// is not working properly (invalid credentials, too many failed requests, etc) and take further action based on the result.
|
// is not working properly (invalid credentials, too many failed requests, etc) and take further action based on the result.
|
||||||
// Implementation should be goroutine-safe.
|
// Implementation should be goroutine-safe.
|
||||||
type Counter interface {
|
type Counter interface {
|
||||||
|
// Name can be used as a more friendly identifier for the counter.
|
||||||
|
Name() string
|
||||||
|
// SetName of the counter.
|
||||||
|
SetName(name string)
|
||||||
// HitSuccess registers successful request. It should automatically clear error state because that state should be
|
// HitSuccess registers successful request. It should automatically clear error state because that state should be
|
||||||
// used only if error is totally unrecoverable.
|
// used only if error is totally unrecoverable.
|
||||||
HitSuccess()
|
HitSuccess()
|
||||||
@ -55,8 +60,8 @@ type Processor interface {
|
|||||||
|
|
||||||
// NotifyMessageLocalizer is the smallest subset of core.Localizer used in the
|
// NotifyMessageLocalizer is the smallest subset of core.Localizer used in the
|
||||||
type NotifyMessageLocalizer interface {
|
type NotifyMessageLocalizer interface {
|
||||||
SetLocale(string)
|
SetLocale(locale string)
|
||||||
GetLocalizedMessage(string) string
|
GetLocalizedTemplateMessage(messageID string, templateData map[string]interface{}) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyFunc will send notification about error to the system with provided credentials.
|
// NotifyFunc will send notification about error to the system with provided credentials.
|
||||||
@ -64,7 +69,7 @@ type NotifyMessageLocalizer interface {
|
|||||||
type NotifyFunc func(apiURL, apiKey, msg string)
|
type NotifyFunc func(apiURL, apiKey, msg string)
|
||||||
|
|
||||||
// CounterConstructor is used to create counters. This way you can implement your own counter and still use default CounterStorage.
|
// CounterConstructor is used to create counters. This way you can implement your own counter and still use default CounterStorage.
|
||||||
type CounterConstructor func() Counter
|
type CounterConstructor func(name string) Counter
|
||||||
|
|
||||||
// ConnectionDataProvider should return the connection credentials and language by counter ID.
|
// ConnectionDataProvider should return the connection credentials and language by counter ID.
|
||||||
// It's best to use account ID as a counter ID to be able to retrieve the necessary data as easy as possible.
|
// It's best to use account ID as a counter ID to be able to retrieve the necessary data as easy as possible.
|
||||||
|
@ -26,8 +26,8 @@ func (c CounterProcessor) Process(id int, counter Counter) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiURL, apiKey, lang := c.ConnectionDataProvider(id)
|
apiURL, apiKey, _ := c.ConnectionDataProvider(id)
|
||||||
c.Notifier(apiURL, apiKey, c.getErrorText(counter.Message(), lang))
|
c.Notifier(apiURL, apiKey, counter.Message())
|
||||||
counter.FailureProcessed()
|
counter.FailureProcessed()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -55,15 +55,15 @@ func (c CounterProcessor) Process(id int, counter Counter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apiURL, apiKey, lang := c.ConnectionDataProvider(id)
|
apiURL, apiKey, lang := c.ConnectionDataProvider(id)
|
||||||
c.Notifier(apiURL, apiKey, c.getErrorText(c.Error, lang))
|
c.Notifier(apiURL, apiKey, c.getErrorText(counter.Name(), c.Error, lang))
|
||||||
counter.CountersProcessed()
|
counter.CountersProcessed()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c CounterProcessor) getErrorText(msg, lang string) string {
|
func (c CounterProcessor) getErrorText(name, msg, lang string) string {
|
||||||
if c.Localizer == nil {
|
if c.Localizer == nil {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
c.Localizer.SetLocale(lang)
|
c.Localizer.SetLocale(lang)
|
||||||
return c.Localizer.GetLocalizedMessage(msg)
|
return c.Localizer.GetLocalizedTemplateMessage(msg, map[string]interface{}{"Name": name})
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,14 @@ func NewSyncMapStorage(constructor CounterConstructor) Storage {
|
|||||||
return &SyncMapStorage{constructor: constructor}
|
return &SyncMapStorage{constructor: constructor}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SyncMapStorage) Get(id int) Counter {
|
func (s *SyncMapStorage) Get(id int, name string) Counter {
|
||||||
val, found := s.m.Load(id)
|
val, found := s.m.Load(id)
|
||||||
if found {
|
if found {
|
||||||
|
counter := val.(Counter)
|
||||||
|
counter.SetName(name)
|
||||||
return val.(Counter)
|
return val.(Counter)
|
||||||
}
|
}
|
||||||
c := s.constructor()
|
c := s.constructor(name)
|
||||||
s.m.Store(id, c)
|
s.m.Store(id, c)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user