You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.4 KiB
69 lines
1.4 KiB
package collector |
|
|
|
import ( |
|
"fmt" |
|
"sync" |
|
|
|
"go-common/app/service/main/dapper/model" |
|
) |
|
|
|
type countBreaker struct { |
|
rmx sync.RWMutex |
|
n int |
|
slot map[string]struct{} |
|
} |
|
|
|
func (c *countBreaker) Break(key string) error { |
|
c.rmx.Lock() |
|
_, ok := c.slot[key] |
|
c.rmx.Unlock() |
|
if ok { |
|
return nil |
|
} |
|
c.rmx.Lock() |
|
c.slot[key] = struct{}{} |
|
l := len(c.slot) |
|
c.rmx.Unlock() |
|
if l <= c.n { |
|
return nil |
|
} |
|
return fmt.Errorf("%s reach limit number %d breaked", key, c.n) |
|
} |
|
|
|
func newCountBreaker(n int) *countBreaker { |
|
return &countBreaker{n: n, slot: make(map[string]struct{})} |
|
} |
|
|
|
type serviceBreaker struct { |
|
rmx sync.RWMutex |
|
n int |
|
slot map[string]*countBreaker |
|
} |
|
|
|
func (s *serviceBreaker) Process(span *model.Span) error { |
|
s.rmx.RLock() |
|
operationNameBreaker, ok1 := s.slot[span.ServiceName+"_o"] |
|
peerServiceBreaker, ok2 := s.slot[span.ServiceName+"_p"] |
|
s.rmx.RUnlock() |
|
if !ok1 || !ok2 { |
|
s.rmx.Lock() |
|
if !ok1 { |
|
operationNameBreaker = newCountBreaker(s.n) |
|
s.slot[span.ServiceName+"_o"] = operationNameBreaker |
|
} |
|
if !ok2 { |
|
peerServiceBreaker = newCountBreaker(s.n) |
|
s.slot[span.ServiceName+"_p"] = peerServiceBreaker |
|
} |
|
s.rmx.Unlock() |
|
} |
|
if err := operationNameBreaker.Break(span.OperationName); err != nil { |
|
return err |
|
} |
|
return peerServiceBreaker.Break(span.StringTag("peer.service")) |
|
} |
|
|
|
// NewServiceBreakerProcess . |
|
func NewServiceBreakerProcess(n int) Processer { |
|
return &serviceBreaker{n: n, slot: make(map[string]*countBreaker)} |
|
}
|
|
|