Hi,

I've encountered a related issue which is fixed by Jelte's patch. When
a stmt timeout is triggered between the last sent row and the call
disable_statement_timeout:
- the stmt timeout indicator is set
- disable_statement_timeout does nothing as the stmt timeout is now inactive
- CommandComplete is sent
- the next CHECK_FOR_INTERRUPTS process the fired timeout, sending a
stmt timeout error
So the client receives a CommandComplete, followed by an error for the
same command.

+ if (DoingCommandRead)
+ {
+         /*
+          * If we are reading a command from the client, just ignore the
+          * cancel request --- sending an extra error message won't
+          * accomplish anything.  Otherwise, go ahead and throw an error
+          * with the correct reason.
+          */
+ }
+ else if (lock_timeout_occurred)

The comment feels a bit misleading. This isn't limited to cancel
requests: all timeouts will be ignored and discarded when reading a
command from the client. Which is the desired behaviour from what I
understand: The previous command was finished and if we have timeouts
triggered, they happened in the timeframe before reading the new
command.

- * Disable statement timeout, if active.
+ * Disable statement timeout, if active. We preserve the indicator flag
+ * though, otherwise we'd lose the knowledge in ProcessInterupts that the
+ * SIGINT came from a statement timeout.
  */
 static void
 disable_statement_timeout(void)
 {
        if (get_timeout_active(STATEMENT_TIMEOUT))
-               disable_timeout(STATEMENT_TIMEOUT, false);
+               disable_timeout(STATEMENT_TIMEOUT, true);

Is it still possible to have both the statement timeout active and
fired? You added the change to enable_statement_timeout to avoid
restarting it when it was already triggered, so I would expect an
active timeout to not have the indicator flag set. I guess there's the
possible race where the timeout is triggered between
get_timeout_active and disable_timeout.

Regards,
Anthonin Bonnefoy


Reply via email to