It's a bug. conn.async_exec should not return nil. Internally it calles
#block and #get_result. #block waits until some result data is available
and therefore #is_busy returns false. Then the result is retrieved with
#get_result. This is the contract with libpq. Obviously there is
something that breaks this contract.
I can trigger a nil result when calling get_result and async_exec from
two threads (attached). This also results in a lot of other unusual
errors, because one connection should be used by one thread only. The
activerecord connection pool usually does not issue one connection to
two threads, but this case could happen, if connections are checked out
manually from the pool.
Beside this, I can only think of pgbouncer as the error source.
Unfortunately I don't have any experience with this tool.
--
Kind regards,
Lars