@@ -11,14 +11,14 @@ import (
1111 "time"
1212
1313 "github.com/golang/protobuf/proto"
14- "github.com/unit-io/unitdb-go/store"
15- "github.com/unit-io/unitdb-go/utp"
14+ "github.com/unit-io/unitdb-go/internal/ store"
15+ "github.com/unit-io/unitdb-go/internal/ utp"
1616 "github.com/unit-io/unitdb/server/common"
1717 pbx "github.com/unit-io/unitdb/server/proto"
1818 "google.golang.org/grpc"
1919
2020 // Database store
21- _ "github.com/unit-io/unitdb-go/db/unitdb"
21+ _ "github.com/unit-io/unitdb-go/internal/ db/unitdb"
2222)
2323
2424type Client interface {
@@ -39,23 +39,24 @@ type Client interface {
3939 Publish (topic string , payload []byte , pubOpts ... PubOptions ) Result
4040 // Subscribe starts a new subscription. Provide a MessageHandler to be executed when
4141 // a message is published on the topic provided, or nil for the default handler.
42+ // Relay sends a relay request to server. Provide a MessageHandler to be executed when
43+ // a message is published on the topic provided, or nil for the default handler.
44+ Relay (topic string , relOpts ... RelOptions ) Result
4245 Subscribe (topic string , subOpts ... SubOptions ) Result
4346 // Unsubscribe will end the subscription from each of the topics provided.
4447 // Messages published to those topics from other clients will no longer be
4548 // received.
4649 Unsubscribe (topics ... string ) Result
4750}
4851type client struct {
49- mu sync.Mutex // mutex for the connection
5052 opts * options
5153 context context.Context // context for the client
5254 cancel context.CancelFunc // cancellation function
5355 messageIds // local identifier of messages
5456 connID int32 // The unique id of the connection.
55- sessID uint32
56- epoch uint32 // The session ID of the connection.
57- conn net.Conn // the network connection
58- stream grpc.Stream
57+ sessID uint32
58+ epoch uint32 // The session ID of the connection.
59+ conn net.Conn // the network connection
5960 send chan * MessageAndResult
6061 recv chan utp.Message
6162 pub chan * utp.Publish
@@ -180,18 +181,19 @@ func (c *client) ConnectContext(ctx context.Context) error {
180181 c .updateLastTouched ()
181182 go c .keepalive (ctx )
182183 }
184+ // c.closeW.Add(3)
183185 go c .readLoop (ctx ) // process incoming messages
184186 go c .writeLoop (ctx ) // send messages to servers
185187 go c .dispatcher (ctx ) // dispatch messages to client
186188
187- // Take care of any messages in the store
188- var sessKey uint32
189- if c .opts .sessionKey != 0 {
190- sessKey = c .opts .sessionKey
191- } else {
192- sessKey = c .epoch
193- }
194-
189+ // Take care of any messages in the store
190+ var sessKey uint32
191+ if c .opts .sessionKey != 0 {
192+ sessKey = c .opts .sessionKey
193+ } else {
194+ sessKey = c .epoch
195+ }
196+
195197 sessID := c .connID
196198 if rawSess , err := store .Session .Get (uint64 (sessKey )); err == nil {
197199 sessID := binary .LittleEndian .Uint32 (rawSess [:4 ])
@@ -275,7 +277,7 @@ func (c *client) DisconnectContext(ctx context.Context) error {
275277 // Disconnect() called but not connected
276278 return nil
277279 }
278-
280+
279281 defer c .close ()
280282 m := & utp.Disconnect {}
281283 r := & DisconnectResult {result : result {complete : make (chan struct {})}}
@@ -354,6 +356,42 @@ func (c *client) Publish(topic string, payload []byte, pubOpts ...PubOptions) Re
354356 return r
355357}
356358
359+ // Relay send a new relay request. Provide a MessageHandler to be executed when
360+ // a message is published on the topic provided.
361+ func (c * client ) Relay (topic string , relOpts ... RelOptions ) Result {
362+ r := & RelayResult {result : result {complete : make (chan struct {})}}
363+ if err := c .ok (); err != nil {
364+ r .setError (errors .New ("error not connected" ))
365+ return r
366+ }
367+ opts := new (relOptions )
368+ for _ , opt := range relOpts {
369+ opt .set (opts )
370+ }
371+
372+ rel := & utp.Relay {}
373+ rel .RelayRequests = append (rel .RelayRequests , & utp.RelayRequest {Topic : topic , Last : opts .last })
374+
375+ if rel .MessageID == 0 {
376+ mID := c .nextID (r )
377+ rel .MessageID = c .outboundID (mID )
378+ }
379+ relayWaitTimeout := c .opts .writeTimeout
380+ if relayWaitTimeout == 0 {
381+ relayWaitTimeout = time .Second * 30
382+ }
383+ // persist outbound
384+ c .storeOutbound (rel )
385+ select {
386+ case c .send <- & MessageAndResult {m : rel , r : r }:
387+ case <- time .After (relayWaitTimeout ):
388+ r .setError (errors .New ("relay request timeout error occurred" ))
389+ return r
390+ }
391+
392+ return r
393+ }
394+
357395// Subscribe starts a new subscription. Provide a MessageHandler to be executed when
358396// a message is published on the topic provided.
359397func (c * client ) Subscribe (topic string , subOpts ... SubOptions ) Result {
@@ -368,10 +406,7 @@ func (c *client) Subscribe(topic string, subOpts ...SubOptions) Result {
368406 }
369407
370408 sub := & utp.Subscribe {}
371- sub .Subscriptions = append (sub .Subscriptions , & utp.Subscription {DeliveryMode : opts .deliveryMode , Delay : opts .delay , Topic : topic , Last : opts .last })
372-
373- if opts .callback != nil {
374- }
409+ sub .Subscriptions = append (sub .Subscriptions , & utp.Subscription {DeliveryMode : opts .deliveryMode , Delay : opts .delay , Topic : topic })
375410
376411 if sub .MessageID == 0 {
377412 mID := c .nextID (r )
@@ -435,20 +470,35 @@ func (c *client) resume(prefix uint32, subscription bool) {
435470 // isKeyOutbound
436471 if (k & (1 << 4 )) == 0 {
437472 switch msg .Type () {
473+ case utp .RELAY :
474+ p := msg .(* utp.Relay )
475+ r := & RelayResult {result : result {complete : make (chan struct {})}}
476+ r .messageID = msg .Info ().MessageID
477+ c .messageIds .resumeID (MID (r .messageID ))
478+ // var topics []RelayRequest
479+ // for _, req := range p.RelayRequests {
480+ // var t RelayRequest
481+ // t.Topic = req.Topic
482+ // t.Last = req.Last
483+ // topics = append(topics, t)
484+ // }
485+ r .reqs = p .RelayRequests
486+ c .send <- & MessageAndResult {m : msg , r : r }
438487 case utp .SUBSCRIBE :
439488 if subscription {
440489 p := msg .(* utp.Subscribe )
441490 r := & SubscribeResult {result : result {complete : make (chan struct {})}}
442491 r .messageID = msg .Info ().MessageID
443492 c .messageIds .resumeID (MID (r .messageID ))
444- var topics []Subscription
445- for _ , sub := range p .Subscriptions {
446- var t Subscription
447- t .Topic = sub .Topic
448- t .DeliveryMode = sub .DeliveryMode
449- topics = append (topics , t )
450- }
451- r .subs = append (r .subs , topics ... )
493+ // var topics []Subscription
494+ // for _, sub := range p.Subscriptions {
495+ // var t Subscription
496+ // t.Topic = sub.Topic
497+ // t.DeliveryMode = sub.DeliveryMode
498+ // topics = append(topics, t)
499+ // }
500+ // r.subs = append(r.subs, topics...)
501+ r .subs = p .Subscriptions
452502 c .send <- & MessageAndResult {m : msg , r : r }
453503 }
454504 case utp .UNSUBSCRIBE :
0 commit comments