4
4
package node
5
5
6
6
import (
7
+ "connectrpc.com/grpcreflect"
7
8
"context"
8
9
"crypto"
9
10
"crypto/tls"
10
11
"encoding/json"
11
12
"errors"
12
13
"fmt"
14
+ healthhandler "github.com/ava-labs/avalanchego/api/health/connecthandler"
15
+ infohandler "github.com/ava-labs/avalanchego/api/info/connecthandler"
16
+ "github.com/ava-labs/avalanchego/proto/pb/health/v1/healthv1connect"
17
+ "github.com/ava-labs/avalanchego/proto/pb/info/v1/infov1connect"
13
18
"io"
14
19
"io/fs"
15
20
"net"
@@ -21,7 +26,6 @@ import (
21
26
"sync"
22
27
"time"
23
28
24
- "connectrpc.com/grpcreflect"
25
29
"github.com/prometheus/client_golang/prometheus"
26
30
"github.com/prometheus/client_golang/prometheus/collectors"
27
31
"github.com/prometheus/client_golang/prometheus/promhttp"
@@ -48,7 +52,6 @@ import (
48
52
"github.com/ava-labs/avalanchego/network/dialer"
49
53
"github.com/ava-labs/avalanchego/network/peer"
50
54
"github.com/ava-labs/avalanchego/network/throttling"
51
- "github.com/ava-labs/avalanchego/proto/pb/info/v1/infov1connect"
52
55
"github.com/ava-labs/avalanchego/snow"
53
56
"github.com/ava-labs/avalanchego/snow/networking/benchlist"
54
57
"github.com/ava-labs/avalanchego/snow/networking/router"
@@ -80,7 +83,6 @@ import (
80
83
"github.com/ava-labs/avalanchego/vms/registry"
81
84
"github.com/ava-labs/avalanchego/vms/rpcchainvm/runtime"
82
85
83
- connecthandler "github.com/ava-labs/avalanchego/api/info/connect_handler"
84
86
databasefactory "github.com/ava-labs/avalanchego/database/factory"
85
87
avmconfig "github.com/ava-labs/avalanchego/vms/avm/config"
86
88
platformconfig "github.com/ava-labs/avalanchego/vms/platformvm/config"
@@ -266,6 +268,26 @@ func New(
266
268
return nil , fmt .Errorf ("couldn't initialize indexer: %w" , err )
267
269
}
268
270
271
+ // mount InfoService onto the shared gRPC mux
272
+ infoPattern , infoHandler := infov1connect .NewInfoServiceHandler (
273
+ infohandler .NewConnectInfoService (n .info ),
274
+ )
275
+ n .grpcMux .Handle (infoPattern , infoHandler )
276
+
277
+ // mount HealthService onto the same mux
278
+ healthPattern , healthHandler := healthv1connect .NewHealthServiceHandler (
279
+ healthhandler .NewConnectHealthService (n .health ),
280
+ )
281
+ n .grpcMux .Handle (healthPattern , healthHandler )
282
+
283
+ // register reflection for both services, once
284
+ reflector := grpcreflect .NewStaticReflector (
285
+ infov1connect .InfoServiceName ,
286
+ healthv1connect .HealthServiceName ,
287
+ )
288
+ reflectPattern , reflectHandler := grpcreflect .NewHandlerV1 (reflector )
289
+ n .grpcMux .Handle (reflectPattern , reflectHandler )
290
+
269
291
n .health .Start (context .TODO (), n .Config .HealthCheckFreq )
270
292
n .initProfiler ()
271
293
@@ -310,6 +332,9 @@ type Node struct {
310
332
// Monitors node health and runs health checks
311
333
health health.Health
312
334
335
+ // Info service instance
336
+ info * info.Info
337
+
313
338
// Build and parse messages, for both network layer and chain manager
314
339
msgCreator message.Creator
315
340
@@ -352,6 +377,9 @@ type Node struct {
352
377
// Handles HTTP API calls
353
378
APIServer server.Server
354
379
380
+ // Shared HTTP/2 mux for ConnectRPC services
381
+ grpcMux * http.ServeMux
382
+
355
383
// This node's configuration
356
384
Config * node.Config
357
385
@@ -1010,6 +1038,10 @@ func (n *Node) initAPIServer() error {
1010
1038
n .Config .HTTPConfig .HTTPConfig ,
1011
1039
n .Config .HTTPAllowedHosts ,
1012
1040
)
1041
+
1042
+ // Set up a shared HTTP/2 mux for all ConnectRPC services
1043
+ n .grpcMux = http .NewServeMux ()
1044
+ n .APIServer .AddHTTP2Handler (n .grpcMux )
1013
1045
return err
1014
1046
}
1015
1047
@@ -1353,7 +1385,7 @@ func (n *Node) initInfoAPI() error {
1353
1385
return fmt .Errorf ("problem creating proof of possession: %w" , err )
1354
1386
}
1355
1387
1356
- service , info , err := info .NewService (
1388
+ service , infoInst , err := info .NewService (
1357
1389
info.Parameters {
1358
1390
Version : version .CurrentApp ,
1359
1391
NodeID : n .ID ,
@@ -1376,29 +1408,12 @@ func (n *Node) initInfoAPI() error {
1376
1408
if err != nil {
1377
1409
return err
1378
1410
}
1379
-
1380
- // Register the InfoService handler and gRPC reflection handler
1381
- infoPattern , infoHandler := infov1connect .NewInfoServiceHandler (connecthandler .NewConnectInfoService (info ))
1382
-
1383
- // Register the gRPC reflection handler for InfoService
1384
- refPattern , refHandler := grpcreflect .NewHandlerV1 (
1385
- grpcreflect .NewStaticReflector (infov1connect .InfoServiceName ),
1386
- )
1387
-
1388
- // Create a new ServeMux to handle the InfoService and reflection handlers
1389
- mux := http .NewServeMux ()
1390
- mux .Handle (infoPattern , infoHandler )
1391
- mux .Handle (refPattern , refHandler )
1392
-
1393
- if ! n .APIServer .AddHeaderRoute ("info" , mux ) {
1394
- // TODO do not panic
1395
- panic ("could not add info route" )
1396
- }
1411
+ n .info = infoInst
1397
1412
1398
1413
return n .APIServer .AddRoute (
1399
1414
service ,
1400
1415
"info" ,
1401
- "info " ,
1416
+ "" ,
1402
1417
)
1403
1418
}
1404
1419
@@ -1413,10 +1428,13 @@ func (n *Node) initHealthAPI() error {
1413
1428
return err
1414
1429
}
1415
1430
1416
- n .health , err = health .New (n .Log , healthReg )
1431
+ // Create the health service
1432
+ healthService , err := health .New (n .Log , healthReg )
1417
1433
if err != nil {
1418
1434
return err
1419
1435
}
1436
+ // Store the health service in the node's health field
1437
+ n .health = healthService
1420
1438
1421
1439
if ! n .Config .HealthAPIEnabled {
1422
1440
n .Log .Info ("skipping health API initialization because it has been disabled" )
0 commit comments