1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-17 18:06:15 -05:00
v2fly/common/session/context.go
Jebbs 2c5a714903
v5: Health Check & LeastLoad Strategy (#589)
* generate .pb.go

* health checker conf

* check logic

* implement ping

* fix check interval

* improve check results

* health check on add outbounds

* fix tests

* fix ping handler

* fix min rtt < 0

* random alive

* fix check all on add outbounds

* least load strategy

* conf codes optimize

* improve least load strategy

* improve health check on AddOutboundHandler

* cleanup results with scheduler
code optimize

* health ping timeout default 5s

* remove config of health ping round
round 1 seems to be good enough

* fix TestSimpleBalancer

* add TestLeastLoadBalancer

* add todos

* lint and test fix

* balancer fallback

* api health stats command

* add hc cmd to perform health checks
* rename 'health stats' cmd to hci
* many code optimizations

* fix typo

* select none if no match for baselines only config
> prev 'select 1' behavior can achieved by baselines+expected=1

* add LeastLoadStrategy tests

* don't select alive on no match, go to fallback

* api hci refactor
* more detailed info
* ready for future new strategies

* apply lint style

* refactor: strategies don't need ref of balancer

* change check interval unit to seconds
> to reduce influence caused by what is described by new added FIXME

* fix test

* RouterService->RoutingService

* Revert "generate .pb.go"

This reverts commit 0e6fa1be889470d0ad9692f7279da45c030e1919.

* make checks distributed
> but `api hc` is the exception

* BalancingStrategy interface optimize

* fix random selects unchecked

* upgrade cmd hci to bi & rename hc to bc
* bi shows all balancers, while hci shows only heath-check-enabled ones
* shows more info

* fix test

* api bi sort output

* update according to review

* remove checks on add outbound

* refactor: move health checker inside to strategy
* enables rounds setting for health ping
* restore the random behavior, no ping, no pick alive

> if future strategy based on HealthPing, just embed it like what LeastLoad does

* apply lint style

* code optimize

* fix typo

* update desc of bc bi

* ping with head
code optimize

* force rouds to 1 if checks not distributed

* leatload: select by standard deviations

* health ping refactor
* continuously applying results
* config is easier to understand
* checker interfaces simplifying

* add maxRTT config to filter away high delay nodes

* apply lint

* cost for leastload

* api bo to override balancer selecting

* fix health ping statistics & fix test

* check connectivity if ping fail

* add tolerance setting & more detailed bi output

* fix connectivity check

* optimize bi output

* should not put results when network is down

* fixes @_@

* mux optimize

* remove pause option of selecting overriding
> it causes data racing

* update bo desc

* fix potential racing

* simplify locking
* switch sync.Mutex to avoid potential racing
* add more tests
* code optimize

* code optimize

* fix connectivity check when url not set
2021-01-30 08:31:11 +08:00

101 lines
2.8 KiB
Go

package session
import "context"
type sessionKey int
const (
idSessionKey sessionKey = iota
inboundSessionKey
outboundSessionKey
contentSessionKey
muxPreferedSessionKey
sockoptSessionKey
handlerSessionKey
)
// ContextWithID returns a new context with the given ID.
func ContextWithID(ctx context.Context, id ID) context.Context {
return context.WithValue(ctx, idSessionKey, id)
}
// IDFromContext returns ID in this context, or 0 if not contained.
func IDFromContext(ctx context.Context) ID {
if id, ok := ctx.Value(idSessionKey).(ID); ok {
return id
}
return 0
}
func ContextWithInbound(ctx context.Context, inbound *Inbound) context.Context {
return context.WithValue(ctx, inboundSessionKey, inbound)
}
func InboundFromContext(ctx context.Context) *Inbound {
if inbound, ok := ctx.Value(inboundSessionKey).(*Inbound); ok {
return inbound
}
return nil
}
func ContextWithOutbound(ctx context.Context, outbound *Outbound) context.Context {
return context.WithValue(ctx, outboundSessionKey, outbound)
}
func OutboundFromContext(ctx context.Context) *Outbound {
if outbound, ok := ctx.Value(outboundSessionKey).(*Outbound); ok {
return outbound
}
return nil
}
func ContextWithContent(ctx context.Context, content *Content) context.Context {
return context.WithValue(ctx, contentSessionKey, content)
}
func ContentFromContext(ctx context.Context) *Content {
if content, ok := ctx.Value(contentSessionKey).(*Content); ok {
return content
}
return nil
}
// ContextWithMuxPrefered returns a new context with the given bool
func ContextWithMuxPrefered(ctx context.Context, forced bool) context.Context {
return context.WithValue(ctx, muxPreferedSessionKey, forced)
}
// MuxPreferedFromContext returns value in this context, or false if not contained.
func MuxPreferedFromContext(ctx context.Context) bool {
if val, ok := ctx.Value(muxPreferedSessionKey).(bool); ok {
return val
}
return false
}
// ContextWithSockopt returns a new context with Socket configs included
func ContextWithSockopt(ctx context.Context, s *Sockopt) context.Context {
return context.WithValue(ctx, sockoptSessionKey, s)
}
// SockoptFromContext returns Socket configs in this context, or nil if not contained.
func SockoptFromContext(ctx context.Context) *Sockopt {
if sockopt, ok := ctx.Value(sockoptSessionKey).(*Sockopt); ok {
return sockopt
}
return nil
}
// ContextWithHandler returns a new context with handler
func ContextWithHandler(ctx context.Context, handler *Handler) context.Context {
return context.WithValue(ctx, handlerSessionKey, handler)
}
// HandlerFromContext returns handler config in this context, or nil if not
func HandlerFromContext(ctx context.Context) *Handler {
if handler, ok := ctx.Value(handlerSessionKey).(*Handler); ok {
return handler
}
return nil
}