At Tue, 20 Oct 2020 21:22:31 +0900, Masahiko Sawada <masahiko.saw...@2ndquadrant.com> wrote in > On Tue, 20 Oct 2020 at 17:56, tsunakawa.ta...@fujitsu.com > <tsunakawa.ta...@fujitsu.com> wrote: > > > > From: Kyotaro Horiguchi <horikyota....@gmail.com> > > > It seems to respond to a statement-cancel signal immediately while > > > waiting for a coming byte. However, seems to wait forever while > > > waiting a space in send-buffer. (Is that mean the session will be > > > stuck if it sends a large chunk of bytes while the network is down?) > > > > What part makes you worried about that? libpq's send processing? > > > > I've just examined pgfdw_cancel_query(), too. As below, it uses a hidden > > 30 second timeout. After all, postgres_fdw also relies on timeout already. > > It uses the timeout but it's also cancellable before the timeout. See > we call CHECK_FOR_INTERRUPTS() in pgfdw_get_cleanup_result().
Yes. And as Sawada-san mentioned it's not a matter if a specific FDW module accepts cancellation or not. It's sufficient that we have one example. Other FDWs will follow postgres_fdw if needed. > > > After receiving a signal, it closes the problem connection. So the > > > local session is usable after that but the fiailed remote sessions are > > > closed and created another one at the next use. > > > > I couldn't see that the problematic connection is closed when the > > cancellation fails... Am I looking at a wrong place? ... > > I guess Horiguchi-san refereed the following code in pgfdw_xact_callback(): > > /* > * If the connection isn't in a good idle state, discard it to > * recover. Next GetConnection will open a new connection. > */ > if (PQstatus(entry->conn) != CONNECTION_OK || > PQtransactionStatus(entry->conn) != PQTRANS_IDLE || > entry->changing_xact_state) > { > elog(DEBUG3, "discarding connection %p", entry->conn); > disconnect_pg_server(entry); > } Right. Although it's not directly relevant to this discussion, precisely, that part is not visited just after the remote "COMMIT TRANSACTION" failed. If that commit fails or is canceled, an exception is raised while entry->changing_xact_state = true. Then the function is called again within AbortCurrentTransaction() and reaches the above code. regards. -- Kyotaro Horiguchi NTT Open Source Software Center