mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-04 05:40:13 +00:00
Integrate public as bindata optionally (#293)
* Dropped unused codekit config * Integrated dynamic and static bindata for public * Ignore public bindata * Add a general generate make task * Integrated flexible public assets into web command * Updated vendoring, added all missiong govendor deps * Made the linter happy with the bindata and dynamic code * Moved public bindata definition to modules directory * Ignoring the new bindata path now * Updated to the new public modules import path * Updated public bindata command and drop the new prefix
This commit is contained in:
parent
4680c349dd
commit
b6a95a8cb3
691 changed files with 305318 additions and 1272 deletions
214
vendor/github.com/ngaut/pools/roundrobin.go
generated
vendored
Normal file
214
vendor/github.com/ngaut/pools/roundrobin.go
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
// Copyright 2012, Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pools
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RoundRobin is deprecated. Use ResourcePool instead.
|
||||
// RoundRobin allows you to use a pool of resources in a round robin fashion.
|
||||
type RoundRobin struct {
|
||||
mu sync.Mutex
|
||||
available *sync.Cond
|
||||
resources chan fifoWrapper
|
||||
size int64
|
||||
factory Factory
|
||||
idleTimeout time.Duration
|
||||
|
||||
// stats
|
||||
waitCount int64
|
||||
waitTime time.Duration
|
||||
}
|
||||
|
||||
type fifoWrapper struct {
|
||||
resource Resource
|
||||
timeUsed time.Time
|
||||
}
|
||||
|
||||
// NewRoundRobin creates a new RoundRobin pool.
|
||||
// capacity is the maximum number of resources RoundRobin will create.
|
||||
// factory will be the function used to create resources.
|
||||
// If a resource is unused beyond idleTimeout, it's discarded.
|
||||
func NewRoundRobin(capacity int, idleTimeout time.Duration) *RoundRobin {
|
||||
r := &RoundRobin{
|
||||
resources: make(chan fifoWrapper, capacity),
|
||||
size: 0,
|
||||
idleTimeout: idleTimeout,
|
||||
}
|
||||
r.available = sync.NewCond(&r.mu)
|
||||
return r
|
||||
}
|
||||
|
||||
// Open starts allowing the creation of resources
|
||||
func (rr *RoundRobin) Open(factory Factory) {
|
||||
rr.mu.Lock()
|
||||
defer rr.mu.Unlock()
|
||||
rr.factory = factory
|
||||
}
|
||||
|
||||
// Close empties the pool calling Close on all its resources.
|
||||
// It waits for all resources to be returned (Put).
|
||||
func (rr *RoundRobin) Close() {
|
||||
rr.mu.Lock()
|
||||
defer rr.mu.Unlock()
|
||||
for rr.size > 0 {
|
||||
select {
|
||||
case fw := <-rr.resources:
|
||||
go fw.resource.Close()
|
||||
rr.size--
|
||||
default:
|
||||
rr.available.Wait()
|
||||
}
|
||||
}
|
||||
rr.factory = nil
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) IsClosed() bool {
|
||||
return rr.factory == nil
|
||||
}
|
||||
|
||||
// Get will return the next available resource. If none is available, and capacity
|
||||
// has not been reached, it will create a new one using the factory. Otherwise,
|
||||
// it will indefinitely wait till the next resource becomes available.
|
||||
func (rr *RoundRobin) Get() (resource Resource, err error) {
|
||||
return rr.get(true)
|
||||
}
|
||||
|
||||
// TryGet will return the next available resource. If none is available, and capacity
|
||||
// has not been reached, it will create a new one using the factory. Otherwise,
|
||||
// it will return nil with no error.
|
||||
func (rr *RoundRobin) TryGet() (resource Resource, err error) {
|
||||
return rr.get(false)
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) get(wait bool) (resource Resource, err error) {
|
||||
rr.mu.Lock()
|
||||
defer rr.mu.Unlock()
|
||||
// Any waits in this loop will release the lock, and it will be
|
||||
// reacquired before the waits return.
|
||||
for {
|
||||
select {
|
||||
case fw := <-rr.resources:
|
||||
// Found a free resource in the channel
|
||||
if rr.idleTimeout > 0 && fw.timeUsed.Add(rr.idleTimeout).Sub(time.Now()) < 0 {
|
||||
// resource has been idle for too long. Discard & go for next.
|
||||
go fw.resource.Close()
|
||||
rr.size--
|
||||
// Nobody else should be waiting, but signal anyway.
|
||||
rr.available.Signal()
|
||||
continue
|
||||
}
|
||||
return fw.resource, nil
|
||||
default:
|
||||
// resource channel is empty
|
||||
if rr.size >= int64(cap(rr.resources)) {
|
||||
// The pool is full
|
||||
if wait {
|
||||
start := time.Now()
|
||||
rr.available.Wait()
|
||||
rr.recordWait(start)
|
||||
continue
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
// Pool is not full. Create a resource.
|
||||
if resource, err = rr.waitForCreate(); err != nil {
|
||||
// size was decremented, and somebody could be waiting.
|
||||
rr.available.Signal()
|
||||
return nil, err
|
||||
}
|
||||
// Creation successful. Account for this by incrementing size.
|
||||
rr.size++
|
||||
return resource, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) recordWait(start time.Time) {
|
||||
rr.waitCount++
|
||||
rr.waitTime += time.Now().Sub(start)
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) waitForCreate() (resource Resource, err error) {
|
||||
// Prevent thundering herd: increment size before creating resource, and decrement after.
|
||||
rr.size++
|
||||
rr.mu.Unlock()
|
||||
defer func() {
|
||||
rr.mu.Lock()
|
||||
rr.size--
|
||||
}()
|
||||
return rr.factory()
|
||||
}
|
||||
|
||||
// Put will return a resource to the pool. You MUST return every resource to the pool,
|
||||
// even if it's closed. If a resource is closed, you should call Put(nil).
|
||||
func (rr *RoundRobin) Put(resource Resource) {
|
||||
rr.mu.Lock()
|
||||
defer rr.available.Signal()
|
||||
defer rr.mu.Unlock()
|
||||
|
||||
if rr.size > int64(cap(rr.resources)) {
|
||||
if resource != nil {
|
||||
go resource.Close()
|
||||
}
|
||||
rr.size--
|
||||
} else if resource == nil {
|
||||
rr.size--
|
||||
} else {
|
||||
if len(rr.resources) == cap(rr.resources) {
|
||||
panic("unexpected")
|
||||
}
|
||||
rr.resources <- fifoWrapper{resource, time.Now()}
|
||||
}
|
||||
}
|
||||
|
||||
// Set capacity changes the capacity of the pool.
|
||||
// You can use it to expand or shrink.
|
||||
func (rr *RoundRobin) SetCapacity(capacity int) error {
|
||||
rr.mu.Lock()
|
||||
defer rr.available.Broadcast()
|
||||
defer rr.mu.Unlock()
|
||||
|
||||
nr := make(chan fifoWrapper, capacity)
|
||||
// This loop transfers resources from the old channel
|
||||
// to the new one, until it fills up or runs out.
|
||||
// It discards extras, if any.
|
||||
for {
|
||||
select {
|
||||
case fw := <-rr.resources:
|
||||
if len(nr) < cap(nr) {
|
||||
nr <- fw
|
||||
} else {
|
||||
go fw.resource.Close()
|
||||
rr.size--
|
||||
}
|
||||
continue
|
||||
default:
|
||||
}
|
||||
break
|
||||
}
|
||||
rr.resources = nr
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) SetIdleTimeout(idleTimeout time.Duration) {
|
||||
rr.mu.Lock()
|
||||
defer rr.mu.Unlock()
|
||||
rr.idleTimeout = idleTimeout
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) StatsJSON() string {
|
||||
s, c, a, wc, wt, it := rr.Stats()
|
||||
return fmt.Sprintf("{\"Size\": %v, \"Capacity\": %v, \"Available\": %v, \"WaitCount\": %v, \"WaitTime\": %v, \"IdleTimeout\": %v}", s, c, a, wc, int64(wt), int64(it))
|
||||
}
|
||||
|
||||
func (rr *RoundRobin) Stats() (size, capacity, available, waitCount int64, waitTime, idleTimeout time.Duration) {
|
||||
rr.mu.Lock()
|
||||
defer rr.mu.Unlock()
|
||||
return rr.size, int64(cap(rr.resources)), int64(len(rr.resources)), rr.waitCount, rr.waitTime, rr.idleTimeout
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue