MCPcopy
hub / github.com/jackc/pgx / CancelRequest

Method CancelRequest

pgconn/pgconn.go:1089–1159  ·  view source on GitHub ↗

CancelRequest sends a cancel request to the PostgreSQL server. It returns an error if unable to deliver the cancel request, but lack of an error does not ensure that the query was canceled. As specified in the documentation, there is no way to be sure a query was canceled. See https://www.postgresql

(ctx context.Context)

Source from the content-addressed store, hash-verified

1087// is no way to be sure a query was canceled.
1088// See https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-CANCELING-REQUESTS
1089func (pgConn *PgConn) CancelRequest(ctx context.Context) error {
1090 // Open a cancellation request to the same server. The address is taken from the net.Conn directly instead of reusing
1091 // the connection config. This is important in high availability configurations where fallback connections may be
1092 // specified or DNS may be used to load balance.
1093 serverAddr := pgConn.conn.RemoteAddr()
1094 var serverNetwork string
1095 var serverAddress string
1096 if serverAddr.Network() == "unix" {
1097 // for unix sockets, RemoteAddr() calls getpeername() which returns the name the
1098 // server passed to bind(). For Postgres, this is always a relative path "./.s.PGSQL.5432"
1099 // so connecting to it will fail. Fall back to the config's value
1100 serverNetwork, serverAddress = NetworkAddress(pgConn.config.Host, pgConn.config.Port)
1101 } else {
1102 serverNetwork, serverAddress = serverAddr.Network(), serverAddr.String()
1103 }
1104 cancelConn, err := pgConn.config.DialFunc(ctx, serverNetwork, serverAddress)
1105 if err != nil {
1106 // In case of unix sockets, RemoteAddr() returns only the file part of the path. If the
1107 // first connect failed, try the config.
1108 if serverAddr.Network() != "unix" {
1109 return err
1110 }
1111 serverNetwork, serverAddr := NetworkAddress(pgConn.config.Host, pgConn.config.Port)
1112 cancelConn, err = pgConn.config.DialFunc(ctx, serverNetwork, serverAddr)
1113 if err != nil {
1114 return err
1115 }
1116 }
1117 defer cancelConn.Close()
1118
1119 if ctx != context.Background() {
1120 contextWatcher := ctxwatch.NewContextWatcher(&DeadlineContextWatcherHandler{Conn: cancelConn})
1121 contextWatcher.Watch(ctx)
1122 defer contextWatcher.Unwatch()
1123 }
1124
1125 // If the primary connection is encrypted, encrypt the cancel connection the same way so the
1126 // backend pid and secret key are not exposed to a passive network observer. This mirrors libpq's
1127 // PQcancelCreate (PG17+), which reuses the original connection's sslmode/gssencmode for the
1128 // cancel connection. The legacy unencrypted path is still used when the primary connection is
1129 // plaintext (e.g. unix sockets or sslmode=disable).
1130 if pgConn.tlsConfig != nil {
1131 var tlsCancelConn net.Conn
1132 if pgConn.config.SSLNegotiation == "direct" {
1133 tlsCancelConn = tls.Client(cancelConn, pgConn.tlsConfig)
1134 } else {
1135 tlsCancelConn, err = startTLS(cancelConn, pgConn.tlsConfig)
1136 if err != nil {
1137 return fmt.Errorf("tls error on cancel connection: %w", err)
1138 }
1139 }
1140 cancelConn = tlsCancelConn
1141 defer cancelConn.Close()
1142 }
1143
1144 buf := make([]byte, 12+len(pgConn.secretKey))
1145 binary.BigEndian.PutUint32(buf[0:4], uint32(len(buf)))
1146 binary.BigEndian.PutUint32(buf[4:8], 80877102)

Callers 3

asyncCloseMethod · 0.95
TestConnCancelRequestFunction · 0.80
HandleCancelMethod · 0.80

Calls 10

WatchMethod · 0.95
UnwatchMethod · 0.95
NewContextWatcherFunction · 0.92
NetworkAddressFunction · 0.85
startTLSFunction · 0.85
CloseMethod · 0.65
RemoteAddrMethod · 0.45
StringMethod · 0.45
WriteMethod · 0.45
ReadMethod · 0.45

Tested by 1

TestConnCancelRequestFunction · 0.64