6.1
Option dan Fallback hystrix
hystrix.NewClient menerima opts ...Option, dan Option sendiri hanyalah func(*Client) hystrix/options.go:13-141. Setiap option menulis satu field ke struct Client, lalu NewClient memindahkan field-field itu ke hystrix.CommandConfig lewat hystrix.ConfigureCommand hystrix/hystrix_client.go:54-802. Pemisahan ini yang perlu dipegang: option hanya mengisi field heimdall, sedangkan ConfigureCommand yang menentukan perilaku circuit breaker sebenarnya.
Option, field, dan nilai default
Tabel berikut memetakan setiap option ke field Client yang diisinya. Struct Client beserta field-field itu ada di hystrix/hystrix_client.go:21-373, dan nilai default yang dipasang NewClient tercantum di hystrix/hystrix_client.go:39-494.
| Option | Field Client | Default | Catatan |
|---|---|---|---|
WithCommandName | hystrixCommandName | string kosong (tidak ada konstanta default) | dipakai sebagai kunci hystrix.ConfigureCommand |
WithHystrixTimeout | hystrixTimeout | 30 * time.Second | dikirim sebagai Timeout |
WithMaxConcurrentRequests | maxConcurrentRequests | 100 | dikirim sebagai MaxConcurrentRequests |
WithRequestVolumeThreshold | requestVolumeThreshold | 10 | dikirim sebagai RequestVolumeThreshold |
WithSleepWindow | sleepWindow | 500 * time.Millisecond | dikirim sebagai SleepWindow |
WithErrorPercentThreshold | errorPercentThreshold | 25 | dikirim sebagai ErrorPercentThreshold |
WithFallbackFunc / WithFallbackCtxFunc | fallbackFunc | nil | lihat bagian alur fallback |
WithHTTPTimeout / WithHTTPClient | field di dalam httpclient.Client | httpclient.NewClient() | diteruskan ke httpclient |
WithRetryCount / WithRetrier | retryCount / retrier | 0 / heimdall.NewNoRetrier() | detail di Retry dan Backoff |
WithRetryableStatusCodes | retryableCodes | kosong | diurutkan dengan slices.Sort |
Baris-baris tabel itu bertumpu pada definisi option berikut: WithCommandName hystrix/options.go:16-215, WithHystrixTimeout hystrix/options.go:30-356, WithMaxConcurrentRequests hystrix/options.go:37-42, WithRequestVolumeThreshold hystrix/options.go:44-49, WithSleepWindow hystrix/options.go:51-56, dan WithErrorPercentThreshold hystrix/options.go:58-63.
Option retry pada klien yang sama ada di hystrix/options.go:82-9411, sedangkan WithRetryableStatusCodes mengurutkan status code dengan slices.Sort sebelum menyimpannya hystrix/options.go:104-11312. Dua option yang diarahkan ke httpclient menyusun ulang option dari paket itu, yaitu WithHTTPTimeout hystrix/options.go:23-2813 dan WithHTTPClient hystrix/options.go:96-10214.
Nilai default di tabel di atas diverifikasi langsung oleh TestOptionsHaveDefaults hystrix/options_test.go:35-4615, sedangkan TestOptionsAreSet memastikan setiap option menimpa field yang benar, termasuk retryableCodes yang menjadi []int{200, 400, 424} hystrix/options_test.go:12-3316.
Dua timeout yang berbeda
Klien ini memegang dua timeout dengan tugas berbeda. WithHystrixTimeout hanya menyimpan durasi ke field hystrixTimeout hystrix/options.go:30-356, dan nilainya dipakai hystrix untuk mencatat error. WithHTTPTimeout, sebaliknya, meneruskan durasi ke httpclient.WithHTTPTimeout pada klien HTTP di dalamnya hystrix/options.go:23-2813, sehingga yang berubah adalah kapan klien HTTP sendiri mengembalikan timeout. README menyebut kedua nilai ini sebaiknya sama kecuali ada kebutuhan khusus README.md:10817. Opsi httpclient yang lain dibahas di Option pada httpclient.
⚠️ Kedua durasi dikonversi ke bilangan bulat milidetik oleh
durationToIntsebelum masuk kehystrix.CommandConfighystrix/hystrix_client.go:82-9218. Artinya nilai di bawah satu milidetik terpotong menjadi0, dan nilai yang melewatimaxIntdipangkas kemaxInttanpa error.TestOptionsAreSetbahkan memakaiWithHystrixTimeout(1100)tanpa satuan, yaitu 1100 nanodetik, sehingga field berisi1100tetapi konfigurasi hystrix menjadi0milidetik hystrix/options_test.go:12-3316.
Konfigurasi yang dikirim ke hystrix-go
Setelah semua option dijalankan, NewClient memanggil hystrix.ConfigureCommand dengan nama command sebagai kunci dan lima nilai sebagai isi CommandConfig: Timeout, MaxConcurrentRequests, RequestVolumeThreshold, SleepWindow, dan ErrorPercentThreshold hystrix/hystrix_client.go:71-7719.
Nama command itu juga muncul di pesan error pembuatan request, misalnya "GET %s - request creation failed: %w" pada Get hystrix/hystrix_client.go:95-10520. Jadi WithCommandName bukan sekadar label: ia menamai konfigurasi circuit breaker sekaligus memberi konteks pada error yang dikembalikan.
Alur fallback
Fallback diteruskan sebagai argumen ketiga hystrix.DoC di dalam hystrixDo hystrix/hystrix_client.go:220-24121. Fungsi run yang dibungkus hystrix.DoC mengembalikan error dari hhc.client.Do, atau mengembalikan errRetryableCode ketika status code ada di retryableCodes maupun bernilai 500 ke atas. errRetryableCode didefinisikan sebagai errors.New("server returned status code to retry") hystrix/hystrix_client.go:5222.
graph LR
RUN["run func: hhc.client.Do"] -->|"doErr tidak nil"| FB
RUN -->|"status di retryableCodes atau 5xx"| RETRY["errRetryableCode"]
RETRY --> FB["hystrix.DoC dengan fallback"]
FB --> CALL["hhc.fallbackFunc(ctx, err)"]
CALL -->|"return nil"| OK["hystrixDo: response, nil"]
CALL -->|"return err"| FAIL["hystrixDo: nil, error"]
OK --> DONE["Do: err == nil, loop retry berhenti"]
style OK fill:#2d7d46,color:#fff
style DONE fill:#2d7d46,color:#fff
style RETRY fill:#f59e0b,color:#000
style CALL fill:#8b5cf6,color:#fff
style FAIL fill:#dc2626,color:#fff
%% fig: Alur fallback di hystrixDo
%% desc: Fungsi run mengembalikan doErr atau errRetryableCode, lalu hystrix.DoC memanggil fallbackFunc; nilai balik fallback menentukan apakah Do mengembalikan error atau melanjutkan tanpa error.Perilaku cabang-cabang itu tampak di test paket hystrix.
| Skenario | Cara memasang | Hasil yang diperiksa |
|---|---|---|
| Tanpa fallback | hanya option command, timeout, dan threshold | err berisi "no such host" hystrix/hystrix_client_test.go:518-53323 |
| Fallback mengembalikan error | WithFallbackFunc(func(err error) error { return err }) | err berisi "fallback failed" hystrix/hystrix_client_test.go:535-55624 |
Fallback nil | WithFallbackFunc(nil) | err berisi "unsupported protocol scheme" hystrix/hystrix_client_test.go:558-57625 |
| Fallback ber-context dipanggil | WithFallbackCtxFunc | variabel called menjadi true hystrix/hystrix_client_test.go:578-60126 |
Fallback mengembalikan nil | WithFallbackCtxFunc yang return nil | err bernilai nil hystrix/hystrix_client_test.go:603-62227 |
Fallback tanpa context dan dengan context
Paket ini mendefinisikan dua tipe fungsi: fallbackFunc func(error) error dan fallbackCtxFunc func(context.Context, error) error hystrix/hystrix_client.go:18-1928. WithFallbackFunc menerima bentuk pertama, tetapi tidak menyimpannya langsung: ia membungkusnya menjadi WithFallbackCtxFunc dan mengabaikan context.Context yang diberikan hystrix/options.go:65-8029. WithFallbackCtxFunc adalah yang benar-benar menulis ke field fallbackFunc hystrix/options.go:76-8030.
Bentuk kedua ini yang akhirnya diserahkan ke hystrix.DoC, karena field fallbackFunc pada struct Client bertipe func(ctx context.Context, err error) error hystrix/hystrix_client.go:21-373.
WithFallbackFunc(nil) tidak memasang fallback apa pun: option itu mengembalikan fungsi kosong func(_ *Client) {} sehingga field fallbackFunc tetap nil hystrix/options.go:65-7331. Karena itu, klien dengan WithFallbackFunc(nil) tetap mengembalikan error HTTP aslinya hystrix/hystrix_client_test.go:558-57625.
Setelah fallback mengembalikan nil
Fallback yang mengembalikan nil membuat hystrix.DoC selesai tanpa error, sehingga hystrixDo mengembalikan response beserta nil sebagai error hystrix/hystrix_client.go:220-24121. Di lapisan atas, Do melihat err == nil lalu mencatat Success() pada error budget dan keluar dari loop retry hystrix/hystrix_client.go:198-20732. Konsekuensinya, request dianggap berhasil walaupun tidak ada response HTTP yang terisi.
Jalur khusus berlaku untuk errRetryableCode: Do mengembalikan response bersama nil ketika errors.Is(err, errRetryableCode) benar, dan hanya mengembalikan error lain apa adanya hystrix/hystrix_client.go:209-21533.
⚠️ Fallback yang selalu mengembalikan
nilakan menutupi kegagalan sepenuhnya: tidak ada error yang naik ke pemanggil, sehingga retry tidak pernah berjalan. Pastikan fallback mengembalikan error ketika kegagalan perlu terlihat, seperti pola diTestHystrixHTTPClientReturnsFallbackFailureWithAFallBackFunctionWhichReturnAnErrorhystrix/hystrix_client_test.go:535-55624.