1use std::time::Duration;
2
3use memberlist_proto::Label;
4
5use super::proto::{DelegateVersion, ProtocolVersion};
6
7#[cfg(any(
8 feature = "crc32",
9 feature = "xxhash32",
10 feature = "xxhash64",
11 feature = "xxhash3",
12 feature = "murmur3"
13))]
14use super::proto::ChecksumAlgorithm;
15
16#[cfg(any(
17 feature = "zstd",
18 feature = "snappy",
19 feature = "brotli",
20 feature = "lz4",
21))]
22use super::proto::CompressAlgorithm;
23
24#[cfg(feature = "encryption")]
25use super::proto::{EncryptionAlgorithm, SecretKey, SecretKeys};
26
27#[cfg(feature = "metrics")]
28pub use super::proto::MetricLabels;
29
30#[viewit::viewit(getters(vis_all = "pub"), setters(vis_all = "pub", prefix = "with"))]
32#[derive(Debug, Clone)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct Options {
35 #[viewit(
41 getter(const, style = "ref", attrs(doc = "Get the label of the node."),),
42 setter(attrs(doc = "Set the label of the node. (Builder pattern)"),)
43 )]
44 #[cfg_attr(
45 feature = "serde",
46 serde(default, skip_serializing_if = "Label::is_empty")
47 )]
48 label: Label,
49
50 #[viewit(
53 getter(
54 const,
55 attrs(
56 doc = "Get if the check that inbound packets and gossip streams need to be label prefixed."
57 ),
58 ),
59 setter(attrs(
60 doc = "Set if the check that inbound packets and gossip streams need to be label prefixed. (Builder pattern)"
61 ),)
62 )]
63 skip_inbound_label_check: bool,
64
65 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
69 #[viewit(
70 getter(
71 const,
72 attrs(
73 doc = "Returns the timeout for establishing a stream connection with a remote node for a full state sync, and for stream read and write operations."
74 )
75 ),
76 setter(
77 const,
78 attrs(
79 doc = "Sets the timeout for establishing a stream connection with a remote node for a full state sync, and for stream read and write operations (Builder pattern)."
80 )
81 )
82 )]
83 timeout: Duration,
84
85 #[viewit(
91 getter(
92 const,
93 attrs(
94 doc = "Returns the number of nodes that will be asked to perform an indirect probe of a node in the case a direct probe fails."
95 )
96 ),
97 setter(
98 const,
99 attrs(
100 doc = "Sets the number of nodes that will be asked to perform an indirect probe of a node in the case a direct probe fails (Builder pattern)."
101 )
102 )
103 )]
104 indirect_checks: usize,
105
106 #[viewit(
116 getter(const, attrs(doc = "Returns the retransmit mult")),
117 setter(const, attrs(doc = "Sets the retransmit mult (Builder pattern)."))
118 )]
119 retransmit_mult: usize,
120
121 #[viewit(
133 getter(const, attrs(doc = "Returns the suspicion mult")),
134 setter(const, attrs(doc = "Sets the suspicion mult (Builder pattern)."))
135 )]
136 suspicion_mult: usize,
137
138 #[viewit(
154 getter(const, attrs(doc = "Returns the suspicion max timeout mult")),
155 setter(
156 const,
157 attrs(doc = "Sets the suspicion max timeout mult (Builder pattern).")
158 )
159 )]
160 suspicion_max_timeout_mult: usize,
161
162 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
171 #[viewit(
172 getter(const, attrs(doc = "Returns the push pull interval")),
173 setter(const, attrs(doc = "Sets the push pull interval (Builder pattern)."))
174 )]
175 push_pull_interval: Duration,
176
177 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
181 #[viewit(
182 getter(const, attrs(doc = "Returns the probe interval")),
183 setter(const, attrs(doc = "Sets the probe interval (Builder pattern)."))
184 )]
185 probe_interval: Duration,
186 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
190 #[viewit(
191 getter(const, attrs(doc = "Returns the probe timeout")),
192 setter(const, attrs(doc = "Sets the probe timeout (Builder pattern)."))
193 )]
194 probe_timeout: Duration,
195
196 #[viewit(
200 getter(const, attrs(doc = "Returns whether disable promised pings or not")),
201 setter(
202 const,
203 attrs(doc = "Sets whether disable promised pings or not (Builder pattern).")
204 )
205 )]
206 disable_reliable_pings: bool,
207
208 #[viewit(
212 getter(const, attrs(doc = "Returns the awareness max multiplier")),
213 setter(
214 const,
215 attrs(doc = "Sets the awareness max multiplier (Builder pattern).")
216 )
217 )]
218 awareness_max_multiplier: usize,
219
220 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
226 #[viewit(
227 getter(const, attrs(doc = "Returns the gossip interval")),
228 setter(const, attrs(doc = "Sets the gossip interval (Builder pattern)."))
229 )]
230 gossip_interval: Duration,
231
232 #[viewit(
237 getter(const, attrs(doc = "Returns the gossip nodes")),
238 setter(const, attrs(doc = "Sets the gossip nodes (Builder pattern)."))
239 )]
240 gossip_nodes: usize,
241 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
244 #[viewit(
245 getter(const, attrs(doc = "Returns the gossip to the dead timeout")),
246 setter(
247 const,
248 attrs(doc = "Sets the gossip to the dead timeout (Builder pattern).")
249 )
250 )]
251 gossip_to_the_dead_time: Duration,
252
253 #[viewit(
255 getter(
256 const,
257 attrs(doc = "Returns the protocol version this node is speaking")
258 ),
259 setter(
260 const,
261 attrs(doc = "Sets the protocol version this node is speaking (Builder pattern).")
262 )
263 )]
264 protocol_version: ProtocolVersion,
265
266 #[viewit(
271 getter(
272 const,
273 attrs(doc = "Returns the delegate version this node is speaking")
274 ),
275 setter(
276 const,
277 attrs(doc = "Sets the delegate version this node is speaking (Builder pattern).")
278 )
279 )]
280 delegate_version: DelegateVersion,
281
282 #[viewit(
286 getter(const, attrs(doc = "Returns the handoff queue depth")),
287 setter(const, attrs(doc = "Sets the handoff queue depth (Builder pattern)."))
288 )]
289 handoff_queue_depth: usize,
290
291 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
295 #[viewit(
296 getter(const, attrs(doc = "Returns the dead node reclaim time")),
297 setter(
298 const,
299 attrs(doc = "Sets the dead node reclaim time (Builder pattern).")
300 )
301 )]
302 dead_node_reclaim_time: Duration,
303
304 #[cfg_attr(feature = "serde", serde(with = "humantime_serde"))]
307 #[viewit(
308 getter(const, attrs(doc = "Returns the queue check interval")),
309 setter(const, attrs(doc = "Sets the queue check interval (Builder pattern)."))
310 )]
311 queue_check_interval: Duration,
312
313 #[cfg(any(
321 feature = "crc32",
322 feature = "xxhash32",
323 feature = "xxhash64",
324 feature = "xxhash3",
325 feature = "murmur3",
326 ))]
327 #[cfg_attr(
328 feature = "serde",
329 serde(skip_serializing_if = "Option::is_none", default)
330 )]
331 #[viewit(
332 getter(
333 const,
334 attrs(
335 doc = "Returns the checksum algorithm for the packets sent through transport.",
336 cfg(any(
337 feature = "crc32",
338 feature = "xxhash32",
339 feature = "xxhash64",
340 feature = "xxhash3",
341 feature = "murmur3",
342 )),
343 cfg_attr(
344 docsrs,
345 doc(cfg(any(
346 feature = "crc32",
347 feature = "xxhash32",
348 feature = "xxhash64",
349 feature = "xxhash3",
350 feature = "murmur3",
351 )))
352 )
353 )
354 ),
355 setter(
356 const,
357 rename = "maybe_checksum_algo",
358 attrs(
359 doc = "Sets the checksum algorithm for the packets sent through transport.",
360 cfg(any(
361 feature = "crc32",
362 feature = "xxhash32",
363 feature = "xxhash64",
364 feature = "xxhash3",
365 feature = "murmur3",
366 )),
367 cfg_attr(
368 docsrs,
369 doc(cfg(any(
370 feature = "crc32",
371 feature = "xxhash32",
372 feature = "xxhash64",
373 feature = "xxhash3",
374 feature = "murmur3",
375 )))
376 )
377 )
378 )
379 )]
380 checksum_algo: Option<ChecksumAlgorithm>,
381
382 #[cfg(any(
388 feature = "encryption",
389 feature = "lz4",
390 feature = "zstd",
391 feature = "brotli",
392 feature = "snappy",
393 ))]
394 #[cfg_attr(
395 docsrs,
396 doc(cfg(any(
397 feature = "encryption",
398 feature = "lz4",
399 feature = "zstd",
400 feature = "brotli",
401 feature = "snappy",
402 )))
403 )]
404 #[viewit(
405 getter(
406 const,
407 attrs(
408 doc = "Get the size of a message that should be offload to [`rayon`] thread pool for encryption or compression.",
409 cfg(any(
410 feature = "encryption",
411 feature = "lz4",
412 feature = "zstd",
413 feature = "brotli",
414 feature = "snappy",
415 )),
416 cfg_attr(docsrs, doc(cfg(any(feature = "compression", feature = "encryption"))))
417 ),
418 ),
419 setter(attrs(
420 doc = "Set the size of a message that should be offload to [`rayon`] thread pool for encryption or compression. (Builder pattern)",
421 cfg(any(
422 feature = "encryption",
423 feature = "lz4",
424 feature = "zstd",
425 feature = "brotli",
426 feature = "snappy",
427 )),
428 cfg_attr(
429 docsrs,
430 doc(cfg(any(
431 feature = "encryption",
432 feature = "lz4",
433 feature = "zstd",
434 feature = "brotli",
435 feature = "snappy",
436 )))
437 )
438 ),)
439 )]
440 offload_size: usize,
441
442 #[cfg(feature = "encryption")]
452 #[cfg_attr(
453 feature = "serde",
454 serde(skip_serializing_if = "Option::is_none", default)
455 )]
456 #[viewit(
457 getter(
458 const,
459 attrs(
460 doc = "Returns the encryption algorithm for the messages sent through transport.",
461 cfg(feature = "encryption"),
462 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
463 )
464 ),
465 setter(
466 const,
467 rename = "maybe_encryption_algo",
468 attrs(
469 doc = "Sets the encryption algorithm for the messages sent through transport.",
470 cfg(feature = "encryption"),
471 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
472 )
473 )
474 )]
475 encryption_algo: Option<EncryptionAlgorithm>,
476
477 #[cfg_attr(feature = "serde", serde(default))]
481 #[cfg(feature = "encryption")]
482 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
483 #[viewit(
484 getter(
485 const,
486 attrs(
487 doc = "Get whether to enforce encryption for outgoing gossip. It is used for upshifting from unencrypted to encrypted gossip on a running cluster.",
488 cfg(feature = "encryption"),
489 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
490 ),
491 ),
492 setter(attrs(
493 doc = "Set whether to enforce encryption for outgoing gossip. It is used for upshifting from unencrypted to encrypted gossip on a running cluster. (Builder pattern)",
494 cfg(feature = "encryption"),
495 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
496 ),)
497 )]
498 gossip_verify_outgoing: bool,
499
500 #[cfg_attr(feature = "serde", serde(default))]
504 #[cfg(feature = "encryption")]
505 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
506 #[viewit(
507 getter(
508 const,
509 attrs(
510 doc = "Get whether to enforce encryption for incoming gossip. It is used for upshifting from unencrypted to encrypted gossip on a running cluster.",
511 cfg(feature = "encryption"),
512 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
513 ),
514 ),
515 setter(attrs(
516 doc = "Set whether to enforce encryption for incoming gossip. It is used for upshifting from unencrypted to encrypted gossip on a running cluster. (Builder pattern)",
517 cfg(feature = "encryption"),
518 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
519 ),)
520 )]
521 gossip_verify_incoming: bool,
522
523 #[cfg(feature = "encryption")]
530 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
531 #[viewit(
532 getter(
533 const,
534 style = "ref",
535 result(converter(fn = "Option::as_ref"), type = "Option<&SecretKey>"),
536 attrs(
537 doc = "Get the primary encryption key in a keyring.",
538 cfg(feature = "encryption"),
539 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
540 ),
541 ),
542 setter(
543 rename = "maybe_primary_key",
544 attrs(
545 doc = "Set the primary encryption key in a keyring. (Builder pattern)",
546 cfg(feature = "encryption"),
547 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
548 ),
549 )
550 )]
551 #[cfg_attr(
552 feature = "serde",
553 serde(skip_serializing_if = "Option::is_none", default)
554 )]
555 primary_key: Option<SecretKey>,
556
557 #[viewit(
559 getter(
560 style = "ref",
561 result(converter(fn = "AsRef::as_ref"), type = "&[SecretKey]"),
562 attrs(
563 doc = "Get all of the encryption keys used internally.",
564 cfg(feature = "encryption"),
565 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
566 ),
567 ),
568 setter(attrs(
569 doc = "Set all of the encryption keys used internally. (Builder pattern)",
570 cfg(feature = "encryption"),
571 cfg_attr(docsrs, doc(cfg(feature = "encryption")))
572 ))
573 )]
574 #[cfg(feature = "encryption")]
575 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
576 #[cfg_attr(
577 feature = "serde",
578 serde(skip_serializing_if = "SecretKeys::is_empty", default)
579 )]
580 secret_keys: SecretKeys,
581
582 #[cfg(any(
586 feature = "zstd",
587 feature = "lz4",
588 feature = "brotli",
589 feature = "snappy",
590 ))]
591 #[cfg_attr(
592 feature = "serde",
593 serde(skip_serializing_if = "Option::is_none", default)
594 )]
595 #[viewit(
596 getter(
597 const,
598 attrs(
599 doc = "Returns the compress algorithm for the messages sent through transport.",
600 cfg(any(
601 feature = "zstd",
602 feature = "lz4",
603 feature = "brotli",
604 feature = "snappy",
605 )),
606 cfg_attr(
607 docsrs,
608 doc(cfg(any(
609 feature = "zstd",
610 feature = "lz4",
611 feature = "brotli",
612 feature = "snappy",
613 )))
614 )
615 )
616 ),
617 setter(
618 const,
619 rename = "maybe_compress_algo",
620 attrs(
621 doc = "Sets the compress algorithm for the messages sent through transport.",
622 cfg(any(
623 feature = "zstd",
624 feature = "lz4",
625 feature = "brotli",
626 feature = "snappy",
627 )),
628 cfg_attr(
629 docsrs,
630 doc(cfg(any(
631 feature = "zstd",
632 feature = "lz4",
633 feature = "brotli",
634 feature = "snappy",
635 )))
636 )
637 )
638 )
639 )]
640 compress_algo: Option<CompressAlgorithm>,
641
642 #[viewit(
644 getter(
645 style = "ref",
646 const,
647 attrs(
648 doc = "Get the metric labels for the memberlist.",
649 cfg(feature = "metrics"),
650 cfg_attr(docsrs, doc(cfg(feature = "metrics")))
651 )
652 ),
653 setter(attrs(
654 doc = "Sets the metric labels for the memberlist.",
655 cfg(feature = "metrics"),
656 cfg_attr(docsrs, doc(cfg(feature = "metrics")))
657 ))
658 )]
659 #[cfg(feature = "metrics")]
660 metric_labels: std::sync::Arc<MetricLabels>,
661}
662
663impl Default for Options {
664 #[inline]
665 fn default() -> Self {
666 Self::lan()
667 }
668}
669
670impl Options {
671 #[inline]
678 pub fn lan() -> Self {
679 Self {
680 label: Label::empty(),
681 timeout: Duration::from_secs(10), indirect_checks: 3, retransmit_mult: 4, suspicion_mult: 4, suspicion_max_timeout_mult: 6, push_pull_interval: Duration::from_secs(30), probe_interval: Duration::from_millis(500), probe_timeout: Duration::from_secs(1), disable_reliable_pings: false, awareness_max_multiplier: 8, gossip_interval: Duration::from_millis(200), gossip_nodes: 3, gossip_to_the_dead_time: Duration::from_secs(30), delegate_version: DelegateVersion::V1,
695 protocol_version: ProtocolVersion::V1,
696 handoff_queue_depth: 1024,
697 dead_node_reclaim_time: Duration::ZERO,
698 queue_check_interval: Duration::from_secs(30),
699 skip_inbound_label_check: false,
700 #[cfg(any(
701 feature = "crc32",
702 feature = "xxhash32",
703 feature = "xxhash64",
704 feature = "xxhash3",
705 feature = "murmur3"
706 ))]
707 checksum_algo: None,
708 #[cfg(any(
709 feature = "encryption",
710 feature = "lz4",
711 feature = "zstd",
712 feature = "brotli",
713 feature = "snappy",
714 ))]
715 offload_size: 1024 * 1024,
716 #[cfg(feature = "encryption")]
717 encryption_algo: None,
718 #[cfg(feature = "encryption")]
719 gossip_verify_incoming: false,
720 #[cfg(feature = "encryption")]
721 gossip_verify_outgoing: false,
722 #[cfg(feature = "encryption")]
723 primary_key: None,
724 #[cfg(feature = "encryption")]
725 secret_keys: SecretKeys::new(),
726 #[cfg(any(
727 feature = "zstd",
728 feature = "lz4",
729 feature = "brotli",
730 feature = "snappy",
731 ))]
732 compress_algo: None,
733 #[cfg(feature = "metrics")]
734 metric_labels: std::sync::Arc::new(MetricLabels::new()),
735 }
736 }
737
738 #[inline]
742 pub fn wan() -> Self {
743 Self::lan()
744 .with_timeout(Duration::from_secs(30))
745 .with_suspicion_mult(6)
746 .with_push_pull_interval(Duration::from_secs(60))
747 .with_probe_timeout(Duration::from_secs(3))
748 .with_probe_interval(Duration::from_secs(5))
749 .with_gossip_nodes(4)
750 .with_gossip_interval(Duration::from_millis(500))
751 .with_gossip_to_the_dead_time(Duration::from_secs(60))
752 }
753
754 #[inline]
758 pub fn local() -> Self {
759 Self::lan()
760 .with_timeout(Duration::from_secs(1))
761 .with_indirect_checks(1)
762 .with_retransmit_mult(2)
763 .with_suspicion_mult(3)
764 .with_push_pull_interval(Duration::from_secs(15))
765 .with_probe_timeout(Duration::from_millis(200))
766 .with_probe_interval(Duration::from_secs(1))
767 .with_gossip_interval(Duration::from_millis(100))
768 .with_gossip_to_the_dead_time(Duration::from_secs(15))
769 }
770
771 #[cfg(any(
774 feature = "zstd",
775 feature = "lz4",
776 feature = "brotli",
777 feature = "snappy",
778 ))]
779 #[cfg_attr(
780 docsrs,
781 doc(cfg(any(
782 feature = "zstd",
783 feature = "lz4",
784 feature = "brotli",
785 feature = "snappy",
786 )))
787 )]
788 #[inline]
789 pub fn with_compress_algo(mut self, compress_algo: CompressAlgorithm) -> Self {
790 self.compress_algo = Some(compress_algo);
791 self
792 }
793
794 #[cfg(any(
797 feature = "crc32",
798 feature = "xxhash32",
799 feature = "xxhash64",
800 feature = "xxhash3",
801 feature = "murmur3",
802 ))]
803 #[cfg_attr(
804 docsrs,
805 doc(cfg(any(
806 feature = "crc32",
807 feature = "xxhash32",
808 feature = "xxhash64",
809 feature = "xxhash3",
810 feature = "murmur3",
811 )))
812 )]
813 #[inline]
814 pub fn with_checksum_algo(mut self, checksum_algo: ChecksumAlgorithm) -> Self {
815 self.checksum_algo = Some(checksum_algo);
816 self
817 }
818
819 #[cfg(feature = "encryption")]
822 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
823 #[inline]
824 pub fn with_encryption_algo(mut self, encryption_algo: EncryptionAlgorithm) -> Self {
825 self.encryption_algo = Some(encryption_algo);
826 self
827 }
828
829 #[cfg(feature = "encryption")]
831 #[cfg_attr(docsrs, doc(cfg(feature = "encryption")))]
832 #[inline]
833 pub fn with_primary_key(mut self, primary_key: SecretKey) -> Self {
834 self.primary_key = Some(primary_key);
835 self
836 }
837}
838
839#[cfg(test)]
840mod tests {
841 use super::*;
842
843 #[test]
844 fn test_constructor() {
845 let _ = Options::wan();
846 let _ = Options::lan();
847 let _ = Options::local();
848 }
849}