Started LDAP support

This commit is contained in:
2023-10-24 22:15:58 +02:00
parent 4a9a913d66
commit 7bcd00c97b
11 changed files with 669 additions and 82 deletions

113
util/genpool/genpool.go Normal file
View 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
}