update dependencies (#296)

This commit is contained in:
tobi 2021-11-13 12:29:08 +01:00 committed by GitHub
commit 829a934d23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
124 changed files with 2453 additions and 1588 deletions

9
vendor/codeberg.org/gruf/go-nowish/LICENSE generated vendored Normal file
View file

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2021 gruf
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

3
vendor/codeberg.org/gruf/go-nowish/README.md generated vendored Normal file
View file

@ -0,0 +1,3 @@
a simple Go library with useful time utiities:
- Clock: a high performance clock giving a good "ish" representation of "now" (hence the name!)
- Timeout: a reusable structure for enforcing timeouts with a cancel

141
vendor/codeberg.org/gruf/go-nowish/time.go generated vendored Normal file
View file

@ -0,0 +1,141 @@
package nowish
import (
"sync"
"sync/atomic"
"time"
"unsafe"
)
// Start returns a new Clock instance initialized and
// started with the provided precision, along with the
// stop function for it's underlying timer
func Start(precision time.Duration) (*Clock, func()) {
c := Clock{}
return &c, c.Start(precision)
}
type Clock struct {
noCopy noCopy //nolint noCopy because a copy will fuck with atomics
// format stores the time formatting style string
format string
// valid indicates whether the current value stored in .Format is valid
valid uint32
// mutex protects writes to .Format, not because it would be unsafe, but
// because we want to minimize unnnecessary allocations
mutex sync.Mutex
// nowfmt is an unsafe pointer to the last-updated time format string
nowfmt unsafe.Pointer
// now is an unsafe pointer to the last-updated time.Time object
now unsafe.Pointer
}
// Start starts the clock with the provided precision, the
// returned function is the stop function for the underlying timer
func (c *Clock) Start(precision time.Duration) func() {
// Create ticker from duration
tick := time.NewTicker(precision)
// Set initial time
t := time.Now()
atomic.StorePointer(&c.now, unsafe.Pointer(&t))
// Set initial format
s := ""
atomic.StorePointer(&c.nowfmt, unsafe.Pointer(&s))
// If formatting string unset, set default
c.mutex.Lock()
if c.format == "" {
c.format = time.RFC822
}
c.mutex.Unlock()
// Start main routine
go c.run(tick)
// Return stop fn
return tick.Stop
}
// run is the internal clock ticking loop
func (c *Clock) run(tick *time.Ticker) {
for {
// Wait on tick
_, ok := <-tick.C
// Channel closed
if !ok {
break
}
// Update time
t := time.Now()
atomic.StorePointer(&c.now, unsafe.Pointer(&t))
// Invalidate format string
atomic.StoreUint32(&c.valid, 0)
}
}
// Now returns a good (ish) estimate of the current 'now' time
func (c *Clock) Now() time.Time {
return *(*time.Time)(atomic.LoadPointer(&c.now))
}
// NowFormat returns the formatted "now" time, cached until next tick and "now" updates
func (c *Clock) NowFormat() string {
// If format still valid, return this
if atomic.LoadUint32(&c.valid) == 1 {
return *(*string)(atomic.LoadPointer(&c.nowfmt))
}
// Get mutex lock
c.mutex.Lock()
// Double check still invalid
if atomic.LoadUint32(&c.valid) == 1 {
c.mutex.Unlock()
return *(*string)(atomic.LoadPointer(&c.nowfmt))
}
// Calculate time format
b := c.Now().AppendFormat(
make([]byte, 0, len(c.format)),
c.format,
)
// Update the stored value and set valid!
atomic.StorePointer(&c.nowfmt, unsafe.Pointer(&b))
atomic.StoreUint32(&c.valid, 1)
// Unlock and return
c.mutex.Unlock()
// Note:
// it's safe to do this conversion here
// because this byte slice will never change.
// and we have the direct pointer to it, we're
// not requesting it atomicly via c.Format
return *(*string)(unsafe.Pointer(&b))
}
// SetFormat sets the time format string used by .NowFormat()
func (c *Clock) SetFormat(format string) {
// Get mutex lock
c.mutex.Lock()
// Update time format
c.format = format
// Invalidate current format string
atomic.StoreUint32(&c.valid, 0)
// Unlock
c.mutex.Unlock()
}

118
vendor/codeberg.org/gruf/go-nowish/timeout.go generated vendored Normal file
View file

@ -0,0 +1,118 @@
package nowish
import (
"sync"
"sync/atomic"
"time"
)
// Timeout provides a reusable structure for enforcing timeouts with a cancel
type Timeout struct {
noCopy noCopy //nolint noCopy because a copy will mess with atomics
tk *time.Timer // tk is the underlying timeout-timer
ch syncer // ch is the cancel synchronization channel
wg sync.WaitGroup // wg is the waitgroup to hold .Start() until timeout goroutine started
st timeoutState // st stores the current timeout state (and protects concurrent use)
}
// NewTimeout returns a new Timeout instance
func NewTimeout() Timeout {
tk := time.NewTimer(time.Minute)
tk.Stop() // don't keep it running
return Timeout{
tk: tk,
ch: make(syncer),
}
}
func (t *Timeout) runTimeout(hook func()) {
t.wg.Add(1)
go func() {
cancelled := false
// Signal started
t.wg.Done()
select {
// Timeout reached
case <-t.tk.C:
if !t.st.stop() /* a sneaky cancel! */ {
t.ch.recv()
cancelled = true
defer t.ch.send()
}
// Cancel called
case <-t.ch:
cancelled = true
defer t.ch.send()
}
// Ensure timer stopped
if cancelled && !t.tk.Stop() {
<-t.tk.C
}
// Defer reset state
defer t.st.reset()
// If timed out call hook
if !cancelled {
hook()
}
}()
t.wg.Wait()
}
// Start starts the timer with supplied timeout. If timeout is reached before
// cancel then supplied timeout hook will be called. Error may be called if
// Timeout is already running when this function is called
func (t *Timeout) Start(d time.Duration, hook func()) {
if !t.st.start() {
panic("nowish: timeout already started")
}
t.runTimeout(hook)
t.tk.Reset(d)
}
// Cancel cancels the currently running timer. If a cancel is achieved, then
// this function will return after the timeout goroutine is finished
func (t *Timeout) Cancel() {
if !t.st.stop() {
return
}
t.ch.send()
t.ch.recv()
}
// timeoutState provides a thread-safe timeout state mechanism
type timeoutState uint32
// start attempts to start the state, must be already reset, returns success
func (t *timeoutState) start() bool {
return atomic.CompareAndSwapUint32((*uint32)(t), 0, 1)
}
// stop attempts to stop the state, must already be started, returns success
func (t *timeoutState) stop() bool {
return atomic.CompareAndSwapUint32((*uint32)(t), 1, 2)
}
// reset is fairly self explanatory
func (t *timeoutState) reset() {
atomic.StoreUint32((*uint32)(t), 0)
}
// syncer provides helpful receiver methods for a synchronization channel
type syncer (chan struct{})
// send blocks on sending an empty value down channel
func (s syncer) send() {
s <- struct{}{}
}
// recv blocks on receiving (and dropping) empty value from channel
func (s syncer) recv() {
<-s
}

10
vendor/codeberg.org/gruf/go-nowish/util.go generated vendored Normal file
View file

@ -0,0 +1,10 @@
package nowish
//nolint
type noCopy struct{}
//nolint
func (*noCopy) Lock() {}
//nolint
func (*noCopy) Unlock() {}