NewFrontedClients returns one *http.Client per SNI host in cfg.SNIHosts. Each client has an independent transport/connection-pool so requests to different SNI names are genuinely separate TLS sessions, each consuming its own throttle bucket. pollTimeout is the per-request ceiling; it should comfort
(cfg FrontingConfig, pollTimeout time.Duration, probeURL string)
| 54 | // mail.google.com) because they terminate at different fronts, so a |
| 55 | // shared cache produces no resumes — only same-SNI reuse helps. |
| 56 | func NewFrontedClients(cfg FrontingConfig, pollTimeout time.Duration, probeURL string) []*http.Client { |
| 57 | hosts := cfg.SNIHosts |
| 58 | if len(hosts) == 0 { |
| 59 | hosts = []string{"www.google.com"} |
| 60 | } |
| 61 | caches := make(map[string]tls.ClientSessionCache, len(hosts)) |
| 62 | for _, sni := range hosts { |
| 63 | if _, ok := caches[sni]; !ok { |
| 64 | caches[sni] = tls.NewLRUClientSessionCache(8) |
| 65 | } |
| 66 | } |
| 67 | clients := make([]*http.Client, len(hosts)) |
| 68 | for i, sni := range hosts { |
| 69 | clients[i] = newFrontedClient(cfg.GoogleIP, sni, pollTimeout, caches[sni]) |
| 70 | } |
| 71 | hosts, clients = filterFrontedClientsByProbe(hosts, clients, probeURL) |
| 72 | // Best-effort: warm each SNI's TLS session in the background so the |
| 73 | // first real poll resumes (saves ~140 ms TLS handshake per cold conn). |
| 74 | // Zero Apps Script executions consumed; failures are silently ignored. |
| 75 | prewarmFrontedClients(cfg.GoogleIP, hosts, caches) |
| 76 | return clients |
| 77 | } |
| 78 | |
| 79 | type frontedProbeResult struct { |
| 80 | index int |
no test coverage detected