mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-30 22:11:07 +00:00 
			
		
		
		
	* Allow common redis and leveldb connections Prevents multiple reopening of redis and leveldb connections to the same place by sharing connections. Further allows for more configurable redis connection type using the redisURI and a leveldbURI scheme. Signed-off-by: Andrew Thornton <art27@cantab.net> * add unit-test Signed-off-by: Andrew Thornton <art27@cantab.net> * as per @lunny Signed-off-by: Andrew Thornton <art27@cantab.net> * add test Signed-off-by: Andrew Thornton <art27@cantab.net> * Update modules/cache/cache_redis.go * Update modules/queue/queue_disk.go * Update modules/cache/cache_redis.go * Update modules/cache/cache_redis.go * Update modules/queue/unique_queue_disk.go * Update modules/queue/queue_disk.go * Update modules/queue/unique_queue_disk.go * Update modules/session/redis.go Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: Lauris BH <lauris@nix.lv>
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package redis
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"crypto/tls"
 | |
| 	"net"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| // UniversalOptions information is required by UniversalClient to establish
 | |
| // connections.
 | |
| type UniversalOptions struct {
 | |
| 	// Either a single address or a seed list of host:port addresses
 | |
| 	// of cluster/sentinel nodes.
 | |
| 	Addrs []string
 | |
| 
 | |
| 	// Database to be selected after connecting to the server.
 | |
| 	// Only single-node and failover clients.
 | |
| 	DB int
 | |
| 
 | |
| 	// Common options.
 | |
| 
 | |
| 	Dialer             func(ctx context.Context, network, addr string) (net.Conn, error)
 | |
| 	OnConnect          func(*Conn) error
 | |
| 	Username           string
 | |
| 	Password           string
 | |
| 	MaxRetries         int
 | |
| 	MinRetryBackoff    time.Duration
 | |
| 	MaxRetryBackoff    time.Duration
 | |
| 	DialTimeout        time.Duration
 | |
| 	ReadTimeout        time.Duration
 | |
| 	WriteTimeout       time.Duration
 | |
| 	PoolSize           int
 | |
| 	MinIdleConns       int
 | |
| 	MaxConnAge         time.Duration
 | |
| 	PoolTimeout        time.Duration
 | |
| 	IdleTimeout        time.Duration
 | |
| 	IdleCheckFrequency time.Duration
 | |
| 	TLSConfig          *tls.Config
 | |
| 
 | |
| 	// Only cluster clients.
 | |
| 
 | |
| 	MaxRedirects   int
 | |
| 	ReadOnly       bool
 | |
| 	RouteByLatency bool
 | |
| 	RouteRandomly  bool
 | |
| 
 | |
| 	// The sentinel master name.
 | |
| 	// Only failover clients.
 | |
| 	MasterName string
 | |
| }
 | |
| 
 | |
| // Cluster returns cluster options created from the universal options.
 | |
| func (o *UniversalOptions) Cluster() *ClusterOptions {
 | |
| 	if len(o.Addrs) == 0 {
 | |
| 		o.Addrs = []string{"127.0.0.1:6379"}
 | |
| 	}
 | |
| 
 | |
| 	return &ClusterOptions{
 | |
| 		Addrs:     o.Addrs,
 | |
| 		Dialer:    o.Dialer,
 | |
| 		OnConnect: o.OnConnect,
 | |
| 
 | |
| 		Username: o.Username,
 | |
| 		Password: o.Password,
 | |
| 
 | |
| 		MaxRedirects:   o.MaxRedirects,
 | |
| 		ReadOnly:       o.ReadOnly,
 | |
| 		RouteByLatency: o.RouteByLatency,
 | |
| 		RouteRandomly:  o.RouteRandomly,
 | |
| 
 | |
| 		MaxRetries:      o.MaxRetries,
 | |
| 		MinRetryBackoff: o.MinRetryBackoff,
 | |
| 		MaxRetryBackoff: o.MaxRetryBackoff,
 | |
| 
 | |
| 		DialTimeout:        o.DialTimeout,
 | |
| 		ReadTimeout:        o.ReadTimeout,
 | |
| 		WriteTimeout:       o.WriteTimeout,
 | |
| 		PoolSize:           o.PoolSize,
 | |
| 		MinIdleConns:       o.MinIdleConns,
 | |
| 		MaxConnAge:         o.MaxConnAge,
 | |
| 		PoolTimeout:        o.PoolTimeout,
 | |
| 		IdleTimeout:        o.IdleTimeout,
 | |
| 		IdleCheckFrequency: o.IdleCheckFrequency,
 | |
| 
 | |
| 		TLSConfig: o.TLSConfig,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Failover returns failover options created from the universal options.
 | |
| func (o *UniversalOptions) Failover() *FailoverOptions {
 | |
| 	if len(o.Addrs) == 0 {
 | |
| 		o.Addrs = []string{"127.0.0.1:26379"}
 | |
| 	}
 | |
| 
 | |
| 	return &FailoverOptions{
 | |
| 		SentinelAddrs: o.Addrs,
 | |
| 		MasterName:    o.MasterName,
 | |
| 
 | |
| 		Dialer:    o.Dialer,
 | |
| 		OnConnect: o.OnConnect,
 | |
| 
 | |
| 		DB:       o.DB,
 | |
| 		Username: o.Username,
 | |
| 		Password: o.Password,
 | |
| 
 | |
| 		MaxRetries:      o.MaxRetries,
 | |
| 		MinRetryBackoff: o.MinRetryBackoff,
 | |
| 		MaxRetryBackoff: o.MaxRetryBackoff,
 | |
| 
 | |
| 		DialTimeout:  o.DialTimeout,
 | |
| 		ReadTimeout:  o.ReadTimeout,
 | |
| 		WriteTimeout: o.WriteTimeout,
 | |
| 
 | |
| 		PoolSize:           o.PoolSize,
 | |
| 		MinIdleConns:       o.MinIdleConns,
 | |
| 		MaxConnAge:         o.MaxConnAge,
 | |
| 		PoolTimeout:        o.PoolTimeout,
 | |
| 		IdleTimeout:        o.IdleTimeout,
 | |
| 		IdleCheckFrequency: o.IdleCheckFrequency,
 | |
| 
 | |
| 		TLSConfig: o.TLSConfig,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Simple returns basic options created from the universal options.
 | |
| func (o *UniversalOptions) Simple() *Options {
 | |
| 	addr := "127.0.0.1:6379"
 | |
| 	if len(o.Addrs) > 0 {
 | |
| 		addr = o.Addrs[0]
 | |
| 	}
 | |
| 
 | |
| 	return &Options{
 | |
| 		Addr:      addr,
 | |
| 		Dialer:    o.Dialer,
 | |
| 		OnConnect: o.OnConnect,
 | |
| 
 | |
| 		DB:       o.DB,
 | |
| 		Username: o.Username,
 | |
| 		Password: o.Password,
 | |
| 
 | |
| 		MaxRetries:      o.MaxRetries,
 | |
| 		MinRetryBackoff: o.MinRetryBackoff,
 | |
| 		MaxRetryBackoff: o.MaxRetryBackoff,
 | |
| 
 | |
| 		DialTimeout:  o.DialTimeout,
 | |
| 		ReadTimeout:  o.ReadTimeout,
 | |
| 		WriteTimeout: o.WriteTimeout,
 | |
| 
 | |
| 		PoolSize:           o.PoolSize,
 | |
| 		MinIdleConns:       o.MinIdleConns,
 | |
| 		MaxConnAge:         o.MaxConnAge,
 | |
| 		PoolTimeout:        o.PoolTimeout,
 | |
| 		IdleTimeout:        o.IdleTimeout,
 | |
| 		IdleCheckFrequency: o.IdleCheckFrequency,
 | |
| 
 | |
| 		TLSConfig: o.TLSConfig,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // --------------------------------------------------------------------
 | |
| 
 | |
| // UniversalClient is an abstract client which - based on the provided options -
 | |
| // can connect to either clusters, or sentinel-backed failover instances
 | |
| // or simple single-instance servers. This can be useful for testing
 | |
| // cluster-specific applications locally.
 | |
| type UniversalClient interface {
 | |
| 	Cmdable
 | |
| 	Context() context.Context
 | |
| 	AddHook(Hook)
 | |
| 	Watch(fn func(*Tx) error, keys ...string) error
 | |
| 	Do(args ...interface{}) *Cmd
 | |
| 	DoContext(ctx context.Context, args ...interface{}) *Cmd
 | |
| 	Process(cmd Cmder) error
 | |
| 	ProcessContext(ctx context.Context, cmd Cmder) error
 | |
| 	Subscribe(channels ...string) *PubSub
 | |
| 	PSubscribe(channels ...string) *PubSub
 | |
| 	Close() error
 | |
| }
 | |
| 
 | |
| var _ UniversalClient = (*Client)(nil)
 | |
| var _ UniversalClient = (*ClusterClient)(nil)
 | |
| var _ UniversalClient = (*Ring)(nil)
 | |
| 
 | |
| // NewUniversalClient returns a new multi client. The type of client returned depends
 | |
| // on the following three conditions:
 | |
| //
 | |
| // 1. if a MasterName is passed a sentinel-backed FailoverClient will be returned
 | |
| // 2. if the number of Addrs is two or more, a ClusterClient will be returned
 | |
| // 3. otherwise, a single-node redis Client will be returned.
 | |
| func NewUniversalClient(opts *UniversalOptions) UniversalClient {
 | |
| 	if opts.MasterName != "" {
 | |
| 		return NewFailoverClient(opts.Failover())
 | |
| 	} else if len(opts.Addrs) > 1 {
 | |
| 		return NewClusterClient(opts.Cluster())
 | |
| 	}
 | |
| 	return NewClient(opts.Simple())
 | |
| }
 |