@@ -3,7 +3,9 @@ use crate::cass_error::CassError;
3
3
use crate :: cass_types:: CassConsistency ;
4
4
use crate :: exec_profile:: { CassExecProfile , ExecProfileName , exec_profile_builder_modify} ;
5
5
use crate :: future:: CassFuture ;
6
- use crate :: load_balancing:: { CassHostFilter , LoadBalancingConfig , LoadBalancingKind } ;
6
+ use crate :: load_balancing:: {
7
+ CassHostFilter , DcRestriction , LoadBalancingConfig , LoadBalancingKind ,
8
+ } ;
7
9
use crate :: retry_policy:: CassRetryPolicy ;
8
10
use crate :: ssl:: CassSsl ;
9
11
use crate :: timestamp_generator:: CassTimestampGen ;
@@ -826,20 +828,44 @@ pub(crate) unsafe fn set_load_balance_dc_aware_n(
826
828
used_hosts_per_remote_dc : c_uint ,
827
829
allow_remote_dcs_for_local_cl : cass_bool_t ,
828
830
) -> CassError {
829
- if local_dc_raw. is_null ( ) || local_dc_length == 0 {
831
+ let Some ( local_dc) = ( unsafe { ptr_to_cstr_n ( local_dc_raw, local_dc_length) } ) else {
832
+ tracing:: error!(
833
+ "Provided null or non-UTF-8 local DC name to cass_*_set_load_balance_dc_aware(_n)!"
834
+ ) ;
830
835
return CassError :: CASS_ERROR_LIB_BAD_PARAMS ;
831
- }
836
+ } ;
832
837
833
- if used_hosts_per_remote_dc != 0 || allow_remote_dcs_for_local_cl ! = 0 {
834
- // TODO: Add warning that the parameters are deprecated and not supported in the driver.
838
+ if local_dc_length = = 0 {
839
+ tracing :: error! ( "Provided empty local DC name to cass_*_set_load_balance_dc_aware(_n)!" ) ;
835
840
return CassError :: CASS_ERROR_LIB_BAD_PARAMS ;
836
841
}
837
842
838
- let local_dc = unsafe { ptr_to_cstr_n ( local_dc_raw, local_dc_length) }
839
- . unwrap ( )
840
- . to_string ( ) ;
843
+ let permit_dc_failover = if used_hosts_per_remote_dc > 0 {
844
+ // TODO: update cassandra.h documentation to reflect this behaviour.
845
+ tracing:: warn!(
846
+ "cass_*_set_load_balance_dc_aware(_n): `used_hosts_per_remote_dc` parameter is only partially \
847
+ supported in the driver: `0` is supported correctly, and any value `>0` has the semantics of \" +inf\" , \
848
+ which means no limit on the number of hosts per remote DC. This is different from the original cpp-driver! \
849
+ To clarify, you can understand this parameter as \" permit_dc_failover\" , with `0` being `false` and `>0` \
850
+ being `true`."
851
+ ) ;
852
+ true
853
+ } else {
854
+ false
855
+ } ;
841
856
842
- load_balancing_config. load_balancing_kind = Some ( LoadBalancingKind :: DcAware { local_dc } ) ;
857
+ let allow_remote_dcs_for_local_cl = allow_remote_dcs_for_local_cl != 0 ;
858
+
859
+ load_balancing_config. load_balancing_kind = Some ( LoadBalancingKind :: DcAware {
860
+ local_dc : local_dc. to_owned ( ) ,
861
+ permit_dc_failover,
862
+ allow_remote_dcs_for_local_cl,
863
+ } ) ;
864
+ load_balancing_config. filtering . dc_restriction = if permit_dc_failover {
865
+ DcRestriction :: None
866
+ } else {
867
+ DcRestriction :: Local ( local_dc. to_owned ( ) )
868
+ } ;
843
869
844
870
CassError :: CASS_OK
845
871
}
@@ -1757,7 +1783,7 @@ mod tests {
1757
1783
cass_cluster_set_load_balance_dc_aware(
1758
1784
cluster_raw. borrow_mut( ) ,
1759
1785
c"eu" . as_ptr( ) ,
1760
- 0 ,
1786
+ 0 , // forbid DC failover
1761
1787
0
1762
1788
) ,
1763
1789
CassError :: CASS_OK
@@ -1777,8 +1803,14 @@ mod tests {
1777
1803
let cluster = BoxFFI :: as_ref ( cluster_raw. borrow ( ) ) . unwrap ( ) ;
1778
1804
let load_balancing_kind = & cluster. load_balancing_config . load_balancing_kind ;
1779
1805
match load_balancing_kind {
1780
- Some ( LoadBalancingKind :: DcAware { local_dc } ) => {
1781
- assert_eq ! ( local_dc, "eu" )
1806
+ Some ( LoadBalancingKind :: DcAware {
1807
+ local_dc,
1808
+ permit_dc_failover,
1809
+ allow_remote_dcs_for_local_cl,
1810
+ } ) => {
1811
+ assert_eq ! ( local_dc, "eu" ) ;
1812
+ assert ! ( !permit_dc_failover) ;
1813
+ assert ! ( !allow_remote_dcs_for_local_cl) ;
1782
1814
}
1783
1815
_ => panic ! ( "Expected preferred dc" ) ,
1784
1816
}
@@ -1814,8 +1846,8 @@ mod tests {
1814
1846
cass_cluster_set_load_balance_dc_aware(
1815
1847
cluster_raw. borrow_mut( ) ,
1816
1848
c"eu" . as_ptr( ) ,
1817
- 0 ,
1818
- 0
1849
+ 42 , // allow DC failover
1850
+ cass_true // allow remote DCs for local CL
1819
1851
) ,
1820
1852
CassError :: CASS_OK
1821
1853
) ;
@@ -1824,34 +1856,20 @@ mod tests {
1824
1856
let node_location_preference =
1825
1857
& cluster. load_balancing_config . load_balancing_kind ;
1826
1858
match node_location_preference {
1827
- Some ( LoadBalancingKind :: DcAware { local_dc } ) => {
1828
- assert_eq ! ( local_dc, "eu" )
1859
+ Some ( LoadBalancingKind :: DcAware {
1860
+ local_dc,
1861
+ permit_dc_failover,
1862
+ allow_remote_dcs_for_local_cl,
1863
+ } ) => {
1864
+ assert_eq ! ( local_dc, "eu" ) ;
1865
+ assert ! ( permit_dc_failover) ;
1866
+ assert ! ( allow_remote_dcs_for_local_cl) ;
1829
1867
}
1830
1868
_ => panic ! ( "Expected preferred dc" ) ,
1831
1869
}
1832
1870
}
1833
1871
/* Test invalid configurations */
1834
1872
{
1835
- // Nonzero deprecated parameters
1836
- assert_cass_error_eq ! (
1837
- cass_cluster_set_load_balance_dc_aware(
1838
- cluster_raw. borrow_mut( ) ,
1839
- c"eu" . as_ptr( ) ,
1840
- 1 ,
1841
- 0
1842
- ) ,
1843
- CassError :: CASS_ERROR_LIB_BAD_PARAMS
1844
- ) ;
1845
- assert_cass_error_eq ! (
1846
- cass_cluster_set_load_balance_dc_aware(
1847
- cluster_raw. borrow_mut( ) ,
1848
- c"eu" . as_ptr( ) ,
1849
- 0 ,
1850
- 1
1851
- ) ,
1852
- CassError :: CASS_ERROR_LIB_BAD_PARAMS
1853
- ) ;
1854
-
1855
1873
// null pointers
1856
1874
assert_cass_error_eq ! (
1857
1875
cass_cluster_set_load_balance_dc_aware(
0 commit comments