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  }