@@ -2,9 +2,11 @@ use std::borrow::Cow;
22use std:: env:: var;
33use std:: fmt:: { Display , Write } ;
44use std:: path:: { Path , PathBuf } ;
5+ use std:: time:: Duration ;
56
67pub use ssl_mode:: PgSslMode ;
78
9+ use crate :: net:: KeepaliveConfig ;
810use crate :: { connection:: LogSettings , net:: tls:: CertificateInput } ;
911
1012mod connect;
@@ -30,6 +32,8 @@ pub struct PgConnectOptions {
3032 pub ( crate ) log_settings : LogSettings ,
3133 pub ( crate ) extra_float_digits : Option < Cow < ' static , str > > ,
3234 pub ( crate ) options : Option < String > ,
35+ pub ( crate ) keepalives : bool ,
36+ pub ( crate ) keepalive_config : KeepaliveConfig ,
3337}
3438
3539impl Default for PgConnectOptions {
@@ -90,6 +94,9 @@ impl PgConnectOptions {
9094 extra_float_digits : Some ( "2" . into ( ) ) ,
9195 log_settings : Default :: default ( ) ,
9296 options : var ( "PGOPTIONS" ) . ok ( ) ,
97+ // Matches libpq default: keepalives=1 with OS defaults for timers.
98+ keepalives : true ,
99+ keepalive_config : KeepaliveConfig :: default ( ) ,
93100 }
94101 }
95102
@@ -441,6 +448,85 @@ impl PgConnectOptions {
441448 self
442449 }
443450
451+ /// Enables or disables TCP keepalive on the connection.
452+ ///
453+ /// This option is ignored for Unix domain sockets.
454+ ///
455+ /// Keepalive is enabled by default.
456+ ///
457+ /// When enabled, OS defaults are used for all timer parameters unless
458+ /// overridden by [`keepalives_idle`][Self::keepalives_idle],
459+ /// [`keepalives_interval`][Self::keepalives_interval], or
460+ /// [`keepalives_retries`][Self::keepalives_retries].
461+ ///
462+ /// # Example
463+ ///
464+ /// ```rust
465+ /// # use sqlx_postgres::PgConnectOptions;
466+ /// let options = PgConnectOptions::new()
467+ /// .keepalives(false);
468+ /// ```
469+ pub fn keepalives ( mut self , enable : bool ) -> Self {
470+ self . keepalives = enable;
471+ self
472+ }
473+
474+ /// Sets the idle time before TCP keepalive probes begin.
475+ ///
476+ /// This is ignored for Unix domain sockets, or if the `keepalives`
477+ /// option is disabled.
478+ ///
479+ /// # Example
480+ ///
481+ /// ```rust
482+ /// # use std::time::Duration;
483+ /// # use sqlx_postgres::PgConnectOptions;
484+ /// let options = PgConnectOptions::new()
485+ /// .keepalives_idle(Duration::from_secs(60));
486+ /// ```
487+ pub fn keepalives_idle ( mut self , idle : Duration ) -> Self {
488+ self . keepalive_config . idle = Some ( idle) ;
489+ self
490+ }
491+
492+ /// Sets the interval between TCP keepalive probes.
493+ ///
494+ /// This is ignored for Unix domain sockets, or if the `keepalives`
495+ /// option is disabled.
496+ ///
497+ /// # Example
498+ ///
499+ /// ```rust
500+ /// # use std::time::Duration;
501+ /// # use sqlx_postgres::PgConnectOptions;
502+ /// let options = PgConnectOptions::new()
503+ /// .keepalives_interval(Duration::from_secs(5));
504+ /// ```
505+ pub fn keepalives_interval ( mut self , interval : Duration ) -> Self {
506+ self . keepalive_config . interval = Some ( interval) ;
507+ self
508+ }
509+
510+ /// Sets the maximum number of TCP keepalive probes before the connection is dropped.
511+ ///
512+ /// This is ignored for Unix domain sockets, or if the `keepalives`
513+ /// option is disabled.
514+ ///
515+ /// Only supported on Unix platforms; ignored on other platforms.
516+ ///
517+ /// # Example
518+ ///
519+ /// ```rust
520+ /// # use sqlx_postgres::PgConnectOptions;
521+ /// let options = PgConnectOptions::new()
522+ /// .keepalives_retries(3);
523+ /// ```
524+ #[ cfg( unix) ]
525+ pub fn keepalives_retries ( mut self , retries : u32 ) -> Self {
526+ self . keepalive_config . retries = Some ( retries) ;
527+ self
528+ }
529+
444530 /// We try using a socket if hostname starts with `/` or if socket parameter
445531 /// is specified.
446532 pub ( crate ) fn fetch_socket ( & self ) -> Option < String > {
@@ -569,6 +655,34 @@ impl PgConnectOptions {
569655 pub fn get_options ( & self ) -> Option < & str > {
570656 self . options . as_deref ( )
571657 }
658+
659+ /// Get whether TCP keepalives are enabled.
660+ ///
661+ /// # Example
662+ ///
663+ /// ```rust
664+ /// # use sqlx_postgres::PgConnectOptions;
665+ /// let options = PgConnectOptions::new();
666+ /// assert!(options.get_keepalives());
667+ /// ```
668+ pub fn get_keepalives ( & self ) -> bool {
669+ self . keepalives
670+ }
671+
672+ /// Get the idle time before TCP keepalive probes begin.
673+ pub fn get_keepalives_idle ( & self ) -> Option < Duration > {
674+ self . keepalive_config . idle
675+ }
676+
677+ /// Get the interval between TCP keepalive probes.
678+ pub fn get_keepalives_interval ( & self ) -> Option < Duration > {
679+ self . keepalive_config . interval
680+ }
681+
682+ /// Get the maximum number of TCP keepalive probes.
683+ pub fn get_keepalives_retries ( & self ) -> Option < u32 > {
684+ self . keepalive_config . retries
685+ }
572686}
573687
574688fn default_host ( port : u16 ) -> String {
0 commit comments