mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-04 13:50:39 +00:00
Support http service graceful restart (#416)
* support http service graceful restart * fix dependencies
This commit is contained in:
parent
fa60cf0ea4
commit
527c2dd665
20 changed files with 1919 additions and 3 deletions
35
vendor/github.com/facebookgo/stats/aggregation.go
generated
vendored
Normal file
35
vendor/github.com/facebookgo/stats/aggregation.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
package stats
|
||||
|
||||
import "sort"
|
||||
|
||||
// Average returns the average value
|
||||
func Average(values []float64) float64 {
|
||||
if len(values) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var val float64
|
||||
for _, point := range values {
|
||||
val += point
|
||||
}
|
||||
return val / float64(len(values))
|
||||
}
|
||||
|
||||
// Sum returns the sum of all the given values
|
||||
func Sum(values []float64) float64 {
|
||||
var val float64
|
||||
for _, point := range values {
|
||||
val += point
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// Percentiles returns a map containing the asked for percentiles
|
||||
func Percentiles(values []float64, percentiles map[string]float64) map[string]float64 {
|
||||
sort.Float64s(values)
|
||||
results := map[string]float64{}
|
||||
for label, p := range percentiles {
|
||||
results[label] = values[int(float64(len(values))*p)]
|
||||
}
|
||||
return results
|
||||
}
|
112
vendor/github.com/facebookgo/stats/counter.go
generated
vendored
Normal file
112
vendor/github.com/facebookgo/stats/counter.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
package stats
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Type is the type of aggregation of apply
|
||||
type Type int
|
||||
|
||||
const (
|
||||
AggregateAvg Type = iota
|
||||
AggregateSum
|
||||
AggregateHistogram
|
||||
)
|
||||
|
||||
var (
|
||||
// HistogramPercentiles is used to determine which percentiles to return for
|
||||
// SimpleCounter.Aggregate
|
||||
HistogramPercentiles = map[string]float64{
|
||||
"p50": 0.5,
|
||||
"p95": 0.95,
|
||||
"p99": 0.99,
|
||||
}
|
||||
|
||||
// MinSamplesForPercentiles is used by SimpleCounter.Aggregate to determine
|
||||
// what the minimum number of samples is required for percentile analysis
|
||||
MinSamplesForPercentiles = 10
|
||||
)
|
||||
|
||||
// Aggregates can be used to merge counters together. This is not goroutine safe
|
||||
type Aggregates map[string]Counter
|
||||
|
||||
// Add adds the counter for aggregation. This is not goroutine safe
|
||||
func (a Aggregates) Add(c Counter) error {
|
||||
key := c.FullKey()
|
||||
if counter, ok := a[key]; ok {
|
||||
if counter.GetType() != c.GetType() {
|
||||
return fmt.Errorf("stats: mismatched aggregation type for: %s", key)
|
||||
}
|
||||
counter.AddValues(c.GetValues()...)
|
||||
} else {
|
||||
a[key] = c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Counter is the interface used by Aggregates to merge counters together
|
||||
type Counter interface {
|
||||
// FullKey is used to uniquely identify the counter
|
||||
FullKey() string
|
||||
|
||||
// AddValues adds values for aggregation
|
||||
AddValues(...float64)
|
||||
|
||||
// GetValues returns the values for aggregation
|
||||
GetValues() []float64
|
||||
|
||||
// GetType returns the type of aggregation to apply
|
||||
GetType() Type
|
||||
}
|
||||
|
||||
// SimpleCounter is a basic implementation of the Counter interface
|
||||
type SimpleCounter struct {
|
||||
Key string
|
||||
Values []float64
|
||||
Type Type
|
||||
}
|
||||
|
||||
// FullKey is part of the Counter interace
|
||||
func (s *SimpleCounter) FullKey() string {
|
||||
return s.Key
|
||||
}
|
||||
|
||||
// GetValues is part of the Counter interface
|
||||
func (s *SimpleCounter) GetValues() []float64 {
|
||||
return s.Values
|
||||
}
|
||||
|
||||
// AddValues is part of the Counter interface
|
||||
func (s *SimpleCounter) AddValues(vs ...float64) {
|
||||
s.Values = append(s.Values, vs...)
|
||||
}
|
||||
|
||||
// GetType is part of the Counter interface
|
||||
func (s *SimpleCounter) GetType() Type {
|
||||
return s.Type
|
||||
}
|
||||
|
||||
// Aggregate aggregates the provided values appropriately, returning a map
|
||||
// from key to value. If AggregateHistogram is specified, the map will contain
|
||||
// the relevant percentiles as specified by HistogramPercentiles
|
||||
func (s *SimpleCounter) Aggregate() map[string]float64 {
|
||||
switch s.Type {
|
||||
case AggregateAvg:
|
||||
return map[string]float64{
|
||||
s.Key: Average(s.Values),
|
||||
}
|
||||
case AggregateSum:
|
||||
return map[string]float64{
|
||||
s.Key: Sum(s.Values),
|
||||
}
|
||||
case AggregateHistogram:
|
||||
histogram := map[string]float64{
|
||||
s.Key: Average(s.Values),
|
||||
}
|
||||
if len(s.Values) > MinSamplesForPercentiles {
|
||||
for k, v := range Percentiles(s.Values, HistogramPercentiles) {
|
||||
histogram[fmt.Sprintf("%s.%s", s.Key, k)] = v
|
||||
}
|
||||
}
|
||||
return histogram
|
||||
}
|
||||
panic("stats: unsupported aggregation type")
|
||||
}
|
30
vendor/github.com/facebookgo/stats/license
generated
vendored
Normal file
30
vendor/github.com/facebookgo/stats/license
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
BSD License
|
||||
|
||||
For stats software
|
||||
|
||||
Copyright (c) 2015, Facebook, Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name Facebook nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
33
vendor/github.com/facebookgo/stats/patents
generated
vendored
Normal file
33
vendor/github.com/facebookgo/stats/patents
generated
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
Additional Grant of Patent Rights Version 2
|
||||
|
||||
"Software" means the stats software distributed by Facebook, Inc.
|
||||
|
||||
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
|
||||
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
|
||||
(subject to the termination provision below) license under any Necessary
|
||||
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
|
||||
transfer the Software. For avoidance of doubt, no license is granted under
|
||||
Facebook’s rights in any patent claims that are infringed by (i) modifications
|
||||
to the Software made by you or any third party or (ii) the Software in
|
||||
combination with any software or other technology.
|
||||
|
||||
The license granted hereunder will terminate, automatically and without notice,
|
||||
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
|
||||
directly or indirectly, or take a direct financial interest in, any Patent
|
||||
Assertion: (i) against Facebook or any of its subsidiaries or corporate
|
||||
affiliates, (ii) against any party if such Patent Assertion arises in whole or
|
||||
in part from any software, technology, product or service of Facebook or any of
|
||||
its subsidiaries or corporate affiliates, or (iii) against any party relating
|
||||
to the Software. Notwithstanding the foregoing, if Facebook or any of its
|
||||
subsidiaries or corporate affiliates files a lawsuit alleging patent
|
||||
infringement against you in the first instance, and you respond by filing a
|
||||
patent infringement counterclaim in that lawsuit against that party that is
|
||||
unrelated to the Software, the license granted hereunder will not terminate
|
||||
under section (i) of this paragraph due to such counterclaim.
|
||||
|
||||
A "Necessary Claim" is a claim of a patent owned by Facebook that is
|
||||
necessarily infringed by the Software standing alone.
|
||||
|
||||
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
|
||||
or contributory infringement or inducement to infringe any patent, including a
|
||||
cross-claim or counterclaim.
|
4
vendor/github.com/facebookgo/stats/readme.md
generated
vendored
Normal file
4
vendor/github.com/facebookgo/stats/readme.md
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
stats [](https://travis-ci.org/facebookgo/stats)
|
||||
=====
|
||||
|
||||
Documentation: https://godoc.org/github.com/facebookgo/stats
|
166
vendor/github.com/facebookgo/stats/stats.go
generated
vendored
Normal file
166
vendor/github.com/facebookgo/stats/stats.go
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
// Package stats defines a lightweight interface for collecting statistics. It
|
||||
// doesn't provide an implementation, just the shared interface.
|
||||
package stats
|
||||
|
||||
// Client provides methods to collection statistics.
|
||||
type Client interface {
|
||||
// BumpAvg bumps the average for the given key.
|
||||
BumpAvg(key string, val float64)
|
||||
|
||||
// BumpSum bumps the sum for the given key.
|
||||
BumpSum(key string, val float64)
|
||||
|
||||
// BumpHistogram bumps the histogram for the given key.
|
||||
BumpHistogram(key string, val float64)
|
||||
|
||||
// BumpTime is a special version of BumpHistogram which is specialized for
|
||||
// timers. Calling it starts the timer, and it returns a value on which End()
|
||||
// can be called to indicate finishing the timer. A convenient way of
|
||||
// recording the duration of a function is calling it like such at the top of
|
||||
// the function:
|
||||
//
|
||||
// defer s.BumpTime("my.function").End()
|
||||
BumpTime(key string) interface {
|
||||
End()
|
||||
}
|
||||
}
|
||||
|
||||
// PrefixClient adds multiple keys for the same value, with each prefix
|
||||
// added to the key and calls the underlying client.
|
||||
func PrefixClient(prefixes []string, client Client) Client {
|
||||
return &prefixClient{
|
||||
Prefixes: prefixes,
|
||||
Client: client,
|
||||
}
|
||||
}
|
||||
|
||||
type prefixClient struct {
|
||||
Prefixes []string
|
||||
Client Client
|
||||
}
|
||||
|
||||
func (p *prefixClient) BumpAvg(key string, val float64) {
|
||||
for _, prefix := range p.Prefixes {
|
||||
p.Client.BumpAvg(prefix+key, val)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *prefixClient) BumpSum(key string, val float64) {
|
||||
for _, prefix := range p.Prefixes {
|
||||
p.Client.BumpSum(prefix+key, val)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *prefixClient) BumpHistogram(key string, val float64) {
|
||||
for _, prefix := range p.Prefixes {
|
||||
p.Client.BumpHistogram(prefix+key, val)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *prefixClient) BumpTime(key string) interface {
|
||||
End()
|
||||
} {
|
||||
var m multiEnder
|
||||
for _, prefix := range p.Prefixes {
|
||||
m = append(m, p.Client.BumpTime(prefix+key))
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// multiEnder combines many enders together.
|
||||
type multiEnder []interface {
|
||||
End()
|
||||
}
|
||||
|
||||
func (m multiEnder) End() {
|
||||
for _, e := range m {
|
||||
e.End()
|
||||
}
|
||||
}
|
||||
|
||||
// HookClient is useful for testing. It provides optional hooks for each
|
||||
// expected method in the interface, which if provided will be called. If a
|
||||
// hook is not provided, it will be ignored.
|
||||
type HookClient struct {
|
||||
BumpAvgHook func(key string, val float64)
|
||||
BumpSumHook func(key string, val float64)
|
||||
BumpHistogramHook func(key string, val float64)
|
||||
BumpTimeHook func(key string) interface {
|
||||
End()
|
||||
}
|
||||
}
|
||||
|
||||
// BumpAvg will call BumpAvgHook if defined.
|
||||
func (c *HookClient) BumpAvg(key string, val float64) {
|
||||
if c.BumpAvgHook != nil {
|
||||
c.BumpAvgHook(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpSum will call BumpSumHook if defined.
|
||||
func (c *HookClient) BumpSum(key string, val float64) {
|
||||
if c.BumpSumHook != nil {
|
||||
c.BumpSumHook(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpHistogram will call BumpHistogramHook if defined.
|
||||
func (c *HookClient) BumpHistogram(key string, val float64) {
|
||||
if c.BumpHistogramHook != nil {
|
||||
c.BumpHistogramHook(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpTime will call BumpTimeHook if defined.
|
||||
func (c *HookClient) BumpTime(key string) interface {
|
||||
End()
|
||||
} {
|
||||
if c.BumpTimeHook != nil {
|
||||
return c.BumpTimeHook(key)
|
||||
}
|
||||
return NoOpEnd
|
||||
}
|
||||
|
||||
type noOpEnd struct{}
|
||||
|
||||
func (n noOpEnd) End() {}
|
||||
|
||||
// NoOpEnd provides a dummy value for use in tests as valid return value for
|
||||
// BumpTime().
|
||||
var NoOpEnd = noOpEnd{}
|
||||
|
||||
// BumpAvg calls BumpAvg on the Client if it isn't nil. This is useful when a
|
||||
// component has an optional stats.Client.
|
||||
func BumpAvg(c Client, key string, val float64) {
|
||||
if c != nil {
|
||||
c.BumpAvg(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpSum calls BumpSum on the Client if it isn't nil. This is useful when a
|
||||
// component has an optional stats.Client.
|
||||
func BumpSum(c Client, key string, val float64) {
|
||||
if c != nil {
|
||||
c.BumpSum(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpHistogram calls BumpHistogram on the Client if it isn't nil. This is
|
||||
// useful when a component has an optional stats.Client.
|
||||
func BumpHistogram(c Client, key string, val float64) {
|
||||
if c != nil {
|
||||
c.BumpHistogram(key, val)
|
||||
}
|
||||
}
|
||||
|
||||
// BumpTime calls BumpTime on the Client if it isn't nil. If the Client is nil
|
||||
// it still returns a valid return value which will be a no-op. This is useful
|
||||
// when a component has an optional stats.Client.
|
||||
func BumpTime(c Client, key string) interface {
|
||||
End()
|
||||
} {
|
||||
if c != nil {
|
||||
return c.BumpTime(key)
|
||||
}
|
||||
return NoOpEnd
|
||||
}
|
17
vendor/github.com/facebookgo/stats/stopper.go
generated
vendored
Normal file
17
vendor/github.com/facebookgo/stats/stopper.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package stats
|
||||
|
||||
import "time"
|
||||
|
||||
// Stopper calls Client.BumpSum and Client.BumpHistogram when End'ed
|
||||
type Stopper struct {
|
||||
Key string
|
||||
Start time.Time
|
||||
Client Client
|
||||
}
|
||||
|
||||
// End the Stopper
|
||||
func (s *Stopper) End() {
|
||||
since := time.Since(s.Start).Seconds() * 1000.0
|
||||
s.Client.BumpSum(s.Key+".total", since)
|
||||
s.Client.BumpHistogram(s.Key, since)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue