github.com/ronaksoft/rony@v0.16.26-0.20230807065236-1743dbfe6959/internal/gateway/dummy/gateway.go (about) 1 package dummyGateway 2 3 import ( 4 "sync" 5 "sync/atomic" 6 7 "github.com/ronaksoft/rony" 8 "github.com/ronaksoft/rony/errors" 9 ) 10 11 /* 12 Creation Time: 2020 - Oct - 02 13 Created by: (ehsan) 14 Maintainers: 15 1. Ehsan N. Moosa (E2) 16 Auditor: Ehsan N. Moosa (E2) 17 Copyright Ronak Software Group 2020 18 */ 19 20 type Config struct { 21 Exposer func(gw *Gateway) 22 } 23 24 type Gateway struct { 25 conns map[uint64]*Conn 26 connsMtx sync.RWMutex 27 connsTotal int32 28 delegate rony.GatewayDelegate 29 } 30 31 func New(config Config) (*Gateway, error) { 32 g := &Gateway{ 33 conns: make(map[uint64]*Conn, 8192), 34 } 35 36 // Call the exposer make caller have access to this gateway object 37 if config.Exposer != nil { 38 config.Exposer(g) 39 } 40 41 return g, nil 42 } 43 44 func (g *Gateway) Subscribe(d rony.GatewayDelegate) { 45 g.delegate = d 46 } 47 48 // OpenConn opens a persistent connection to the gateway. For short-lived use RPC or REST methods. 49 func (g *Gateway) OpenConn( 50 connID uint64, persistent bool, 51 onReceiveMessage func(connID uint64, streamID int64, data []byte), 52 hdr ...*rony.KeyValue, 53 ) { 54 dConn := g.openConn(connID, persistent) 55 dConn.onMessage = func(connID uint64, streamID int64, data []byte, _ map[string]string) { 56 onReceiveMessage(connID, streamID, data) 57 } 58 59 g.delegate.OnConnect(dConn, hdr...) 60 } 61 62 func (g *Gateway) openConn(connID uint64, persistent bool) *Conn { 63 dConn := NewConn(connID).SetPersistent(persistent) 64 g.connsMtx.Lock() 65 g.conns[connID] = dConn 66 g.connsMtx.Unlock() 67 68 atomic.AddInt32(&g.connsTotal, 1) 69 70 return dConn 71 } 72 73 // CloseConn closed the connection 74 func (g *Gateway) CloseConn(connID uint64) { 75 g.connsMtx.Lock() 76 c := g.conns[connID] 77 delete(g.conns, connID) 78 g.connsMtx.Unlock() 79 if c == nil { 80 return 81 } 82 g.delegate.OnClose(c) 83 atomic.AddInt32(&g.connsTotal, -1) 84 } 85 86 // RPC emulates sending an RPC command to the connection. It opens a non-persistent connection if connID 87 // does not exist 88 func (g *Gateway) RPC(connID uint64, streamID int64, data []byte) error { 89 g.connsMtx.RLock() 90 conn := g.conns[connID] 91 g.connsMtx.RUnlock() 92 if conn == nil { 93 return errors.ErrConnectionNotExists 94 } 95 96 go g.delegate.OnMessage(conn, streamID, data) 97 98 return nil 99 } 100 101 // REST emulates a Http REST request. 102 func (g *Gateway) REST( 103 connID uint64, method, path string, 104 body []byte, 105 kvs ...*rony.KeyValue, 106 ) (respBody []byte, respHdr map[string]string) { 107 conn := g.openConn(connID, false) 108 conn.onMessage = func(connID uint64, streamID int64, data []byte, hdr map[string]string) { 109 respHdr = hdr 110 respBody = data 111 } 112 conn.method = method 113 conn.path = path 114 conn.body = body 115 for _, kv := range kvs { 116 conn.kv[kv.Key] = kv.Key 117 } 118 defer g.CloseConn(connID) 119 120 g.delegate.OnMessage(conn, 0, nil) 121 122 return 123 } 124 125 func (g *Gateway) Start() { 126 // Do nothing 127 } 128 129 func (g *Gateway) Run() { 130 // Do nothing 131 } 132 133 func (g *Gateway) Shutdown() { 134 // Do nothing 135 } 136 137 func (g *Gateway) GetConn(connID uint64) rony.Conn { 138 g.connsMtx.RLock() 139 conn := g.conns[connID] 140 g.connsMtx.RUnlock() 141 if conn == nil { 142 return nil 143 } 144 145 return conn 146 } 147 148 func (g *Gateway) Addr() []string { 149 return []string{"TEST"} 150 } 151 152 func (g *Gateway) Protocol() rony.GatewayProtocol { 153 return rony.Dummy 154 }