11package main
22
33import (
4+ "fmt"
5+ "net"
46 "os"
57 "time"
68
79 "github.com/uber-go/tally"
810 "github.com/urfave/cli/v2"
911 "go.uber.org/fx"
1012 "go.uber.org/yarpc"
13+ "go.uber.org/yarpc/api/peer"
1114 "go.uber.org/yarpc/transport/grpc"
1215 "go.uber.org/zap"
1316
17+ sharddistributorv1 "github.com/uber/cadence/.gen/proto/sharddistributor/v1"
1418 "github.com/uber/cadence/common/clock"
1519 "github.com/uber/cadence/common/log"
1620 "github.com/uber/cadence/service/sharddistributor/canary"
1721 "github.com/uber/cadence/service/sharddistributor/canary/executors"
1822 "github.com/uber/cadence/service/sharddistributor/client/clientcommon"
23+ "github.com/uber/cadence/service/sharddistributor/client/executorclient"
24+ "github.com/uber/cadence/service/sharddistributor/client/spectatorclient"
1925 "github.com/uber/cadence/service/sharddistributor/config"
2026 "github.com/uber/cadence/tools/common/commoncli"
2127)
@@ -25,6 +31,7 @@ const (
2531 defaultShardDistributorEndpoint = "127.0.0.1:7943"
2632 defaultFixedNamespace = "shard-distributor-canary"
2733 defaultEphemeralNamespace = "shard-distributor-canary-ephemeral"
34+ defaultCanaryGRPCPort = 7953 // Port for canary to receive ping requests
2835
2936 shardDistributorServiceName = "cadence-shard-distributor"
3037)
@@ -33,11 +40,12 @@ func runApp(c *cli.Context) {
3340 endpoint := c .String ("endpoint" )
3441 fixedNamespace := c .String ("fixed-namespace" )
3542 ephemeralNamespace := c .String ("ephemeral-namespace" )
43+ canaryGRPCPort := c .Int ("canary-grpc-port" )
3644
37- fx .New (opts (fixedNamespace , ephemeralNamespace , endpoint )).Run ()
45+ fx .New (opts (fixedNamespace , ephemeralNamespace , endpoint , canaryGRPCPort )).Run ()
3846}
3947
40- func opts (fixedNamespace , ephemeralNamespace , endpoint string ) fx.Option {
48+ func opts (fixedNamespace , ephemeralNamespace , endpoint string , canaryGRPCPort int ) fx.Option {
4149 configuration := clientcommon.Config {
4250 Namespaces : []clientcommon.NamespaceConfig {
4351 {Namespace : fixedNamespace , HeartBeatInterval : 1 * time .Second , MigrationMode : config .MigrationModeONBOARDED },
@@ -49,22 +57,51 @@ func opts(fixedNamespace, ephemeralNamespace, endpoint string) fx.Option {
4957 },
5058 }
5159
60+ canaryGRPCAddress := fmt .Sprintf ("127.0.0.1:%d" , canaryGRPCPort )
61+
62+ // Create listener for GRPC inbound
63+ listener , err := net .Listen ("tcp" , canaryGRPCAddress )
64+ if err != nil {
65+ panic (err )
66+ }
67+
5268 transport := grpc .NewTransport ()
53- yarpcConfig := yarpc.Config {
54- Name : "shard-distributor-canary" ,
55- Outbounds : yarpc.Outbounds {
56- shardDistributorServiceName : {
57- Unary : transport .NewSingleOutbound (endpoint ),
58- },
59- },
69+
70+ executorMetadata := executorclient.ExecutorMetadata {
71+ clientcommon .GrpcAddressMetadataKey : canaryGRPCAddress ,
6072 }
6173
6274 return fx .Options (
6375 fx .Supply (
6476 fx .Annotate (tally .NoopScope , fx .As (new (tally.Scope ))),
6577 fx .Annotate (clock .NewRealTimeSource (), fx .As (new (clock.TimeSource ))),
66- yarpcConfig ,
6778 configuration ,
79+ transport ,
80+ executorMetadata ,
81+ ),
82+
83+ fx .Provide (func (peerChooser spectatorclient.SpectatorPeerChooserInterface ) yarpc.Config {
84+ return yarpc.Config {
85+ Name : "shard-distributor-canary" ,
86+ Inbounds : yarpc.Inbounds {
87+ transport .NewInbound (listener ), // Listen for incoming ping requests
88+ },
89+ Outbounds : yarpc.Outbounds {
90+ shardDistributorServiceName : {
91+ Unary : transport .NewSingleOutbound (endpoint ),
92+ Stream : transport .NewSingleOutbound (endpoint ),
93+ },
94+ // canary-to-canary outbound uses peer chooser to route to other canary instances
95+ "shard-distributor-canary" : {
96+ Unary : transport .NewOutbound (peerChooser ),
97+ Stream : transport .NewOutbound (peerChooser ),
98+ },
99+ },
100+ }
101+ }),
102+
103+ fx .Provide (
104+ func (t * grpc.Transport ) peer.Transport { return t },
68105 ),
69106 fx .Provide (
70107 yarpc .NewDispatcher ,
@@ -73,12 +110,17 @@ func opts(fixedNamespace, ephemeralNamespace, endpoint string) fx.Option {
73110 fx .Provide (zap .NewDevelopment ),
74111 fx .Provide (log .NewLogger ),
75112
113+ // Register canary procedures with dispatcher
114+ fx .Invoke (func (dispatcher * yarpc.Dispatcher , server sharddistributorv1.ShardDistributorExecutorCanaryAPIYARPCServer ) {
115+ dispatcher .Register (sharddistributorv1 .BuildShardDistributorExecutorCanaryAPIYARPCProcedures (server ))
116+ }),
117+
76118 // Start the YARPC dispatcher
77119 fx .Invoke (func (lc fx.Lifecycle , dispatcher * yarpc.Dispatcher ) {
78120 lc .Append (fx .StartStopHook (dispatcher .Start , dispatcher .Stop ))
79121 }),
80122
81- // Include the canary module
123+ // Include the canary module - it will set up spectator peer choosers and canary client
82124 canary .Module (canary.NamespacesNames {FixedNamespace : fixedNamespace , EphemeralNamespace : ephemeralNamespace , ExternalAssignmentNamespace : executors .ExternalAssignmentNamespace , SharddistributorServiceName : shardDistributorServiceName }),
83125 )
84126}
@@ -110,6 +152,11 @@ func buildCLI() *cli.App {
110152 Value : defaultEphemeralNamespace ,
111153 Usage : "namespace for ephemeral shard creation testing" ,
112154 },
155+ & cli.IntFlag {
156+ Name : "canary-grpc-port" ,
157+ Value : defaultCanaryGRPCPort ,
158+ Usage : "port for canary to receive ping requests" ,
159+ },
113160 },
114161 Action : func (c * cli.Context ) error {
115162 runApp (c )
0 commit comments