| 135 | } |
| 136 | |
| 137 | func (s *Topom) RefreshProxyStats(timeout time.Duration) (*sync2.Future, error) { |
| 138 | s.mu.Lock() |
| 139 | defer s.mu.Unlock() |
| 140 | ctx, err := s.newContext() |
| 141 | if err != nil { |
| 142 | return nil, err |
| 143 | } |
| 144 | var fut sync2.Future |
| 145 | for _, p := range ctx.proxy { |
| 146 | fut.Add() |
| 147 | go func(p *models.Proxy) { |
| 148 | stats := s.newProxyStats(p, timeout) |
| 149 | stats.UnixTime = time.Now().Unix() |
| 150 | fut.Done(p.Token, stats) |
| 151 | |
| 152 | switch x := stats.Stats; { |
| 153 | case x == nil: |
| 154 | case x.Closed || x.Online: |
| 155 | default: |
| 156 | if err := s.OnlineProxy(p.AdminAddr); err != nil { |
| 157 | log.WarnErrorf(err, "auto online proxy-[%s] failed", p.Token) |
| 158 | } |
| 159 | } |
| 160 | }(p) |
| 161 | } |
| 162 | go func() { |
| 163 | stats := make(map[string]*ProxyStats) |
| 164 | for k, v := range fut.Wait() { |
| 165 | stats[k] = v.(*ProxyStats) |
| 166 | } |
| 167 | s.mu.Lock() |
| 168 | defer s.mu.Unlock() |
| 169 | s.stats.proxies = stats |
| 170 | }() |
| 171 | return &fut, nil |
| 172 | } |