@@ -267,6 +267,7 @@ function Connection(
267
267
throw_error:: Bool = true ,
268
268
connect_timeout:: Real = 0 ,
269
269
options:: Dict{String, String} = CONNECTION_OPTION_DEFAULTS,
270
+ nonblocking:: Bool = false ,
270
271
kwargs...
271
272
)
272
273
if options === CONNECTION_OPTION_DEFAULTS
@@ -300,7 +301,7 @@ function Connection(
300
301
)
301
302
302
303
# If password needed and not entered, prompt the user
303
- if libpq_c. PQconnectionNeedsPassword (jl_conn. conn) == 1
304
+ connection = if libpq_c. PQconnectionNeedsPassword (jl_conn. conn) == 1
304
305
push! (keywords, " password" )
305
306
user = unsafe_string (libpq_c. PQuser (jl_conn. conn))
306
307
# close this connection; will open another one below with the user-provided password
@@ -309,19 +310,28 @@ function Connection(
309
310
pass = Base. getpass (prompt)
310
311
push! (values, read (pass, String))
311
312
Base. shred! (pass)
312
- return handle_new_connection (
313
+ handle_new_connection (
313
314
Connection (
314
315
_connect_nonblocking (keywords, values, false ; timeout= connect_timeout);
315
316
kwargs...
316
317
);
317
318
throw_error= throw_error,
318
319
)
319
320
else
320
- return handle_new_connection (
321
+ handle_new_connection (
321
322
jl_conn;
322
323
throw_error= throw_error,
323
324
)
324
325
end
326
+
327
+ if nonblocking
328
+ success = libpq_c. PQsetnonblocking (connection. conn, convert (Cint, nonblock)) == 0
329
+ if ! success
330
+ close (connection)
331
+ error (LOGGER, " Could not provide a non-blocking connection" )
332
+ end
333
+ end
334
+ return connection
325
335
end
326
336
327
337
# AbstractLock primitives:
791
801
socket (jl_conn:: Connection ) = socket (jl_conn. conn)
792
802
793
803
"""
804
+ isnonblocking(jl_conn::Connection)
805
+
794
806
Sets the nonblocking connection status of the PG connections.
795
807
While async_execute is non-blocking on the receiving side,
796
- the sending side is still nonblockign without this
808
+ the sending side is still nonblocking without this
797
809
Returns true on success, false on failure
798
810
799
811
https://www.postgresql.org/docs/current/libpq-async.html
@@ -808,28 +820,37 @@ Returns true if the connection is set to non-blocking, false otherwise
808
820
809
821
https://www.postgresql.org/docs/current/libpq-async.html
810
822
"""
811
- function isnonblocking (jl_conn)
823
+ function isnonblocking (jl_conn:: Connection )
812
824
return libpq_c. PQisnonblocking (jl_conn. conn) == 1
813
825
end
814
826
815
827
"""
816
- Do the flush dance described in the libpq docs. Required when the
828
+ _flush(jl_conn::Connection)
829
+
830
+ Do the _flush dance described in the libpq docs. Required when the
817
831
connections are set to nonblocking and we want do send queries/data
818
832
without blocking.
819
833
820
- https://www.postgresql.org/docs/current/libpq-async.html#LIBPQ-PQFlush
834
+ https://www.postgresql.org/docs/current/libpq-async.html#LIBPQ-PQFLUSH
821
835
"""
822
- function flush (jl_conn)
823
- watcher = FDWatcher (socket (jl_conn), true , true ) # can wait for reads and writes
836
+ function _flush (jl_conn:: Connection )
837
+ local watcher = nothing
838
+ if isnonblocking (jl_conn)
839
+ watcher = FDWatcher (socket (jl_conn), true , true ) # can wait for reads and writes
840
+ end
824
841
try
825
- while true # Iterators.repeated(true) # would make me more comfotable I think
842
+ while true
826
843
flushstatus = libpq_c. PQflush (jl_conn. conn)
827
844
# 0 indicates success
828
- flushstatus == 0 && return true
845
+ if flushstatus == 0
846
+ return true
829
847
# -1 indicates error
830
- flushstatus < 0 && error (LOGGER, Errors. PQConnectionError (jl_conn))
831
- # Could not send all data without blocking, need to wait FD
832
- flushstatus == 1 && begin
848
+ elseif flushstatus < 0
849
+ return false
850
+ # 1 indicates that we could not send all data without blocking,
851
+ elseif flushstatus == 1
852
+ # need to wait FD
853
+ # Only applicable when the connection is in nonblocking mode
833
854
wait (watcher) # Wait for the watcher
834
855
# If it becomes write-ready, call PQflush again.
835
856
if watcher. mask. writable
@@ -838,15 +859,12 @@ function flush(jl_conn)
838
859
if watcher. mask. readable
839
860
# if the stream is readable, we have to consume data from the server first.
840
861
success = libpq_c. PQconsumeInput (jl_conn. conn) == 1
841
- ! success && error (LOGGER, Errors . PQConnectionError (jl_conn))
862
+ ! success && return false
842
863
end
843
864
end
844
865
end
845
- catch
846
- # We don't want to manage anything here
847
- rethrow ()
848
866
finally
849
867
# Just close the watcher
850
- close (watcher)
868
+ ! isnothing (watcher) && close (watcher)
851
869
end
852
870
end
0 commit comments