1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use super::super::{
    super::regions::{DomainWithPort, IpAddrWithPort},
    ResponseError, RetriedStatsInfo,
};
use maybe_owned::{MaybeOwned, MaybeOwnedMut};
use qiniu_http::{Extensions, Metrics};
use std::mem::replace;

/// 选择器反馈
///
/// 用以修正选择器的选择逻辑,优化选择结果
#[derive(Debug)]
pub struct ChooserFeedback<'f> {
    ips: &'f [IpAddrWithPort],
    domain: Option<&'f DomainWithPort>,
    retried: MaybeOwned<'f, RetriedStatsInfo>,
    extensions: MaybeOwnedMut<'f, Extensions>,
    metrics: Option<&'f Metrics>,
    error: Option<&'f ResponseError>,
}

impl<'f> ChooserFeedback<'f> {
    /// 创建选择器反馈构建器
    #[inline]
    pub fn builder(ips: &'f [IpAddrWithPort]) -> ChooserFeedbackBuilder<'f> {
        ChooserFeedbackBuilder::new(ips)
    }

    /// 获取 IP 地址列表
    #[inline]
    pub fn ips(&'f self) -> &'f [IpAddrWithPort] {
        self.ips
    }

    /// 获取域名
    ///
    /// 如果不存在域名的话,则返回 [`None`]
    #[inline]
    pub fn domain(&'f self) -> Option<&'f DomainWithPort> {
        self.domain
    }

    /// 获取重试统计信息
    #[inline]
    pub fn retried(&'f self) -> &'f RetriedStatsInfo {
        &self.retried
    }

    /// 获取扩展信息
    #[inline]
    pub fn extensions(&'f self) -> &'f Extensions {
        &self.extensions
    }

    /// 获取扩展信息的可变引用
    #[inline]
    pub fn extensions_mut(&'f mut self) -> &'f mut Extensions {
        &mut self.extensions
    }

    /// 获取 HTTP 响应的指标信息
    #[inline]
    pub fn metrics(&'f self) -> Option<&'f Metrics> {
        self.metrics
    }

    /// 获取 HTTP 响应错误
    #[inline]
    pub fn error(&'f self) -> Option<&'f ResponseError> {
        self.error
    }
}

/// 选择器反馈构建器
#[derive(Debug)]
pub struct ChooserFeedbackBuilder<'f>(ChooserFeedback<'f>);

impl<'f> ChooserFeedbackBuilder<'f> {
    /// 创建选择器反馈构建器
    #[inline]
    pub fn new(ips: &'f [IpAddrWithPort]) -> Self {
        Self(ChooserFeedback {
            ips,
            domain: None,
            metrics: None,
            error: None,
            retried: Default::default(),
            extensions: Default::default(),
        })
    }

    /// 设置域名
    #[inline]
    pub fn domain(&mut self, domain: &'f DomainWithPort) -> &mut Self {
        self.0.domain = Some(domain);
        self
    }

    /// 设置重试统计信息
    #[inline]
    pub fn retried(&mut self, retried: &'f RetriedStatsInfo) -> &mut Self {
        self.0.retried = MaybeOwned::from(retried);
        self
    }

    /// 获取扩展信息的可变引用
    #[inline]
    pub fn extensions(&mut self, extensions: &'f mut Extensions) -> &mut Self {
        self.0.extensions = MaybeOwnedMut::from(extensions);
        self
    }

    /// 设置 HTTP 响应的指标信息
    #[inline]
    pub fn metrics(&mut self, metrics: &'f Metrics) -> &mut Self {
        self.0.metrics = Some(metrics);
        self
    }

    /// 设置 HTTP 响应错误
    #[inline]
    pub fn error(&mut self, error: &'f ResponseError) -> &mut Self {
        self.0.error = Some(error);
        self
    }

    /// 构建选择器反馈器
    #[inline]
    pub fn build(&mut self) -> ChooserFeedback<'f> {
        let ips = self.0.ips;
        replace(
            &mut self.0,
            ChooserFeedback {
                ips,
                domain: None,
                metrics: None,
                error: None,
                retried: Default::default(),
                extensions: Default::default(),
            },
        )
    }
}