Source File
bundler.go
Belonging Package
google.golang.org/api/support/bundler
package bundler
import (
)
type mode int
const (
DefaultDelayThreshold = time.Second
DefaultBundleCountThreshold = 10
DefaultBundleByteThreshold = 1e6 // 1M
DefaultBufferedByteLimit = 1e9 // 1G
)
const (
none mode = iota
add
addWait
)
ErrOverflow = errors.New("bundler reached buffered byte limit")
ErrOversizedItem = errors.New("item size exceeds bundle byte limit")
errMixedMethods = errors.New("calls to Add and AddWait cannot be mixed")
)
HandlerLimit int
handler func(interface{}) // called to handle a bundle
itemSliceZero reflect.Value // nil (zero value) for slice of items
mu sync.Mutex // guards access to fields below
flushTimer *time.Timer // implements DelayThreshold
handlerCount int // # of bundles currently being handled (i.e. handler is invoked on them)
sem *semaphore.Weighted // enforces BufferedByteLimit
}
func ( interface{}, func(interface{})) *Bundler {
:= &Bundler{
DelayThreshold: DefaultDelayThreshold,
BundleCountThreshold: DefaultBundleCountThreshold,
BundleByteThreshold: DefaultBundleByteThreshold,
BufferedByteLimit: DefaultBufferedByteLimit,
HandlerLimit: 1,
handler: ,
itemSliceZero: reflect.Zero(reflect.SliceOf(reflect.TypeOf())),
curFlush: &sync.WaitGroup{},
}
return
}
.semOnce.Do(func() {
.sem = semaphore.NewWeighted(int64(.BufferedByteLimit))
})
}
if .handlerCount < .HandlerLimit {
.handlerCount++
go .handle(.curBundle)
.head = .curBundle
.tail = .curBundle
}
.curBundle = nil
if .flushTimer != nil {
.flushTimer.Stop()
.flushTimer = nil
}
}
func ( *Bundler) ( *bundle, int) bool {
return (.BundleByteLimit <= 0 || .size+ <= .BundleByteLimit) &&
(.BundleCountThreshold <= 0 || .items.Len() < .BundleCountThreshold)
}
if .BundleByteLimit > 0 && > .BundleByteLimit {
return ErrOversizedItem
}
.initSemaphores()
if !.sem.TryAcquire(int64()) {
return ErrOverflow
}
.mu.Lock()
defer .mu.Unlock()
return .add(, )
}
if .curBundle != nil && !.canFit(.curBundle, ) {
.enqueueCurBundle()
}
if .curBundle.size >= .BundleByteThreshold ||
.curBundle.items.Len() == .BundleCountThreshold {
.enqueueCurBundle()
}
if .curBundle != nil && .flushTimer == nil {
.flushTimer = time.AfterFunc(.DelayThreshold, .tryHandleBundles)
}
return nil
}
if .BundleByteLimit > 0 && > .BundleByteLimit {
return ErrOversizedItem
if != nil {
<-
}
.Wait()
close()
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |