client.go raw
1 // Package grpc provides a gRPC client for the relay group service.
2 package grpc
3
4 import (
5 "context"
6 "time"
7
8 "google.golang.org/grpc"
9 "google.golang.org/grpc/credentials/insecure"
10 "next.orly.dev/pkg/lol/log"
11
12 commonv1 "next.orly.dev/pkg/proto/orlysync/common/v1"
13 relaygroupv1 "next.orly.dev/pkg/proto/orlysync/relaygroup/v1"
14 )
15
16 // Client is a gRPC client for the relay group service.
17 type Client struct {
18 conn *grpc.ClientConn
19 client relaygroupv1.RelayGroupServiceClient
20 ready chan struct{}
21 }
22
23 // ClientConfig holds configuration for the gRPC client.
24 type ClientConfig struct {
25 ServerAddress string
26 ConnectTimeout time.Duration
27 }
28
29 // New creates a new gRPC relay group client.
30 func New(ctx context.Context, cfg *ClientConfig) (*Client, error) {
31 timeout := cfg.ConnectTimeout
32 if timeout == 0 {
33 timeout = 10 * time.Second
34 }
35
36 dialCtx, cancel := context.WithTimeout(ctx, timeout)
37 defer cancel()
38
39 conn, err := grpc.DialContext(dialCtx, cfg.ServerAddress,
40 grpc.WithTransportCredentials(insecure.NewCredentials()),
41 grpc.WithDefaultCallOptions(
42 grpc.MaxCallRecvMsgSize(16<<20), // 16MB
43 grpc.MaxCallSendMsgSize(16<<20), // 16MB
44 ),
45 )
46 if err != nil {
47 return nil, err
48 }
49
50 c := &Client{
51 conn: conn,
52 client: relaygroupv1.NewRelayGroupServiceClient(conn),
53 ready: make(chan struct{}),
54 }
55
56 go c.waitForReady(ctx)
57
58 return c, nil
59 }
60
61 func (c *Client) waitForReady(ctx context.Context) {
62 for {
63 select {
64 case <-ctx.Done():
65 return
66 default:
67 resp, err := c.client.Ready(ctx, &commonv1.Empty{})
68 if err == nil && resp.Ready {
69 close(c.ready)
70 log.I.F("gRPC relay group client connected and ready")
71 return
72 }
73 time.Sleep(100 * time.Millisecond)
74 }
75 }
76 }
77
78 // Close closes the gRPC connection.
79 func (c *Client) Close() error {
80 if c.conn != nil {
81 return c.conn.Close()
82 }
83 return nil
84 }
85
86 // Ready returns a channel that closes when the client is ready.
87 func (c *Client) Ready() <-chan struct{} {
88 return c.ready
89 }
90
91 // FindAuthoritativeConfig finds the authoritative relay group configuration.
92 func (c *Client) FindAuthoritativeConfig(ctx context.Context) (*relaygroupv1.RelayGroupConfigResponse, error) {
93 return c.client.FindAuthoritativeConfig(ctx, &commonv1.Empty{})
94 }
95
96 // GetRelays returns the list of relays from the authoritative config.
97 func (c *Client) GetRelays(ctx context.Context) ([]string, error) {
98 resp, err := c.client.GetRelays(ctx, &commonv1.Empty{})
99 if err != nil {
100 return nil, err
101 }
102 return resp.Relays, nil
103 }
104
105 // IsAuthorizedPublisher checks if a pubkey can publish relay group configs.
106 func (c *Client) IsAuthorizedPublisher(ctx context.Context, pubkey []byte) (bool, error) {
107 resp, err := c.client.IsAuthorizedPublisher(ctx, &relaygroupv1.AuthorizedPublisherRequest{
108 Pubkey: pubkey,
109 })
110 if err != nil {
111 return false, err
112 }
113 return resp.Authorized, nil
114 }
115
116 // GetAuthorizedPubkeys returns all authorized publisher pubkeys.
117 func (c *Client) GetAuthorizedPubkeys(ctx context.Context) ([][]byte, error) {
118 resp, err := c.client.GetAuthorizedPubkeys(ctx, &commonv1.Empty{})
119 if err != nil {
120 return nil, err
121 }
122 return resp.Pubkeys, nil
123 }
124
125 // ValidateRelayGroupEvent validates a relay group configuration event.
126 func (c *Client) ValidateRelayGroupEvent(ctx context.Context, event *commonv1.Event) (bool, string, error) {
127 resp, err := c.client.ValidateRelayGroupEvent(ctx, &relaygroupv1.ValidateEventRequest{
128 Event: event,
129 })
130 if err != nil {
131 return false, "", err
132 }
133 return resp.Valid, resp.Error, nil
134 }
135
136 // HandleRelayGroupEvent processes a relay group event and triggers peer updates.
137 func (c *Client) HandleRelayGroupEvent(ctx context.Context, event *commonv1.Event) error {
138 _, err := c.client.HandleRelayGroupEvent(ctx, &relaygroupv1.HandleEventRequest{
139 Event: event,
140 })
141 return err
142 }
143