diff --git a/examples/dubbo/with-hystrix-go-client/app/example_fallback_filter.go b/examples/dubbo/with-hystrix-go-client/app/example_fallback_filter.go new file mode 100644 index 0000000000000000000000000000000000000000..748d91d6234cf774d429f0341e48b50dfeabd601 --- /dev/null +++ b/examples/dubbo/with-hystrix-go-client/app/example_fallback_filter.go @@ -0,0 +1,61 @@ +package main + +import ( + "github.com/apache/dubbo-go/common/extension" + "github.com/apache/dubbo-go/common/logger" + "github.com/apache/dubbo-go/filter" + "github.com/apache/dubbo-go/filter/impl" + "github.com/apache/dubbo-go/protocol" + "time" +) + +const ( + EXAMPLE_FALLBACK_FILTER = "example_fallback" +) + +//This is an example filter that handles result from hystrix filter +//Define your filters and write your service downgrade strategy like this +//TODO: Maybe a base fallback filter can be offered +type ExampleFallbackFilter struct { +} + +func GetExampleFallbackFilter() filter.Filter { + return &ExampleFallbackFilter{} +} + +//The name should be the same as in your config +//Put the filter in front of hystrix filter +func init() { + extension.SetFilter(EXAMPLE_FALLBACK_FILTER, GetExampleFallbackFilter) +} + +func (ff *ExampleFallbackFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + return invoker.Invoke(invocation) + +} +func (ff *ExampleFallbackFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result { + if err := result.Error(); err != nil { + hystrixError, ok := err.(*impl.HystrixFilterError) + if ok { + if hystrixError.FailByHystrix() { + logger.Debugf("[Example fallback filter]%s get error caused by %s", invocation.MethodName(), hystrixError.Error()) + //Handle the error caused by Hystrix, including circuit breaking, concurrency limit and timeout + //The detailed error source can be got through hystrixError.Error() + //In this example we return a mock result under this circumstance + res := User{ + "MockID", + "MockName", + 55, + time.Now(), + Gender(MAN), + } + *(invocation.Reply().(*User)) = res + result.SetResult(&res) + result.SetError(nil) + } + } + } + //If the error is not caused by hystrix, the result doesn't come from hystrix filter or there's no error, + //we just return it here. + return result +} diff --git a/filter/impl/hystrix_filter_test.go b/filter/impl/hystrix_filter_test.go index f3cb198eec8fee9b17052dde3b9c1d896e0cbeb2..1b5cd66899deec28c0eb4d53ede0e7bdd9ed8cbc 100644 --- a/filter/impl/hystrix_filter_test.go +++ b/filter/impl/hystrix_filter_test.go @@ -34,6 +34,12 @@ func init() { mockInitHystrixConfig() } +func TestNewHystrixFilterError(t *testing.T) { + get := NewHystrixFilterError(errors.New("test"), true) + assert.True(t, get.(*HystrixFilterError).FailByHystrix()) + assert.Equal(t, "test", get.Error()) +} + func mockInitHystrixConfig() { //Mock config confConsumer = &HystrixFilterConfig{ @@ -51,7 +57,7 @@ func mockInitHystrixConfig() { } confConsumer.Configs["userp"] = &CommandConfigWithError{ 2000, - 8, + 64, 15, 4000, 45, @@ -59,7 +65,7 @@ func mockInitHystrixConfig() { } confConsumer.Configs["userp_m"] = &CommandConfigWithError{ 1200, - 12, + 64, 5, 6000, 60, @@ -85,7 +91,7 @@ func TestGetConfig_1(t *testing.T) { configGot := getConfig("com.ikurento.user.UserProvider", "GetUser", true) assert.NotNil(t, configGot) assert.Equal(t, 1200, configGot.Timeout) - assert.Equal(t, 12, configGot.MaxConcurrentRequests) + assert.Equal(t, 64, configGot.MaxConcurrentRequests) assert.Equal(t, 6000, configGot.SleepWindow) assert.Equal(t, 60, configGot.ErrorPercentThreshold) assert.Equal(t, 5, configGot.RequestVolumeThreshold) @@ -95,7 +101,7 @@ func TestGetConfig_2(t *testing.T) { configGot := getConfig("com.ikurento.user.UserProvider", "GetUser0", true) assert.NotNil(t, configGot) assert.Equal(t, 2000, configGot.Timeout) - assert.Equal(t, 8, configGot.MaxConcurrentRequests) + assert.Equal(t, 64, configGot.MaxConcurrentRequests) assert.Equal(t, 4000, configGot.SleepWindow) assert.Equal(t, 45, configGot.ErrorPercentThreshold) assert.Equal(t, 15, configGot.RequestVolumeThreshold) @@ -187,3 +193,14 @@ func TestHystricFilter_Invoke_CircuitBreak_Omit_Exception(t *testing.T) { assert.False(t, lastRest) } + +func TestGetHystrixFilterConsumer(t *testing.T) { + get := GetHystrixFilterConsumer() + assert.NotNil(t, get) + assert.True(t, get.(*HystrixFilter).COrP) +} +func TestGetHystrixFilterProvider(t *testing.T) { + get := GetHystrixFilterProvider() + assert.NotNil(t, get) + assert.False(t, get.(*HystrixFilter).COrP) +}