discord_cassandra_cpp/cassandra/
cluster.rs

1use crate::cassandra::error::*;
2use crate::cassandra::future::CassFuture;
3use crate::cassandra::policy::retry::RetryPolicy;
4use crate::cassandra::session::session_scope::{Bound, Unbound};
5use crate::cassandra::session::Session;
6use crate::cassandra::ssl::Ssl;
7use crate::cassandra::time::TimestampGen;
8use crate::cassandra::util::{Protected, ProtectedInner};
9
10use crate::cassandra_sys::cass_cluster_free;
11use crate::cassandra_sys::cass_cluster_new;
12use crate::cassandra_sys::cass_cluster_set_connect_timeout;
13use crate::cassandra_sys::cass_cluster_set_connection_heartbeat_interval;
14use crate::cassandra_sys::cass_cluster_set_connection_idle_timeout;
15use crate::cassandra_sys::cass_cluster_set_constant_speculative_execution_policy;
16use crate::cassandra_sys::cass_cluster_set_contact_points_n;
17use crate::cassandra_sys::cass_cluster_set_core_connections_per_host;
18use crate::cassandra_sys::cass_cluster_set_credentials_n;
19use crate::cassandra_sys::cass_cluster_set_latency_aware_routing;
20use crate::cassandra_sys::cass_cluster_set_latency_aware_routing_settings;
21use crate::cassandra_sys::cass_cluster_set_load_balance_dc_aware_n;
22use crate::cassandra_sys::cass_cluster_set_load_balance_round_robin;
23use crate::cassandra_sys::cass_cluster_set_local_address_n;
24use crate::cassandra_sys::cass_cluster_set_max_concurrent_creation;
25use crate::cassandra_sys::cass_cluster_set_max_concurrent_requests_threshold;
26use crate::cassandra_sys::cass_cluster_set_max_connections_per_host;
27use crate::cassandra_sys::cass_cluster_set_max_requests_per_flush;
28use crate::cassandra_sys::cass_cluster_set_no_speculative_execution_policy;
29use crate::cassandra_sys::cass_cluster_set_num_threads_io;
30use crate::cassandra_sys::cass_cluster_set_pending_requests_high_water_mark;
31use crate::cassandra_sys::cass_cluster_set_pending_requests_low_water_mark;
32use crate::cassandra_sys::cass_cluster_set_port;
33use crate::cassandra_sys::cass_cluster_set_protocol_version;
34use crate::cassandra_sys::cass_cluster_set_queue_size_event;
35use crate::cassandra_sys::cass_cluster_set_queue_size_io;
36use crate::cassandra_sys::cass_cluster_set_reconnect_wait_time;
37use crate::cassandra_sys::cass_cluster_set_request_timeout;
38use crate::cassandra_sys::cass_cluster_set_retry_policy;
39use crate::cassandra_sys::cass_cluster_set_ssl;
40use crate::cassandra_sys::cass_cluster_set_tcp_keepalive;
41use crate::cassandra_sys::cass_cluster_set_tcp_nodelay;
42use crate::cassandra_sys::cass_cluster_set_timestamp_gen;
43use crate::cassandra_sys::cass_cluster_set_token_aware_routing;
44use crate::cassandra_sys::cass_cluster_set_token_aware_routing_shuffle_replicas;
45use crate::cassandra_sys::cass_cluster_set_use_schema;
46use crate::cassandra_sys::cass_cluster_set_whitelist_filtering;
47use crate::cassandra_sys::cass_cluster_set_write_bytes_high_water_mark;
48use crate::cassandra_sys::cass_cluster_set_write_bytes_low_water_mark;
49use crate::cassandra_sys::cass_false;
50use crate::cassandra_sys::cass_future_error_code;
51use crate::cassandra_sys::cass_session_connect;
52use crate::cassandra_sys::cass_session_connect_keyspace_n;
53use crate::cassandra_sys::cass_session_new;
54use crate::cassandra_sys::cass_true;
55use crate::cassandra_sys::CassCluster as _Cluster;
56
57use std::ffi::NulError;
58use std::fmt;
59use std::fmt::Display;
60use std::iter::Map;
61use std::net::AddrParseError;
62use std::net::Ipv4Addr;
63use std::os::raw::c_char;
64use std::result;
65use std::str::FromStr;
66use std::{convert::TryInto, ffi::CStr};
67use time::Duration;
68
69/// A CQL protocol version is just an integer.
70pub type CqlProtocol = i32;
71
72///
73/// The main class to use when interacting with a Cassandra cluster.
74/// Typically, one instance of this class will be created for each separate
75/// Cassandra cluster that your application interacts with.
76///
77/// # Examples
78/// ```
79/// # async fn test() {
80/// use cassandra_cpp::Cluster;
81/// let mut cluster = Cluster::default();
82/// cluster.set_contact_points("127.0.0.1").unwrap();
83/// let session = cluster.connect().await.unwrap();
84/// # }
85/// ```
86#[derive(Debug)]
87pub struct Cluster(pub *mut _Cluster);
88
89// The underlying C type has no thread-local state, but does not support access
90// from multiple threads: https://datastax.github.io/cpp-driver/topics/#thread-safety
91unsafe impl Send for Cluster {}
92
93impl Drop for Cluster {
94    /// Frees a cluster instance.
95    fn drop(&mut self) {
96        unsafe { cass_cluster_free(self.0) }
97    }
98}
99
100impl ProtectedInner<*mut _Cluster> for Cluster {
101    fn inner(&self) -> *mut _Cluster {
102        self.0
103    }
104}
105
106impl Protected<*mut _Cluster> for Cluster {
107    fn build(inner: *mut _Cluster) -> Self {
108        if inner.is_null() {
109            panic!("Unexpected null pointer")
110        };
111        Cluster(inner)
112    }
113}
114
115impl Default for Cluster {
116    /// Creates a new cluster
117    fn default() -> Cluster {
118        unsafe { Cluster(cass_cluster_new()) }
119    }
120}
121
122impl Cluster {
123    /// Sets/Appends contact points. This *MUST* be set. The first call sets
124    /// the contact points and any subsequent calls appends additional contact
125    /// points. Passing an empty string will clear the contact points. White space
126    /// is stripped from the contact points.
127    ///
128    ///
129    /// {contact points: "127.0.0.1" "127.0.0.1,127.0.0.2", "server1.domain.com"}
130    ///
131    ///
132    pub fn set_contact_points(&mut self, contact_points: &str) -> Result<&mut Self> {
133        unsafe {
134            let cp_ptr = contact_points.as_ptr() as *const c_char;
135            let err = cass_cluster_set_contact_points_n(self.0, cp_ptr, contact_points.len());
136            err.to_result(self)
137        }
138    }
139
140    /// Sets the local address to bind when connecting to the cluster,
141    /// if desired.
142    ///
143    /// Only numeric addresses are supported.
144    pub fn set_local_address(&mut self, name: &str) -> Result<&mut Self> {
145        unsafe {
146            let name_ptr = name.as_ptr() as *const c_char;
147            let err = cass_cluster_set_local_address_n(self.0, name_ptr, name.len());
148            err.to_result(self)
149        }
150    }
151
152    /// Sets the port
153    ///
154    ///
155    /// Default: 9042
156    ///
157    pub fn set_port(&mut self, port: u16) -> Result<&mut Self> {
158        unsafe { cass_cluster_set_port(self.0, port as i32).to_result(self) }
159    }
160
161    /// Sets the SSL context and enables SSL
162    pub fn set_ssl(&mut self, ssl: Ssl) -> &Self {
163        unsafe {
164            cass_cluster_set_ssl(self.0, ssl.inner());
165            self
166        }
167    }
168
169    /// Connects to the cassandra cluster
170    pub async fn connect(&mut self) -> Result<Session<Unbound>> {
171        let session = Session::new(Unbound);
172        let connect_future = {
173            let connect = unsafe { cass_session_connect(session.inner(), self.0) };
174            CassFuture::build(session, connect)
175        };
176        connect_future.await
177    }
178
179    /// Connects to the cassandra cluster, setting the keyspace of the session.
180    pub async fn connect_keyspace(&mut self, keyspace: &str) -> Result<Session> {
181        let session = Session::new(Bound::new(keyspace));
182        let keyspace_ptr = keyspace.as_ptr() as *const c_char;
183        let connect_keyspace = unsafe {
184            cass_session_connect_keyspace_n(
185                session.inner(),
186                self.inner(),
187                keyspace_ptr,
188                keyspace.len(),
189            )
190        };
191        let connect_future = CassFuture::build(session, connect_keyspace);
192        connect_future.await
193    }
194
195    /// Sets the protocol version. This will automatically downgrade to the lowest
196    /// supported protocol version.
197    ///
198    ///
199    /// Default: version 4
200    ///
201    pub fn set_protocol_version(&mut self, protocol_version: CqlProtocol) -> Result<&mut Self> {
202        unsafe {
203            cass_cluster_set_protocol_version(self.0, protocol_version as i32).to_result(self)
204        }
205    }
206
207    /// Sets the number of IO threads. This is the number of threads
208    /// that will handle query requests.
209    ///
210    ///
211    /// Default: 1
212    ///
213    pub fn set_num_threads_io(&mut self, num_threads: u32) -> Result<&mut Self> {
214        unsafe { cass_cluster_set_num_threads_io(self.0, num_threads).to_result(self) }
215    }
216
217    /// Sets the size of the fixed size queue that stores pending requests.
218    ///
219    ///
220    /// Default: 8192
221    ///
222    pub fn set_queue_size_io(&mut self, queue_size: u32) -> Result<&mut Self> {
223        unsafe { cass_cluster_set_queue_size_io(self.0, queue_size).to_result(self) }
224    }
225
226    /// Sets the size of the fixed size queue that stores events.
227    ///
228    ///
229    /// Default: 8192
230    ///
231    pub fn set_queue_size_event(&mut self, queue_size: u32) -> Result<&mut Self> {
232        unsafe { cass_cluster_set_queue_size_event(self.0, queue_size).to_result(self) }
233    }
234
235    /// Sets the number of connections made to each server in each
236    /// IO thread.
237    ///
238    ///
239    /// Default: 1
240    ///
241    pub fn set_core_connections_per_host(&mut self, num_connections: u32) -> Result<&mut Self> {
242        unsafe {
243            cass_cluster_set_core_connections_per_host(self.0, num_connections).to_result(self)
244        }
245    }
246
247    /// Sets the maximum number of connections made to each server in each
248    /// IO thread.
249    ///
250    ///
251    /// Default: 2
252    ///
253    pub fn set_max_connections_per_host(&mut self, num_connections: u32) -> Result<&mut Self> {
254        unsafe {
255            cass_cluster_set_max_connections_per_host(self.0, num_connections).to_result(self)
256        }
257    }
258
259    /// Sets the amount of time to wait before attempting to reconnect.
260    ///
261    ///
262    /// Default: 1000ms
263    ///
264    pub fn set_reconnect_wait_time(&mut self, wait_time: u32) -> &Self {
265        unsafe {
266            cass_cluster_set_reconnect_wait_time(self.0, wait_time);
267        }
268        self
269    }
270
271    /// Sets the maximum number of connections that will be created concurrently.
272    /// Connections are created when the current connections are unable to keep up with
273    /// request throughput.
274    ///
275    ///
276    /// Default: 1
277    pub fn set_max_concurrent_creation(&mut self, num_connections: u32) -> Result<&mut Self> {
278        unsafe { cass_cluster_set_max_concurrent_creation(self.0, num_connections).to_result(self) }
279    }
280
281    /// Sets the threshold for the maximum number of concurrent requests in-flight
282    /// on a connection before creating a new connection. The number of new connections
283    /// created will not exceed max_connections_per_host.
284    ///
285    ///
286    /// Default: 100
287    pub fn set_max_concurrent_requests_threshold(
288        &mut self,
289        num_requests: u32,
290    ) -> Result<&mut Self> {
291        unsafe {
292            cass_cluster_set_max_concurrent_requests_threshold(self.0, num_requests).to_result(self)
293        }
294    }
295
296    /// Sets the maximum number of requests processed by an IO worker
297    /// per flush.
298    ///
299    ///
300    /// Default: 128
301    pub fn set_max_requests_per_flush(&mut self, num_requests: u32) -> Result<&mut Self> {
302        unsafe { cass_cluster_set_max_requests_per_flush(self.0, num_requests).to_result(self) }
303    }
304
305    /// Sets the high water mark for the number of bytes outstanding
306    /// on a connection. Disables writes to a connection if the number
307    /// of bytes queued exceed this value.
308    ///
309    ///
310    /// Default: 64KB
311    pub fn set_write_bytes_high_water_mark(&mut self, num_bytes: u32) -> Result<&mut Self> {
312        unsafe { cass_cluster_set_write_bytes_high_water_mark(self.0, num_bytes).to_result(self) }
313    }
314
315    /// Sets the low water mark for the number of bytes outstanding
316    /// on a connection. Disables writes to a connection if the number
317    /// of bytes queued fall below this value.
318    ///
319    ///
320    /// Default: 32KB
321    pub fn set_write_bytes_low_water_mark(&mut self, num_bytes: u32) -> Result<&mut Self> {
322        unsafe { cass_cluster_set_write_bytes_low_water_mark(self.0, num_bytes).to_result(self) }
323    }
324
325    /// Sets the high water mark for the number of requests queued waiting
326    /// for a connection in a connection pool. Disables writes to a
327    /// host on an IO worker if the number of requests queued exceed this
328    /// value.
329    ///
330    ///
331    /// Default: 256
332    pub fn set_pending_requests_high_water_mark(&mut self, num_requests: u32) -> Result<&mut Self> {
333        unsafe {
334            cass_cluster_set_pending_requests_high_water_mark(self.0, num_requests).to_result(self)
335        }
336    }
337
338    /// Sets the low water mark for the number of requests queued waiting
339    /// for a connection in a connection pool. After exceeding high water mark
340    /// requests, writes to a host will only resume once the number of requests
341    /// fall below this value.
342    ///
343    ///
344    /// Default: 128
345    pub fn set_pending_requests_low_water_mark(&mut self, num_requests: u32) -> Result<&mut Self> {
346        unsafe {
347            cass_cluster_set_pending_requests_low_water_mark(self.0, num_requests).to_result(self)
348        }
349    }
350
351    /// Sets the timeout for connecting to a node.
352    ///
353    ///
354    /// Default: 5000ms
355    pub fn set_connect_timeout(&mut self, timeout: Duration) -> &Self {
356        unsafe {
357            cass_cluster_set_connect_timeout(self.0, timeout.whole_milliseconds() as u32);
358        }
359        self
360    }
361
362    /// Sets the timeout for waiting for a response from a node.
363    ///
364    ///
365    /// Default: 12000ms
366    pub fn set_request_timeout(&mut self, timeout: Duration) -> &Self {
367        unsafe {
368            cass_cluster_set_request_timeout(self.0, timeout.whole_milliseconds() as u32);
369        }
370        self
371    }
372
373    /// Sets credentials for plain text authentication.
374    pub fn set_credentials(&mut self, username: &str, password: &str) -> Result<&mut Self> {
375        unsafe {
376            let username_ptr = username.as_ptr() as *const c_char;
377            let password_ptr = password.as_ptr() as *const c_char;
378            cass_cluster_set_credentials_n(
379                self.0,
380                username_ptr,
381                username.len(),
382                password_ptr,
383                password.len(),
384            );
385        }
386        Ok(self)
387    }
388
389    /// Configures the cluster to use round-robin load balancing.
390    ///
391    /// The driver discovers all nodes in a cluster and cycles through
392    /// them per request. All are considered 'local'.
393    pub fn set_load_balance_round_robin(&mut self) -> &Self {
394        unsafe {
395            cass_cluster_set_load_balance_round_robin(self.0);
396            self
397        }
398    }
399
400    /// Configures the cluster to use DC-aware load balancing.
401    /// For each query, all live nodes in a primary 'local' DC are tried first,
402    /// followed by any node from other DCs.
403    ///
404    /// <b>Note:</b> This is the default, and does not need to be called unless
405    /// switching an existing from another policy or changing settings.
406    /// Without further configuration, a default local_dc is chosen from the
407    /// first connected contact point, and no remote hosts are considered in
408    /// query plans. If relying on this mechanism, be sure to use only contact
409    /// points from the local DC.
410    pub fn set_load_balance_dc_aware<S>(
411        &mut self,
412        local_dc: &str,
413        used_hosts_per_remote_dc: u32,
414        allow_remote_dcs_for_local_cl: bool,
415    ) -> Result<&mut Self> {
416        unsafe {
417            {
418                let local_dc_ptr = local_dc.as_ptr() as *const c_char;
419                cass_cluster_set_load_balance_dc_aware_n(
420                    self.0,
421                    local_dc_ptr,
422                    local_dc.len(),
423                    used_hosts_per_remote_dc,
424                    if allow_remote_dcs_for_local_cl {
425                        cass_true
426                    } else {
427                        cass_false
428                    },
429                )
430            }
431            .to_result(self)
432        }
433    }
434
435    /// Configures the cluster to use token-aware request routing or not.
436    ///
437    /// <b>Important:</b> Token-aware routing depends on keyspace information.
438    /// For this reason enabling token-aware routing will also enable the usage
439    /// of schema metadata.
440    ///
441    ///
442    /// Default: true (enabled).
443    ///
444    ///
445    /// This routing policy composes the base routing policy, routing
446    /// requests first to replicas on nodes considered 'local' by
447    /// the base load balancing policy.
448    pub fn set_token_aware_routing(&mut self, enabled: bool) -> &Self {
449        unsafe {
450            cass_cluster_set_token_aware_routing(
451                self.0,
452                if enabled { cass_true } else { cass_false },
453            );
454        }
455        self
456    }
457
458    /// Configures token-aware routing to randomly shuffle replicas.
459    /// This can reduce the effectiveness of server-side caching, but it
460    /// can better distribute load over replicas for a given partition key.
461    ///
462    ///
463    /// Default: true (enabled)
464    ///
465    ///
466    /// Note: Token-aware routing must be enabled for the setting to be
467    /// applicable.
468    pub fn set_token_aware_routing_shuffle_replicas(&mut self, enabled: bool) -> &Self {
469        unsafe {
470            cass_cluster_set_token_aware_routing_shuffle_replicas(
471                self.0,
472                if enabled { cass_true } else { cass_false },
473            );
474        }
475        self
476    }
477
478    /// Configures the cluster to use latency-aware request routing or not.
479    ///
480    ///
481    /// Default: false (disabled).
482    ///
483    ///
484    /// This routing policy is a top-level routing policy. It uses the
485    /// base routing policy to determine locality (dc-aware) and/or
486    /// placement (token-aware) before considering the latency.
487    pub fn set_latency_aware_routing(&mut self, enabled: bool) -> &Self {
488        unsafe {
489            cass_cluster_set_latency_aware_routing(
490                self.0,
491                if enabled { cass_true } else { cass_false },
492            );
493        }
494        self
495    }
496
497    /// Configures the settings for latency-aware request routing.
498    ///
499    ///
500    /// Defaults:
501    ///
502    /// <ul>
503    ///   <li>exclusion_threshold: 2.0</li>
504    ///   <li>scale_ms: 100 milliseconds</li>
505    ///  <li>retry_period_ms: 10,000 milliseconds (10 seconds)</li>
506    ///  <li>update_rate_ms: 100 milliseconds</li>
507    ///  <li>min_measured: 50</li>
508    /// </ul>
509    pub fn set_latency_aware_routing_settings(
510        &mut self,
511        exclusion_threshold: f64,
512        scale: Duration,
513        retry_period: Duration,
514        update_rate: Duration,
515        min_measured: u64,
516    ) -> &Self {
517        unsafe {
518            cass_cluster_set_latency_aware_routing_settings(
519                self.0,
520                exclusion_threshold,
521                scale.whole_milliseconds() as u64,
522                retry_period.whole_milliseconds() as u64,
523                update_rate.whole_milliseconds() as u64,
524                min_measured,
525            );
526        }
527        self
528    }
529
530    /// /Sets/Appends whitelist hosts. The first call sets the whitelist hosts and
531    /// any subsequent calls appends additional hosts. Passing an empty string will
532    /// clear and disable the whitelist. White space is striped from the hosts.
533    ///
534    /// This policy filters requests to all other policies, only allowing requests
535    /// to the hosts contained in the whitelist. Any host not in the whitelist will
536    /// be ignored and a connection will not be established. This policy is useful
537    /// for ensuring that the driver will only connect to a predefined set of hosts.
538    ///
539    ///
540    /// Examples: "127.0.0.1" "127.0.0.1,127.0.0.2", "server1.domain.com"
541    pub fn set_whitelist_filtering(&mut self, hosts: Vec<String>) -> &Self {
542        unsafe {
543            cass_cluster_set_whitelist_filtering(self.0, hosts.join(",").as_ptr() as *const i8);
544        }
545        self
546    }
547
548    /// Enable/Disable Nagel's algorithm on connections.
549    ///
550    ///
551    /// <b>Default:</b> true (disables Nagel's algorithm).
552    pub fn set_tcp_nodelay(&mut self, enable: bool) -> &Self {
553        unsafe {
554            cass_cluster_set_tcp_nodelay(self.0, if enable { cass_true } else { cass_false });
555        }
556        self
557    }
558
559    /// Enable/Disable TCP keep-alive
560    ///
561    ///
562    /// Default: false (disabled).
563    pub fn set_tcp_keepalive(&mut self, enable: bool, delay: Duration) -> &Self {
564        unsafe {
565            cass_cluster_set_tcp_keepalive(
566                self.0,
567                if enable { cass_true } else { cass_false },
568                delay.whole_seconds() as u32,
569            );
570        }
571        self
572    }
573
574    /// Sets the timestamp generator used to assign timestamps to all requests
575    /// unless overridden by setting the timestamp on a statement or a batch.
576    ///
577    ///
578    /// Default: server-side timestamp generator.
579    pub fn set_timestamp_gen(&mut self, tsg: &TimestampGen) -> &mut Self {
580        unsafe {
581            cass_cluster_set_timestamp_gen(self.0, TimestampGen::inner(tsg));
582            self
583        }
584    }
585
586    /// Sets the amount of time between heartbeat messages and controls the amount
587    /// of time the connection must be idle before sending heartbeat messages. This
588    /// is useful for preventing intermediate network devices from dropping
589    /// connections.
590    ///
591    ///
592    /// Default: 30 seconds
593    pub fn set_connection_heartbeat_interval(&mut self, hearbeat: Duration) -> &mut Self {
594        unsafe {
595            cass_cluster_set_connection_heartbeat_interval(self.0, hearbeat.whole_seconds() as u32);
596            self
597        }
598    }
599
600    /// Sets the amount of time a connection is allowed to be without a successful
601    /// heartbeat response before being terminated and scheduled for reconnection.
602    ///
603    ///
604    /// Default: 60 seconds
605    pub fn set_connection_idle_timeout(&mut self, timeout: Duration) -> &mut Self {
606        unsafe {
607            cass_cluster_set_connection_idle_timeout(self.0, timeout.whole_seconds() as u32);
608            self
609        }
610    }
611
612    /// Sets the retry policy used for all requests unless overridden by setting
613    /// a retry policy on a statement or a batch.
614    ///
615    ///
616    /// Default: The same policy as would be created by the function:
617    /// cass_retry_policy_default_new(). This policy will retry on a read timeout
618    /// if there was enough replicas, but no data present, on a write timeout if a
619    /// logged batch request failed to write the batch log, and on a unavailable
620    /// error it retries using a new host. In all other cases the default policy
621    /// will return an error.
622    pub fn set_retry_policy(&mut self, retry_policy: RetryPolicy) -> &mut Self {
623        unsafe {
624            cass_cluster_set_retry_policy(self.0, retry_policy.inner());
625            self
626        }
627    }
628
629    /// Enable/Disable retrieving and updating schema metadata. If disabled
630    /// this is allows the driver to skip over retrieving and updating schema
631    /// metadata, but it also disables the usage of token-aware routing and
632    /// cass_session_get_schema() will always return an empty object. This can be
633    /// useful for reducing the startup overhead of short-lived sessions.
634    ///
635    ///
636    /// Default: true (enabled).
637    pub fn set_use_schema(&mut self, enabled: bool) -> &Self {
638        unsafe {
639            cass_cluster_set_use_schema(self.0, if enabled { cass_true } else { cass_false });
640        }
641        self
642    }
643
644    /// Enable constant speculative executions with the supplied settings.
645    ///
646    /// To disable, use [`Cluster::set_no_speculative_execution_policy`].
647    ///
648    /// Default: disabled
649    pub fn set_constant_speculative_execution_policy(
650        &self,
651        constant_delay: Duration,
652        max_speculative_executions: u8,
653    ) -> Result<&Self> {
654        unsafe {
655            cass_cluster_set_constant_speculative_execution_policy(
656                self.0,
657                constant_delay
658                    .whole_milliseconds()
659                    .try_into()
660                    .expect("panic: duration too big."),
661                max_speculative_executions as _,
662            )
663            .to_result(self)
664        }
665    }
666
667    /// Disables speculative executions.
668    ///
669    /// Default: disabled
670    pub fn set_no_speculative_execution_policy(&self) -> Result<&Self> {
671        unsafe { cass_cluster_set_no_speculative_execution_policy(self.0).to_result(self) }
672    }
673}