52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
|
package util
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"sync"
|
||
|
|
||
|
"forge.cadoles.com/cadoles/bouncer/internal/rule"
|
||
|
"github.com/pkg/errors"
|
||
|
"gitlab.com/wpetit/goweb/logger"
|
||
|
)
|
||
|
|
||
|
type RuleEngineFactoryFunc[V any, O any] func(ops O) (*rule.Engine[V], error)
|
||
|
|
||
|
type RevisionedRuleEngine[V any, O any] struct {
|
||
|
mutex sync.RWMutex
|
||
|
revision int
|
||
|
engine *rule.Engine[V]
|
||
|
factory RuleEngineFactoryFunc[V, O]
|
||
|
}
|
||
|
|
||
|
func (e *RevisionedRuleEngine[V, O]) Get(ctx context.Context, revision int, opts O) (*rule.Engine[V], error) {
|
||
|
e.mutex.RLock()
|
||
|
if revision == e.revision {
|
||
|
logger.Debug(ctx, "using cached rule engine", logger.F("layerRevision", revision))
|
||
|
|
||
|
defer e.mutex.RUnlock()
|
||
|
return e.engine, nil
|
||
|
}
|
||
|
e.mutex.RUnlock()
|
||
|
|
||
|
e.mutex.Lock()
|
||
|
defer e.mutex.Unlock()
|
||
|
|
||
|
logger.Debug(ctx, "creating rule engine", logger.F("layerRevision", revision))
|
||
|
|
||
|
engine, err := e.factory(opts)
|
||
|
if err != nil {
|
||
|
return nil, errors.WithStack(err)
|
||
|
}
|
||
|
|
||
|
e.engine = engine
|
||
|
e.revision = revision
|
||
|
|
||
|
return engine, nil
|
||
|
}
|
||
|
|
||
|
func NewRevisionedRuleEngine[V any, O any](factory RuleEngineFactoryFunc[V, O]) *RevisionedRuleEngine[V, O] {
|
||
|
return &RevisionedRuleEngine[V, O]{
|
||
|
factory: factory,
|
||
|
}
|
||
|
}
|