| 24 | ) |
| 25 | |
| 26 | func getContainerClient(ctx context.Context, cfg *Config, hedge bool) (*container.Client, error) { |
| 27 | var err error |
| 28 | |
| 29 | retry := policy.RetryOptions{ |
| 30 | MaxRetries: maxRetries, |
| 31 | // The values for TryTimeout, RetryDelay and MaxRetryDelay are inherited from the old Azure SDK |
| 32 | // (azure-storage-blob-go). |
| 33 | // |
| 34 | // See https://github.com/Azure/azure-storage-blob-go/blob/905b628ceb292e8d769ae62fb7cc5c5e949360db/azblob/zc_policy_retry.go#L89. |
| 35 | TryTimeout: 1 * time.Minute, |
| 36 | RetryDelay: 4 * time.Second, |
| 37 | MaxRetryDelay: 120 * time.Second, |
| 38 | } |
| 39 | if deadline, ok := ctx.Deadline(); ok { |
| 40 | retry.TryTimeout = time.Until(deadline) |
| 41 | } |
| 42 | |
| 43 | customTransport := http.DefaultTransport.(*http.Transport).Clone() |
| 44 | // Default MaxIdleConnsPerHost is 2, increase that to reduce connection turnover |
| 45 | customTransport.MaxIdleConnsPerHost = 100 |
| 46 | // set total max idle connections to a high number |
| 47 | customTransport.MaxIdleConns = 100 |
| 48 | |
| 49 | // add instrumentation |
| 50 | transport := instrumentation.NewTransport(customTransport) |
| 51 | var stats *hedgedhttp.Stats |
| 52 | |
| 53 | // hedge if desired (0 means disabled) |
| 54 | if hedge && cfg.HedgeRequestsAt != 0 { |
| 55 | transport, stats, err = hedgedhttp.NewRoundTripperAndStats(cfg.HedgeRequestsAt, cfg.HedgeRequestsUpTo, transport) |
| 56 | if err != nil { |
| 57 | return nil, err |
| 58 | } |
| 59 | instrumentation.PublishHedgedMetrics(stats) |
| 60 | } |
| 61 | |
| 62 | opts := azblob.ClientOptions{} |
| 63 | opts.Transport = &http.Client{Transport: transport} |
| 64 | opts.Retry = retry |
| 65 | opts.Telemetry = policy.TelemetryOptions{ |
| 66 | ApplicationID: "Tempo", |
| 67 | } |
| 68 | |
| 69 | accountName := getStorageAccountName(cfg) |
| 70 | u, err := url.Parse(fmt.Sprintf("https://%s.%s", accountName, cfg.Endpoint)) |
| 71 | |
| 72 | // If the endpoint doesn't start with blob. we can assume Azurite is being used |
| 73 | // So the endpoint should follow Azurite URL style |
| 74 | // https://learn.microsoft.com/en-us/rest/api/storageservices/get-blob#emulated-storage-service-uri |
| 75 | if !strings.HasPrefix(cfg.Endpoint, "blob.") { |
| 76 | u, err = url.Parse(fmt.Sprintf("http://%s/%s", cfg.Endpoint, accountName)) |
| 77 | } |
| 78 | |
| 79 | if err != nil { |
| 80 | return nil, err |
| 81 | } |
| 82 | |
| 83 | var client *azblob.Client |