@@ -26,10 +26,12 @@ package frontend
2626
2727import (
2828 "context"
29+ "strconv"
2930 "time"
3031
3132 "go.temporal.io/api/workflowservice/v1"
3233 "google.golang.org/grpc"
34+ "google.golang.org/grpc/metadata"
3335
3436 "go.temporal.io/server/client"
3537 "go.temporal.io/server/common/clock"
@@ -42,9 +44,13 @@ import (
4244 "go.temporal.io/server/common/rpc/interceptor"
4345)
4446
45- var (
47+ const (
48+ dcRedirectionContextHeaderName = "xdc-redirection"
49+
4650 dcRedirectionMetricsPrefix = "DCRedirection"
51+ )
4752
53+ var (
4854 localAPIResponses = map [string ]responseConstructorFn {
4955 // Namespace APIs, namespace APIs does not require redirection
5056 "DeprecateNamespace" : func () any { return & workflowservice.DeprecateNamespaceResponse {} },
@@ -173,6 +179,9 @@ func (i *RedirectionInterceptor) Intercept(
173179 if _ , isWorkflowHandler := info .Server .(* WorkflowHandler ); ! isWorkflowHandler {
174180 return handler (ctx , req )
175181 }
182+ if ! i .redirectionAllowed (ctx ) {
183+ return handler (ctx , req )
184+ }
176185
177186 _ , methodName := interceptor .SplitMethodName (info .FullMethod )
178187 if _ , ok := localAPIResponses [methodName ]; ok {
@@ -262,3 +271,22 @@ func (i *RedirectionInterceptor) afterCall(
262271 metricsHandler .Counter (metrics .ClientRedirectionFailures .GetMetricName ()).Record (1 )
263272 }
264273}
274+
275+ func (i * RedirectionInterceptor ) redirectionAllowed (
276+ ctx context.Context ,
277+ ) bool {
278+ // default to allow dc redirection
279+ md , ok := metadata .FromIncomingContext (ctx )
280+ if ! ok {
281+ return true
282+ }
283+ values := md .Get (dcRedirectionContextHeaderName )
284+ if len (values ) == 0 {
285+ return true
286+ }
287+ allowed , err := strconv .ParseBool (values [0 ])
288+ if err != nil {
289+ return true
290+ }
291+ return allowed
292+ }
0 commit comments