TimeNormalizer option for average eta
Vladimir Bauer
6 years ago
| 102 | 102 | // |
| 103 | 103 | // `wcc` optional WC config |
| 104 | 104 | func AverageETA(style TimeStyle, wcc ...WC) Decorator { |
| 105 | return NewAverageETA(style, time.Now(), wcc...) | |
| 105 | return NewAverageETA(style, time.Now(), nil, wcc...) | |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | 108 | // NewAverageETA decorator with user provided start time. |
| 111 | 111 | // |
| 112 | 112 | // `startTime` start time |
| 113 | 113 | // |
| 114 | // `normalizer` available implementations are [FixedIntervalTimeNormalizer|MaxTolerateTimeNormalizer] | |
| 115 | // | |
| 114 | 116 | // `wcc` optional WC config |
| 115 | func NewAverageETA(style TimeStyle, startTime time.Time, wcc ...WC) Decorator { | |
| 117 | func NewAverageETA(style TimeStyle, startTime time.Time, normalizer TimeNormalizer, wcc ...WC) Decorator { | |
| 116 | 118 | var wc WC |
| 117 | 119 | for _, widthConf := range wcc { |
| 118 | 120 | wc = widthConf |
| 119 | 121 | } |
| 120 | 122 | wc.Init() |
| 121 | 123 | d := &averageETA{ |
| 122 | WC: wc, | |
| 123 | startTime: startTime, | |
| 124 | producer: chooseTimeProducer(style), | |
| 124 | WC: wc, | |
| 125 | startTime: startTime, | |
| 126 | normalizer: normalizer, | |
| 127 | producer: chooseTimeProducer(style), | |
| 125 | 128 | } |
| 126 | 129 | return d |
| 127 | 130 | } |
| 129 | 132 | type averageETA struct { |
| 130 | 133 | WC |
| 131 | 134 | startTime time.Time |
| 135 | normalizer TimeNormalizer | |
| 132 | 136 | producer func(time.Duration) string |
| 133 | 137 | completeMsg *string |
| 134 | 138 | } |
| 138 | 142 | return d.FormatMsg(*d.completeMsg) |
| 139 | 143 | } |
| 140 | 144 | |
| 141 | timeElapsed := time.Since(d.startTime) | |
| 142 | v := float64(timeElapsed) / float64(st.Current) | |
| 143 | if math.IsInf(v, 0) || math.IsNaN(v) { | |
| 144 | v = 0 | |
| 145 | } | |
| 146 | remaining := time.Duration((st.Total - st.Current) * int64(math.Round(v))) | |
| 145 | var remaining time.Duration | |
| 146 | if st.Current != 0 { | |
| 147 | durPerItem := float64(time.Since(d.startTime)) / float64(st.Current) | |
| 148 | durPerItem = math.Round(durPerItem) | |
| 149 | remaining = time.Duration((st.Total - st.Current) * int64(durPerItem)) | |
| 150 | if d.normalizer != nil { | |
| 151 | remaining = d.normalizer.Normalize(remaining) | |
| 152 | } | |
| 153 | } | |
| 147 | 154 | return d.FormatMsg(d.producer(remaining)) |
| 148 | 155 | } |
| 149 | 156 | |