Lompat ke konten
dokumentasi.id
Commit ecba1e8
v2
Star2,8 rb

6.1

Option dan Fallback hystrix

hystrix.NewClient menerima opts ...Option, dan Option sendiri hanyalah func(*Client) hystrix/options.go:13-14. 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-80. 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-37, dan nilai default yang dipasang NewClient tercantum di hystrix/hystrix_client.go:39-49.

OptionField ClientDefaultCatatan
WithCommandNamehystrixCommandNamestring kosong (tidak ada konstanta default)dipakai sebagai kunci hystrix.ConfigureCommand
WithHystrixTimeouthystrixTimeout30 * time.Seconddikirim sebagai Timeout
WithMaxConcurrentRequestsmaxConcurrentRequests100dikirim sebagai MaxConcurrentRequests
WithRequestVolumeThresholdrequestVolumeThreshold10dikirim sebagai RequestVolumeThreshold
WithSleepWindowsleepWindow500 * time.Milliseconddikirim sebagai SleepWindow
WithErrorPercentThresholderrorPercentThreshold25dikirim sebagai ErrorPercentThreshold
WithFallbackFunc / WithFallbackCtxFuncfallbackFuncnillihat bagian alur fallback
WithHTTPTimeout / WithHTTPClientfield di dalam httpclient.Clienthttpclient.NewClient()diteruskan ke httpclient
WithRetryCount / WithRetrierretryCount / retrier0 / heimdall.NewNoRetrier()detail di Retry dan Backoff
WithRetryableStatusCodesretryableCodeskosongdiurutkan dengan slices.Sort

Baris-baris tabel itu bertumpu pada definisi option berikut: WithCommandName hystrix/options.go:16-21, WithHystrixTimeout hystrix/options.go:30-35, 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-94, sedangkan WithRetryableStatusCodes mengurutkan status code dengan slices.Sort sebelum menyimpannya hystrix/options.go:104-113. Dua option yang diarahkan ke httpclient menyusun ulang option dari paket itu, yaitu WithHTTPTimeout hystrix/options.go:23-28 dan WithHTTPClient hystrix/options.go:96-102.

Nilai default di tabel di atas diverifikasi langsung oleh TestOptionsHaveDefaults hystrix/options_test.go:35-46, sedangkan TestOptionsAreSet memastikan setiap option menimpa field yang benar, termasuk retryableCodes yang menjadi []int{200, 400, 424} hystrix/options_test.go:12-33.

Dua timeout yang berbeda

Klien ini memegang dua timeout dengan tugas berbeda. WithHystrixTimeout hanya menyimpan durasi ke field hystrixTimeout hystrix/options.go:30-35, dan nilainya dipakai hystrix untuk mencatat error. WithHTTPTimeout, sebaliknya, meneruskan durasi ke httpclient.WithHTTPTimeout pada klien HTTP di dalamnya hystrix/options.go:23-28, sehingga yang berubah adalah kapan klien HTTP sendiri mengembalikan timeout. README menyebut kedua nilai ini sebaiknya sama kecuali ada kebutuhan khusus README.md:108. Opsi httpclient yang lain dibahas di Option pada httpclient.

⚠️ Kedua durasi dikonversi ke bilangan bulat milidetik oleh durationToInt sebelum masuk ke hystrix.CommandConfig hystrix/hystrix_client.go:82-92. Artinya nilai di bawah satu milidetik terpotong menjadi 0, dan nilai yang melewati maxInt dipangkas ke maxInt tanpa error. TestOptionsAreSet bahkan memakai WithHystrixTimeout(1100) tanpa satuan, yaitu 1100 nanodetik, sehingga field berisi 1100 tetapi konfigurasi hystrix menjadi 0 milidetik hystrix/options_test.go:12-33.

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-77.

Nama command itu juga muncul di pesan error pembuatan request, misalnya "GET %s - request creation failed: %w" pada Get hystrix/hystrix_client.go:95-105. 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-241. 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:52.

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.
Fig. 1: Alur fallback di hystrixDoFungsi 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.

SkenarioCara memasangHasil yang diperiksa
Tanpa fallbackhanya option command, timeout, dan thresholderr berisi "no such host" hystrix/hystrix_client_test.go:518-533
Fallback mengembalikan errorWithFallbackFunc(func(err error) error { return err })err berisi "fallback failed" hystrix/hystrix_client_test.go:535-556
Fallback nilWithFallbackFunc(nil)err berisi "unsupported protocol scheme" hystrix/hystrix_client_test.go:558-576
Fallback ber-context dipanggilWithFallbackCtxFuncvariabel called menjadi true hystrix/hystrix_client_test.go:578-601
Fallback mengembalikan nilWithFallbackCtxFunc yang return nilerr bernilai nil hystrix/hystrix_client_test.go:603-622

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-19. WithFallbackFunc menerima bentuk pertama, tetapi tidak menyimpannya langsung: ia membungkusnya menjadi WithFallbackCtxFunc dan mengabaikan context.Context yang diberikan hystrix/options.go:65-80. WithFallbackCtxFunc adalah yang benar-benar menulis ke field fallbackFunc hystrix/options.go:76-80.

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-37.

WithFallbackFunc(nil) tidak memasang fallback apa pun: option itu mengembalikan fungsi kosong func(_ *Client) {} sehingga field fallbackFunc tetap nil hystrix/options.go:65-73. Karena itu, klien dengan WithFallbackFunc(nil) tetap mengembalikan error HTTP aslinya hystrix/hystrix_client_test.go:558-576.

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-241. Di lapisan atas, Do melihat err == nil lalu mencatat Success() pada error budget dan keluar dari loop retry hystrix/hystrix_client.go:198-207. 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-215.

⚠️ Fallback yang selalu mengembalikan nil akan 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 di TestHystrixHTTPClientReturnsFallbackFailureWithAFallBackFunctionWhichReturnAnError hystrix/hystrix_client_test.go:535-556.