Select Git revision
registrar.go
registrar.go 2.49 KiB
package service
import (
"context"
"time"
"git.perx.ru/perxis/perxis-go/pkg/auth"
"git.perx.ru/perxis/perxis-go/pkg/extension"
retry "github.com/avast/retry-go/v4"
"go.uber.org/zap"
"google.golang.org/grpc"
)
const RegistrationDelay = time.Minute
// Registrar выполняет действия по регистрации и обновления регистрации расширений в менеджере расширений. Одновременно
// выполняется регистрация одного или нескольких расширений
type Registrar struct {
addr string
managerConn *grpc.ClientConn
manager extension.Manager
exts []extension.Extension
logger *zap.Logger
stopFn func() error
}
func NewRegistrar(addr string, man extension.Manager, exts []extension.Extension, logger *zap.Logger) *Registrar {
return &Registrar{
addr: addr,
manager: man,
exts: exts,
logger: logger,
}
}
func (reg *Registrar) register(ctx context.Context, manager extension.Manager, desc []*extension.ExtensionConnector) error {
err := retry.Do(
func() error {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := manager.RegisterExtensions(auth.WithSystem(ctx), desc...)
return err
},
retry.RetryIf(func(err error) bool { return err != nil }),
retry.OnRetry(func(n uint, err error) {
reg.logger.Warn("Fail to register extension", zap.Uint("Retry", n), zap.Error(err))
}),
retry.DelayType(retry.BackOffDelay),
retry.MaxDelay(2*time.Minute),
retry.Attempts(1000),
retry.Context(ctx),
)
if err == nil {
reg.logger.Debug("Extensions successful registered")
}
return err
}
func (reg *Registrar) Start() error {
registrationDelay := time.Duration(0)
regCtx, regStop := context.WithCancel(context.Background())
reg.stopFn = func() error {
regStop()
return nil
}
extList := make([]*extension.ExtensionConnector, 0, len(reg.exts))
for _, v := range reg.exts {
desc := *v.GetDescriptor()
desc.Url = reg.addr
extList = append(extList, &extension.ExtensionConnector{Descriptor: &desc})
}
reg.logger.Info("Start registration process")
go func() {
for {
select {
case <-time.After(registrationDelay):
reg.register(regCtx, reg.manager, extList)
registrationDelay = RegistrationDelay
case <-regCtx.Done():
reg.logger.Info("Stop registration process")
return
}
}
}()
return nil
}
func (reg *Registrar) Stop() error {
return reg.stopFn()
}