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


Reply via email to