github.com/ronaksoft/rony@v0.16.26-0.20230807065236-1743dbfe6959/edge/options.go (about) 1 package edge 2 3 import ( 4 "runtime" 5 "time" 6 7 "go.opentelemetry.io/otel/trace" 8 9 "github.com/ronaksoft/rony" 10 "github.com/ronaksoft/rony/errors" 11 gossipCluster "github.com/ronaksoft/rony/internal/cluster/gossip" 12 dummyGateway "github.com/ronaksoft/rony/internal/gateway/dummy" 13 tcpGateway "github.com/ronaksoft/rony/internal/gateway/tcp" 14 scyllaRouter "github.com/ronaksoft/rony/internal/router/scylla" 15 sqlRouter "github.com/ronaksoft/rony/internal/router/sql" 16 udpTunnel "github.com/ronaksoft/rony/internal/tunnel/udp" 17 "github.com/ronaksoft/rony/log" 18 "github.com/scylladb/gocqlx/v2" 19 "gorm.io/gorm" 20 ) 21 22 /* 23 Creation Time: 2020 - Feb - 22 24 Created by: (ehsan) 25 Maintainers: 26 1. Ehsan N. Moosa (E2) 27 Auditor: Ehsan N. Moosa (E2) 28 Copyright Ronak Software Group 2020 29 */ 30 31 type Option func(edge *Server) 32 33 func WithTracer(tracer trace.Tracer) Option { 34 return func(edge *Server) { 35 if tracer == nil { 36 return 37 } 38 edge.tracer = tracer 39 } 40 } 41 42 func WithJSONDispatcher() Option { 43 return func(edge *Server) { 44 edge.dispatcher = &JSONDispatcher{} 45 } 46 } 47 48 // WithCustomDispatcher enables custom dispatcher to write your specific event handlers. 49 func WithCustomDispatcher(d Dispatcher) Option { 50 return func(edge *Server) { 51 if d != nil { 52 edge.dispatcher = d 53 } 54 } 55 } 56 57 type GossipClusterConfig struct { 58 Bootstrap bool 59 ReplicaSet uint64 60 GossipIP string 61 GossipPort int 62 AdvertisedIP string 63 AdvertisedPort int 64 } 65 66 // WithGossipCluster enables the cluster in gossip mode. This mod is eventually consistent mode but there is 67 // no need to a central key-value store or any other 3rd party service to run the cluster 68 func WithGossipCluster(clusterConfig GossipClusterConfig) Option { 69 return func(edge *Server) { 70 edge.cluster = gossipCluster.New( 71 gossipCluster.Config{ 72 ServerID: edge.serverID, 73 Bootstrap: clusterConfig.Bootstrap, 74 ReplicaSet: clusterConfig.ReplicaSet, 75 GossipPort: clusterConfig.GossipPort, 76 GossipIP: clusterConfig.GossipIP, 77 AdvertisedIP: clusterConfig.AdvertisedIP, 78 AdvertisedPort: clusterConfig.AdvertisedPort, 79 Logger: log.DefaultLogger.With("GossipCluster"), 80 }, 81 ) 82 } 83 } 84 85 func WithCustomerCluster(c rony.Cluster) Option { 86 return func(edge *Server) { 87 edge.cluster = c 88 } 89 } 90 91 type gatewayDelegate struct { 92 edge *Server 93 } 94 95 func (g gatewayDelegate) OnConnect(c rony.Conn, kvs ...*rony.KeyValue) { 96 g.edge.onGatewayConnect(c, kvs...) 97 } 98 99 func (g gatewayDelegate) OnMessage(c rony.Conn, streamID int64, data []byte) { 100 g.edge.onGatewayMessage(c, streamID, data) 101 } 102 103 func (g gatewayDelegate) OnClose(c rony.Conn) { 104 g.edge.onGatewayClose(c) 105 } 106 107 type TcpGatewayConfig struct { 108 Concurrency int 109 ListenAddress string 110 MaxBodySize int 111 MaxIdleTime time.Duration 112 Protocol rony.GatewayProtocol 113 ExternalAddrs []string 114 TextDataFrame bool 115 } 116 117 // WithTcpGateway set the gateway to tcp which can support http and/or websocket 118 // Only one gateway could be set and if you set another gateway it panics on runtime. 119 func WithTcpGateway(gatewayConfig TcpGatewayConfig) Option { 120 return func(edge *Server) { 121 if edge.gateway != nil { 122 panic(errors.ErrGatewayAlreadyInitialized) 123 } 124 if gatewayConfig.Protocol == rony.Undefined { 125 gatewayConfig.Protocol = rony.TCP 126 } 127 if gatewayConfig.Concurrency == 0 { 128 gatewayConfig.Concurrency = runtime.NumCPU() * 100 129 } 130 gatewayTcp, err := tcpGateway.New(tcpGateway.Config{ 131 Concurrency: gatewayConfig.Concurrency, 132 ListenAddress: gatewayConfig.ListenAddress, 133 MaxBodySize: gatewayConfig.MaxBodySize, 134 MaxIdleTime: gatewayConfig.MaxIdleTime, 135 Protocol: gatewayConfig.Protocol, 136 ExternalAddrs: gatewayConfig.ExternalAddrs, 137 Logger: log.DefaultLogger.With("TCPGateway"), 138 TextDataFrame: gatewayConfig.TextDataFrame, 139 }) 140 if err != nil { 141 panic(err) 142 } 143 144 gatewayTcp.Subscribe(&gatewayDelegate{edge: edge}) 145 edge.gateway = gatewayTcp 146 } 147 } 148 149 type DummyGatewayConfig = dummyGateway.Config 150 151 // WithTestGateway set the gateway to a dummy gateway which is useful for writing tests. 152 // Only one gateway could be set and if you set another gateway it panics on runtime. 153 func WithTestGateway(gatewayConfig DummyGatewayConfig) Option { 154 return func(edge *Server) { 155 if edge.gateway != nil { 156 panic(errors.ErrGatewayAlreadyInitialized) 157 } 158 gatewayDummy, err := dummyGateway.New(gatewayConfig) 159 if err != nil { 160 panic(err) 161 } 162 gatewayDummy.Subscribe(&gatewayDelegate{edge: edge}) 163 edge.gateway = gatewayDummy 164 } 165 } 166 167 func WithCustomGateway(gateway rony.Gateway) Option { 168 return func(edge *Server) { 169 if edge.gateway != nil { 170 panic(errors.ErrGatewayAlreadyInitialized) 171 } 172 173 gateway.Subscribe(&gatewayDelegate{edge: edge}) 174 edge.gateway = gateway 175 } 176 } 177 178 type UdpTunnelConfig struct { 179 ListenAddress string 180 MaxBodySize int 181 ExternalAddrs []string 182 } 183 184 // WithUdpTunnel set the tunnel to a udp based tunnel which provides communication channel between 185 // edge servers. 186 func WithUdpTunnel(config UdpTunnelConfig) Option { 187 return func(edge *Server) { 188 tunnelUDP, err := udpTunnel.New(udpTunnel.Config{ 189 ServerID: edge.GetServerID(), 190 ListenAddress: config.ListenAddress, 191 MaxBodySize: config.MaxBodySize, 192 ExternalAddrs: config.ExternalAddrs, 193 Logger: log.DefaultLogger.With("Tunnel"), 194 }) 195 if err != nil { 196 panic(err) 197 } 198 tunnelUDP.MessageHandler = edge.onTunnelMessage 199 edge.tunnel = tunnelUDP 200 } 201 } 202 203 func WithCustomRouter(r rony.Router) Option { 204 return func(edge *Server) { 205 edge.router = r 206 } 207 } 208 209 type ScyllaRouterConfig struct { 210 DbSession gocqlx.Session 211 } 212 213 func WithScyllaRouter(config ScyllaRouterConfig) Option { 214 return func(edge *Server) { 215 edge.router = scyllaRouter.New(config.DbSession) 216 } 217 } 218 219 type SqlRouterConfig struct { 220 DB *gorm.DB 221 } 222 223 func WithSqlRouter(config SqlRouterConfig) Option { 224 return func(edge *Server) { 225 edge.router = sqlRouter.New(config.DB) 226 } 227 }