Started LDAP support
This commit is contained in:
113
util/genpool/genpool.go
Normal file
113
util/genpool/genpool.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package genpool
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrPoolClosed = errors.New("pool already closed")
|
||||
)
|
||||
|
||||
type getResp[Item interface{}] struct {
|
||||
Item *Item
|
||||
err error
|
||||
}
|
||||
|
||||
type poolReq[Item interface{}] struct {
|
||||
get chan<- getResp[Item]
|
||||
ret *Item
|
||||
}
|
||||
|
||||
type PoolManager[Item interface{}] interface {
|
||||
Destroy(*Item)
|
||||
Create() (*Item, error)
|
||||
Validate(*Item) bool
|
||||
}
|
||||
|
||||
type poolBackend[Item interface{}] struct {
|
||||
manager PoolManager[Item]
|
||||
pool []*Item
|
||||
}
|
||||
|
||||
func (b *poolBackend[Item]) run(ch <-chan poolReq[Item]) {
|
||||
defer func() {
|
||||
for _, item := range b.pool {
|
||||
b.manager.Destroy(item)
|
||||
}
|
||||
}()
|
||||
for req := range ch {
|
||||
if req.get != nil {
|
||||
// fetch an item
|
||||
for {
|
||||
if len(b.pool) > 0 {
|
||||
item := b.pool[len(b.pool)-1]
|
||||
b.pool = b.pool[:len(b.pool)-1]
|
||||
if b.manager.Validate(item) {
|
||||
req.get <- getResp[Item]{
|
||||
Item: item,
|
||||
err: nil,
|
||||
}
|
||||
break
|
||||
} else {
|
||||
b.manager.Destroy(item)
|
||||
}
|
||||
} else {
|
||||
// last item
|
||||
item, err := b.manager.Create()
|
||||
req.get <- getResp[Item]{
|
||||
Item: item,
|
||||
err: err,
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if req.ret != nil {
|
||||
// return an item to the pool
|
||||
if cap(b.pool) > len(b.pool) {
|
||||
b.pool = append(b.pool, req.ret)
|
||||
} else {
|
||||
b.manager.Destroy(req.ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type Pool[Item interface{}] struct {
|
||||
req chan<- poolReq[Item]
|
||||
}
|
||||
|
||||
func NewPool[Item interface{}](manager PoolManager[Item], capacity int) Pool[Item] {
|
||||
cmdChan := make(chan poolReq[Item])
|
||||
backend := poolBackend[Item]{
|
||||
manager: manager,
|
||||
pool: make([]*Item, 0, capacity),
|
||||
}
|
||||
go backend.run(cmdChan)
|
||||
return Pool[Item]{
|
||||
req: cmdChan,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pool[Item]) Get() (*Item, error) {
|
||||
retCh := make(chan getResp[Item])
|
||||
p.req <- poolReq[Item]{
|
||||
get: retCh,
|
||||
}
|
||||
item, ok := <-retCh
|
||||
if ok {
|
||||
return item.Item, item.err
|
||||
} else {
|
||||
return nil, ErrPoolClosed
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pool[Item]) Put(item *Item) {
|
||||
p.req <- poolReq[Item]{
|
||||
ret: item,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Pool[Item]) Close() {
|
||||
close(p.req)
|
||||
p.req = nil
|
||||
}
|
||||
31
util/startup/startup.go
Normal file
31
util/startup/startup.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package startup
|
||||
|
||||
// Pre-defined queues...
|
||||
var (
|
||||
Logger StartupQueue
|
||||
PostFlags StartupQueue
|
||||
)
|
||||
|
||||
type StartupQueue struct {
|
||||
items []func()
|
||||
hasRun bool
|
||||
}
|
||||
|
||||
func (q *StartupQueue) Add(initFn ...func()) {
|
||||
if q.hasRun {
|
||||
panic("Added init function after startup")
|
||||
}
|
||||
for _, fn := range initFn {
|
||||
q.items = append(q.items, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *StartupQueue) Run() {
|
||||
if q.hasRun {
|
||||
panic("Attempted to run init function twice")
|
||||
}
|
||||
q.hasRun = true
|
||||
for _, fn := range q.items {
|
||||
fn()
|
||||
}
|
||||
}
|
||||
12
util/util.go
Normal file
12
util/util.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package util
|
||||
|
||||
import "os"
|
||||
|
||||
func GetEnvDefault(name string, def string) string {
|
||||
env, exist := os.LookupEnv(name)
|
||||
if exist {
|
||||
return env
|
||||
} else {
|
||||
return def
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user