api

package
v1.15.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 11, 2024 License: Apache-2.0 Imports: 25 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoStore is an empty NoStoreErr object, useful for type checking
	ErrNoStore = &NoStoreErr{}
)

Functions

This section is empty.

Types

type BinlogClient

type BinlogClient struct {
	// contains filtered or unexported fields
}

BinlogClient is the client of binlog.

func NewBinlogClient

func NewBinlogClient(pdEndpoints []string, timeout time.Duration, tlsConfig *tls.Config) (*BinlogClient, error)

NewBinlogClient create a BinlogClient.

func (*BinlogClient) IsDrainerTombstone

func (c *BinlogClient) IsDrainerTombstone(ctx context.Context, addr string) (bool, error)

IsDrainerTombstone check if drainer is tombstone.

func (*BinlogClient) IsPumpTombstone

func (c *BinlogClient) IsPumpTombstone(ctx context.Context, addr string) (bool, error)

IsPumpTombstone check if drainer is tombstone.

func (*BinlogClient) OfflineDrainer

func (c *BinlogClient) OfflineDrainer(ctx context.Context, addr string) error

OfflineDrainer offline a drainer.

func (*BinlogClient) OfflinePump

func (c *BinlogClient) OfflinePump(ctx context.Context, addr string) error

OfflinePump offline a pump.

func (*BinlogClient) UpdateDrainerState added in v1.0.8

func (c *BinlogClient) UpdateDrainerState(ctx context.Context, addr string, state string) error

UpdateDrainerState update the specify state as the specified state.

func (*BinlogClient) UpdatePumpState added in v1.0.8

func (c *BinlogClient) UpdatePumpState(ctx context.Context, addr string, state string) error

UpdatePumpState update the specify state as the specified state.

type CDCOpenAPIClient added in v1.11.0

type CDCOpenAPIClient struct {
	// contains filtered or unexported fields
}

CDCOpenAPIClient is client for access TiCDC Open API

func NewCDCOpenAPIClient added in v1.11.0

func NewCDCOpenAPIClient(ctx context.Context, addresses []string, timeout time.Duration, tlsConfig *tls.Config) *CDCOpenAPIClient

NewCDCOpenAPIClient return a `CDCOpenAPIClient`

func (*CDCOpenAPIClient) DrainCapture added in v1.11.0

func (c *CDCOpenAPIClient) DrainCapture(addr, target string, apiTimeoutSeconds int) error

DrainCapture request cdc owner move all tables on the target capture to other captures.

func (*CDCOpenAPIClient) GetAllCaptures added in v1.11.0

func (c *CDCOpenAPIClient) GetAllCaptures() ([]*Capture, error)

GetAllCaptures return all captures instantaneously

func (*CDCOpenAPIClient) GetCaptureByAddr added in v1.11.0

func (c *CDCOpenAPIClient) GetCaptureByAddr(addr string) (result *Capture, err error)

GetCaptureByAddr return the capture information by the address

func (*CDCOpenAPIClient) GetOwner added in v1.11.0

func (c *CDCOpenAPIClient) GetOwner() (result *Capture, err error)

GetOwner return the cdc owner capture information

func (*CDCOpenAPIClient) GetStatus added in v1.11.0

func (c *CDCOpenAPIClient) GetStatus() (result ServerStatus, err error)

GetStatus return the status of the TiCDC server.

func (*CDCOpenAPIClient) Healthy added in v1.11.0

func (c *CDCOpenAPIClient) Healthy() error

Healthy return true if the TiCDC cluster is healthy

func (*CDCOpenAPIClient) IsCaptureAlive added in v1.11.0

func (c *CDCOpenAPIClient) IsCaptureAlive() error

IsCaptureAlive return error if the capture is not alive

func (*CDCOpenAPIClient) ResignOwner added in v1.11.0

func (c *CDCOpenAPIClient) ResignOwner(address string) error

ResignOwner resign the cdc owner, and wait for a new owner be found address is the current owner's address

type Capture added in v1.11.0

type Capture struct {
	ID            string `json:"id"`
	IsOwner       bool   `json:"is_owner"`
	AdvertiseAddr string `json:"address"`
}

Capture holds common information of a capture in cdc

type DMMasterClient

type DMMasterClient struct {
	// contains filtered or unexported fields
}

DMMasterClient is an HTTP client of the dm-master server

func NewDMMasterClient

func NewDMMasterClient(addrs []string, timeout time.Duration, tlsConfig *tls.Config) *DMMasterClient

NewDMMasterClient returns a new PDClient

func (*DMMasterClient) EvictDMMasterLeader

func (dm *DMMasterClient) EvictDMMasterLeader(retryOpt *utils.RetryOption) error

EvictDMMasterLeader evicts the dm master leader

func (*DMMasterClient) GetLeader

func (dm *DMMasterClient) GetLeader(retryOpt *utils.RetryOption) (string, error)

GetLeader gets leader of dm cluster

func (*DMMasterClient) GetMaster

func (dm *DMMasterClient) GetMaster(name string) (isFound bool, isActive bool, isLeader bool, err error)

GetMaster returns the dm master leader returns isFound, isActive, isLeader, error

func (*DMMasterClient) GetRegisteredMembers

func (dm *DMMasterClient) GetRegisteredMembers() ([]string, []string, error)

GetRegisteredMembers gets all registerer members of dm cluster

func (*DMMasterClient) GetURL

func (dm *DMMasterClient) GetURL(addr string) string

GetURL builds the the client URL of DMClient

func (*DMMasterClient) GetWorker

func (dm *DMMasterClient) GetWorker(name string) (string, error)

GetWorker returns the dm worker status returns (worker stage, error). If worker stage is "", that means this worker is in cluster

func (*DMMasterClient) OfflineMaster

func (dm *DMMasterClient) OfflineMaster(name string, retryOpt *utils.RetryOption) error

OfflineMaster offlines the dm master

func (*DMMasterClient) OfflineMember

func (dm *DMMasterClient) OfflineMember(query string, retryOpt *utils.RetryOption) error

OfflineMember offlines the member of dm cluster

func (*DMMasterClient) OfflineWorker

func (dm *DMMasterClient) OfflineWorker(name string, retryOpt *utils.RetryOption) error

OfflineWorker offlines the dm worker

type DrainCaptureRequest added in v1.11.0

type DrainCaptureRequest struct {
	CaptureID string `json:"capture_id"`
}

DrainCaptureRequest is request for manual `DrainCapture`

type DrainCaptureResp added in v1.11.0

type DrainCaptureResp struct {
	CurrentTableCount int `json:"current_table_count"`
}

DrainCaptureResp is response for manual `DrainCapture`

type LabelInfo added in v1.7.0

type LabelInfo struct {
	Machine   string `json:"machine"`
	Port      string `json:"port"`
	Store     uint64 `json:"store"`
	Status    string `json:"status"`
	Leaders   int    `json:"leaders"`
	Regions   int    `json:"regions"`
	Capacity  string `json:"capacity"`
	Available string `json:"available"`
	Labels    string `json:"labels"`
}

LabelInfo represents an instance label info

type Liveness added in v1.11.0

type Liveness int32

Liveness is the liveness status of a capture.

const (
	// LivenessCaptureAlive means the capture is alive, and ready to serve.
	LivenessCaptureAlive Liveness = 0
	// LivenessCaptureStopping means the capture is in the process of graceful shutdown.
	LivenessCaptureStopping Liveness = 1
)

type MetaPeer added in v1.12.0

type MetaPeer struct {
	*metapb.Peer
	// RoleName is `Role.String()`.
	// Since Role is serialized as int by json by default,
	// introducing it will make the output of pd-ctl easier to identify Role.
	RoleName string `json:"role_name"`
	// IsLearner is `Role == "Learner"`.
	// Since IsLearner was changed to Role in kvproto in 5.0, this field was introduced to ensure api compatibility.
	IsLearner bool `json:"is_learner,omitempty"`
}

MetaPeer is api compatible with *metapb.Peer.

type MetaStore added in v1.4.0

type MetaStore struct {
	*metapb.Store
	StateName string `json:"state_name"`
}

MetaStore contains meta information about a store.

type NoStoreErr added in v1.3.1

type NoStoreErr struct {
	// contains filtered or unexported fields
}

NoStoreErr is the error that no store matching address can be found in PD

func (*NoStoreErr) Error added in v1.3.1

func (e *NoStoreErr) Error() string

Error implement the error interface

func (*NoStoreErr) Is added in v1.3.1

func (e *NoStoreErr) Is(target error) bool

Is implements the error interface

type NodeStatus

type NodeStatus struct {
	NodeID      string `json:"nodeId"`
	Addr        string `json:"host"`
	State       string `json:"state"`
	MaxCommitTS int64  `json:"maxCommitTS"`
	UpdateTS    int64  `json:"updateTS"`
}

NodeStatus represents the status saved in etcd.

type PDClient

type PDClient struct {
	// contains filtered or unexported fields
}

PDClient is an HTTP client of the PD server

func NewPDClient

func NewPDClient(
	ctx context.Context,
	addrs []string,
	timeout time.Duration,
	tlsConfig *tls.Config,
) *PDClient

NewPDClient returns a new PDClient, the context must have a *logprinter.Logger as value of "logger"

func (*PDClient) CheckHealth added in v1.0.5

func (pc *PDClient) CheckHealth() error

CheckHealth checks the health of PD node

func (*PDClient) CheckRegion added in v1.4.0

func (pc *PDClient) CheckRegion(state string) (*RegionsInfo, error)

CheckRegion queries for the region with specific status

func (*PDClient) CheckTSOHealth added in v1.15.1

func (pc *PDClient) CheckTSOHealth(retryOpt *utils.RetryOption) error

CheckTSOHealth checks the health of TSO service(which is a Micro Service component of PD)

func (*PDClient) DelPD

func (pc *PDClient) DelPD(name string, retryOpt *utils.RetryOption) error

DelPD deletes a PD node from the cluster, name is the Name of the PD member

func (*PDClient) DelStore

func (pc *PDClient) DelStore(host string, retryOpt *utils.RetryOption) error

DelStore deletes stores from a (TiKV) host The host parameter should be in format of IP:Port, that matches store's address

func (*PDClient) EvictPDLeader

func (pc *PDClient) EvictPDLeader(retryOpt *utils.RetryOption) error

EvictPDLeader evicts the PD leader

func (*PDClient) EvictStoreLeader

func (pc *PDClient) EvictStoreLeader(host string, retryOpt *utils.RetryOption, countLeader func(string) (int, error)) error

EvictStoreLeader evicts the store leaders The host parameter should be in format of IP:Port, that matches store's address

func (*PDClient) GetClusterID added in v1.7.0

func (pc *PDClient) GetClusterID() (uint64, error)

GetClusterID return cluster ID

func (*PDClient) GetConfig added in v1.4.0

func (pc *PDClient) GetConfig() (map[string]any, error)

GetConfig returns all PD configs

func (*PDClient) GetCurrentStore added in v1.3.1

func (pc *PDClient) GetCurrentStore(addr string) (*StoreInfo, error)

GetCurrentStore gets the current store info of a given host

func (*PDClient) GetDashboardAddress

func (pc *PDClient) GetDashboardAddress() (string, error)

GetDashboardAddress get the PD node address which runs dashboard

func (*PDClient) GetLeader

func (pc *PDClient) GetLeader() (*pdpb.Member, error)

GetLeader queries the leader node of PD cluster

func (*PDClient) GetLocationLabels added in v1.2.0

func (pc *PDClient) GetLocationLabels() ([]string, bool, error)

GetLocationLabels gets the replication.location-labels config from pd server

func (*PDClient) GetMembers

func (pc *PDClient) GetMembers() (*pdpb.GetMembersResponse, error)

GetMembers queries for member list from the PD server

func (*PDClient) GetReplicateConfig

func (pc *PDClient) GetReplicateConfig() ([]byte, error)

GetReplicateConfig gets the PD replication config

func (*PDClient) GetStores

func (pc *PDClient) GetStores() (*StoresInfo, error)

GetStores queries the stores info from PD server

func (*PDClient) GetTiKVLabels added in v1.2.3

func (pc *PDClient) GetTiKVLabels() (map[string]map[string]string, []map[string]LabelInfo, error)

GetTiKVLabels implements TiKVLabelProvider

func (*PDClient) GetURL

func (pc *PDClient) GetURL(addr string) string

GetURL builds the client URL of PDClient

func (*PDClient) IsTombStone

func (pc *PDClient) IsTombStone(host string) (bool, error)

IsTombStone check if the node is Tombstone. The host parameter should be in format of IP:Port, that matches store's address

func (*PDClient) IsUp added in v1.0.2

func (pc *PDClient) IsUp(host string) (bool, error)

IsUp check if the node is Up state. The host parameter should be in format of IP:Port, that matches store's address

func (*PDClient) RecoverStoreLeader added in v1.12.0

func (pc *PDClient) RecoverStoreLeader(host string, originalCount int, retryOpt *utils.RetryOption, countLeader func(string) (int, error)) error

RecoverStoreLeader waits for some leaders to transfer back.

Currently, recoverStoreLeader will be considered as succeed in any of the following case

  1. 2/3 of leaders are already transferred back.

  2. Original leader count is less than 200. Though the accurate threshold is 57, it can be set to a larger value, for example 200. Moreover, clusters which have small number of leaders are supposed to has low pressure, and this recovering strategy may be unnecessary for them. Clusters in production env usually has thousands of leaders.

    Since PD considers it as balance when the leader count delta is less than 10, so these two conditions should be taken into consideration

    - When the original leader count is less than 20, there is possibility that no leader will transfer back. For example: The target store's leader count is 19. Other stores' leader count are 9. There are 20 stores in total. In this case, there may be no leader to transfer back.

    - When the leader count is less than 57, there is possibility that only less than 2/3 leaders are transferred back. `(N-10-9 >= 2/3*N) -> (N>=57)`. For example: The target store's leader count is 56. Other stores' leader count are 46. There are 57 stores in total. In this case, there may be only 37 leaders to transfer back, and 37/56 < 2/3. Accordingly, if the target store's leader count is 57, then there may be 38 leaders to transfer back, and 38/57 == 2/3.

  3. The leader count has been unchanged for 5 times.

func (*PDClient) RemoveStoreEvict

func (pc *PDClient) RemoveStoreEvict(host string) error

RemoveStoreEvict removes a store leader evict scheduler, which allows following leaders to be transffered to it again.

func (*PDClient) SetAllStoreLimits added in v1.4.0

func (pc *PDClient) SetAllStoreLimits(value int) error

SetAllStoreLimits sets store for all stores and types, it has the same effect as `pd-ctl store limit all value`

func (*PDClient) SetReplicationConfig added in v1.4.0

func (pc *PDClient) SetReplicationConfig(key string, value int) error

SetReplicationConfig sets a config key value of PD replication, it has the same effect as `pd-ctl config set key value`

func (*PDClient) UpdateReplicateConfig

func (pc *PDClient) UpdateReplicateConfig(body io.Reader) error

UpdateReplicateConfig updates the PD replication config

func (*PDClient) UpdateScheduleConfig added in v1.0.2

func (pc *PDClient) UpdateScheduleConfig(body io.Reader) error

UpdateScheduleConfig updates the PD schedule config

func (*PDClient) WaitLeader

func (pc *PDClient) WaitLeader(retryOpt *utils.RetryOption) error

WaitLeader wait until there's a leader or timeout.

type PDPeerStats added in v1.12.0

type PDPeerStats struct {
	*pdpb.PeerStats
	Peer MetaPeer `json:"peer"`
}

PDPeerStats is api compatible with *pdpb.PeerStats. NOTE: This type is exported by HTTP API. Please pay more attention when modifying it.

type PDReplicationConfig added in v1.4.0

type PDReplicationConfig struct {
	// MaxReplicas is the number of replicas for each region.
	MaxReplicas uint64 `toml:"max-replicas" json:"max-replicas"`

	// The label keys specified the location of a store.
	// The placement priorities is implied by the order of label keys.
	// For example, ["zone", "rack"] means that we should place replicas to
	// different zones first, then to different racks if we don't have enough zones.
	LocationLabels typeutil.StringSlice `toml:"location-labels" json:"location-labels"`
	// StrictlyMatchLabel strictly checks if the label of TiKV is matched with LocationLabels.
	StrictlyMatchLabel bool `toml:"strictly-match-label" json:"strictly-match-label,string"`

	// When PlacementRules feature is enabled. MaxReplicas, LocationLabels and IsolationLabels are not used any more.
	EnablePlacementRules bool `toml:"enable-placement-rules" json:"enable-placement-rules,string"`

	// IsolationLevel is used to isolate replicas explicitly and forcibly if it's not empty.
	// Its value must be empty or one of LocationLabels.
	// Example:
	// location-labels = ["zone", "rack", "host"]
	// isolation-level = "zone"
	// With configuration like above, PD ensure that all replicas be placed in different zones.
	// Even if a zone is down, PD will not try to make up replicas in other zone
	// because other zones already have replicas on it.
	IsolationLevel string `toml:"isolation-level" json:"isolation-level"`
}

PDReplicationConfig is the replication type configuration ReplicationConfig from PD.

type RegionInfo added in v1.4.0

type RegionInfo struct {
	ID          uint64              `json:"id"`
	StartKey    string              `json:"start_key"`
	EndKey      string              `json:"end_key"`
	RegionEpoch *metapb.RegionEpoch `json:"epoch,omitempty"`
	Peers       []MetaPeer          `json:"peers,omitempty"`

	Leader          MetaPeer      `json:"leader,omitempty"`
	DownPeers       []PDPeerStats `json:"down_peers,omitempty"`
	PendingPeers    []MetaPeer    `json:"pending_peers,omitempty"`
	WrittenBytes    uint64        `json:"written_bytes"`
	ReadBytes       uint64        `json:"read_bytes"`
	WrittenKeys     uint64        `json:"written_keys"`
	ReadKeys        uint64        `json:"read_keys"`
	ApproximateSize int64         `json:"approximate_size"`
	ApproximateKeys int64         `json:"approximate_keys"`
	Buckets         []string      `json:"buckets,omitempty"`

	ReplicationStatus *ReplicationStatus `json:"replication_status,omitempty"`
}

RegionInfo records detail region info for api usage.

type RegionsInfo added in v1.4.0

type RegionsInfo struct {
	Count   int           `json:"count"`
	Regions []*RegionInfo `json:"regions"`
}

RegionsInfo contains some regions with the detailed region info.

type ReplicationStatus added in v1.4.0

type ReplicationStatus struct {
	State   string `json:"state"`
	StateID uint64 `json:"state_id"`
}

ReplicationStatus represents the replication mode status of the region.

type ServerStatus added in v1.11.0

type ServerStatus struct {
	Version  string   `json:"version"`
	GitHash  string   `json:"git_hash"`
	ID       string   `json:"id"`
	Pid      int      `json:"pid"`
	IsOwner  bool     `json:"is_owner"`
	Liveness Liveness `json:"liveness"`
}

ServerStatus holds some common information of a TiCDC server

type StatusResp

type StatusResp struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

StatusResp represents the response of status api.

type StoreInfo added in v1.4.0

type StoreInfo struct {
	Store  *MetaStore   `json:"store"`
	Status *StoreStatus `json:"status"`
}

StoreInfo contains information about a store.

type StoreStatus added in v1.4.0

type StoreStatus struct {
	Capacity           typeutil.ByteSize  `json:"capacity"`
	Available          typeutil.ByteSize  `json:"available"`
	UsedSize           typeutil.ByteSize  `json:"used_size"`
	LeaderCount        int                `json:"leader_count"`
	LeaderWeight       float64            `json:"leader_weight"`
	LeaderScore        float64            `json:"leader_score"`
	LeaderSize         int64              `json:"leader_size"`
	RegionCount        int                `json:"region_count"`
	RegionWeight       float64            `json:"region_weight"`
	RegionScore        float64            `json:"region_score"`
	RegionSize         int64              `json:"region_size"`
	SlowScore          uint64             `json:"slow_score,omitempty"` // added omitempty
	SendingSnapCount   uint32             `json:"sending_snap_count,omitempty"`
	ReceivingSnapCount uint32             `json:"receiving_snap_count,omitempty"`
	ApplyingSnapCount  uint32             `json:"applying_snap_count,omitempty"`
	IsBusy             bool               `json:"is_busy,omitempty"`
	StartTS            *time.Time         `json:"start_ts,omitempty"`
	LastHeartbeatTS    *time.Time         `json:"last_heartbeat_ts,omitempty"`
	Uptime             *typeutil.Duration `json:"uptime,omitempty"`
}

StoreStatus contains status about a store.

type StoresInfo added in v1.4.0

type StoresInfo struct {
	Count  int          `json:"count"`
	Stores []*StoreInfo `json:"stores"`
}

StoresInfo records stores' info.

type TiDBClient added in v1.14.0

type TiDBClient struct {
	// contains filtered or unexported fields
}

TiDBClient is client for access TiKVCDC Open API

func NewTiDBClient added in v1.14.0

func NewTiDBClient(ctx context.Context, addresses []string, timeout time.Duration, tlsConfig *tls.Config) *TiDBClient

NewTiDBClient return a `TiDBClient`

func (*TiDBClient) FinishUpgrade added in v1.14.0

func (c *TiDBClient) FinishUpgrade() error

FinishUpgrade sends the finish upgrade message to the TiDB server

func (*TiDBClient) StartUpgrade added in v1.14.0

func (c *TiDBClient) StartUpgrade() error

StartUpgrade sends the start upgrade message to the TiDB server

type TiKVCDCCapture added in v1.11.0

type TiKVCDCCapture struct {
	ID            string `json:"id"`
	IsOwner       bool   `json:"is_owner"`
	AdvertiseAddr string `json:"address"`
}

TiKVCDCCapture holds common information of a capture in cdc

type TiKVCDCLiveness added in v1.11.0

type TiKVCDCLiveness int32

TiKVCDCLiveness is the liveness status of a capture.

const (
	// TiKVCDCCaptureAlive means the capture is alive, and ready to serve.
	TiKVCDCCaptureAlive TiKVCDCLiveness = 0
	// TiKVCDCCaptureStopping means the capture is in the process of graceful shutdown.
	TiKVCDCCaptureStopping TiKVCDCLiveness = 1
)

type TiKVCDCOpenAPIClient added in v1.11.0

type TiKVCDCOpenAPIClient struct {
	// contains filtered or unexported fields
}

TiKVCDCOpenAPIClient is client for access TiKVCDC Open API

func NewTiKVCDCOpenAPIClient added in v1.11.0

func NewTiKVCDCOpenAPIClient(ctx context.Context, addresses []string, timeout time.Duration, tlsConfig *tls.Config) *TiKVCDCOpenAPIClient

NewTiKVCDCOpenAPIClient return a `TiKVCDCOpenAPIClient`

func (*TiKVCDCOpenAPIClient) GetAllCaptures added in v1.11.0

func (c *TiKVCDCOpenAPIClient) GetAllCaptures() (result []*TiKVCDCCapture, err error)

GetAllCaptures return all captures instantaneously

func (*TiKVCDCOpenAPIClient) GetCaptureByAddr added in v1.11.0

func (c *TiKVCDCOpenAPIClient) GetCaptureByAddr(addr string) (*TiKVCDCCapture, error)

GetCaptureByAddr return the capture information by the address

func (*TiKVCDCOpenAPIClient) GetOwner added in v1.11.0

func (c *TiKVCDCOpenAPIClient) GetOwner() (*TiKVCDCCapture, error)

GetOwner return the TiKV-CDC owner capture information

func (*TiKVCDCOpenAPIClient) GetStatus added in v1.11.0

func (c *TiKVCDCOpenAPIClient) GetStatus() (result TiKVCDCServerStatus, err error)

GetStatus return the status of the TiKVCDC server.

func (*TiKVCDCOpenAPIClient) IsCaptureAlive added in v1.11.0

func (c *TiKVCDCOpenAPIClient) IsCaptureAlive() error

IsCaptureAlive return error if the capture is not alive

func (*TiKVCDCOpenAPIClient) ResignOwner added in v1.11.0

func (c *TiKVCDCOpenAPIClient) ResignOwner() error

ResignOwner resign the TiKV-CDC owner, and wait for a new owner be found

type TiKVCDCServerStatus added in v1.11.0

type TiKVCDCServerStatus struct {
	Version  string          `json:"version"`
	GitHash  string          `json:"git_hash"`
	ID       string          `json:"id"`
	Pid      int             `json:"pid"`
	IsOwner  bool            `json:"is_owner"`
	Liveness TiKVCDCLiveness `json:"liveness"`
}

TiKVCDCServerStatus holds some common information of a TiCDC server

Directories

Path Synopsis
Package pb is a reverse proxy.
Package pb is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL