From 2b4ef142fc5bd07c796dbaca4dee04292145b8f4 Mon Sep 17 00:00:00 2001 From: Ryan Date: Sat, 20 Jan 2024 14:39:38 -0600 Subject: [PATCH 1/4] feat(rpc): readiness check --- nodebuilder/node/admin.go | 4 ++++ nodebuilder/node/node.go | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/nodebuilder/node/admin.go b/nodebuilder/node/admin.go index 8063835f1d..9e53026d56 100644 --- a/nodebuilder/node/admin.go +++ b/nodebuilder/node/admin.go @@ -38,6 +38,10 @@ func (m *module) Info(context.Context) (Info, error) { }, nil } +func (m *module) Ready(context.Context) (bool, error) { + return true, nil +} + func (m *module) LogLevelSet(_ context.Context, name, level string) error { return logging.SetLogLevel(name, level) } diff --git a/nodebuilder/node/node.go b/nodebuilder/node/node.go index 18ce93615b..1aff2a29db 100644 --- a/nodebuilder/node/node.go +++ b/nodebuilder/node/node.go @@ -14,6 +14,9 @@ type Module interface { // Info returns administrative information about the node. Info(context.Context) (Info, error) + // Ready returns true once the node's RPC is ready to accept requests. + Ready(context.Context) (bool, error) + // LogLevelSet sets the given component log level to the given level. LogLevelSet(ctx context.Context, name, level string) error @@ -28,6 +31,7 @@ var _ Module = (*API)(nil) type API struct { Internal struct { Info func(context.Context) (Info, error) `perm:"admin"` + Ready func(context.Context) (bool, error) `perm:"public"` LogLevelSet func(ctx context.Context, name, level string) error `perm:"admin"` AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"admin"` AuthNew func(ctx context.Context, perms []auth.Permission) (string, error) `perm:"admin"` @@ -38,6 +42,10 @@ func (api *API) Info(ctx context.Context) (Info, error) { return api.Internal.Info(ctx) } +func (api *API) Ready(ctx context.Context) (bool, error) { + return api.Internal.Ready(ctx) +} + func (api *API) LogLevelSet(ctx context.Context, name, level string) error { return api.Internal.LogLevelSet(ctx, name, level) } From 1ac19fddbc4cc7d159f75afd630d4572acb70e97 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 22 Jan 2024 09:55:32 -0600 Subject: [PATCH 2/4] adding test and changing perms to read --- nodebuilder/node/node.go | 2 +- nodebuilder/tests/api_test.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/nodebuilder/node/node.go b/nodebuilder/node/node.go index 1aff2a29db..b2bc7dac31 100644 --- a/nodebuilder/node/node.go +++ b/nodebuilder/node/node.go @@ -31,7 +31,7 @@ var _ Module = (*API)(nil) type API struct { Internal struct { Info func(context.Context) (Info, error) `perm:"admin"` - Ready func(context.Context) (bool, error) `perm:"public"` + Ready func(context.Context) (bool, error) `perm:"read"` LogLevelSet func(ctx context.Context, name, level string) error `perm:"admin"` AuthVerify func(ctx context.Context, token string) ([]auth.Permission, error) `perm:"admin"` AuthNew func(ctx context.Context, perms []auth.Permission) (string, error) `perm:"admin"` diff --git a/nodebuilder/tests/api_test.go b/nodebuilder/tests/api_test.go index 2fd4b2d3da..4999d3d8b6 100644 --- a/nodebuilder/tests/api_test.go +++ b/nodebuilder/tests/api_test.go @@ -58,6 +58,10 @@ func TestNodeModule(t *testing.T) { require.NoError(t, err) require.Equal(t, info.APIVersion, node.APIVersion) + ready, err := client.Node.Ready(ctx) + require.NoError(t, err) + require.True(t, ready) + perms, err := client.Node.AuthVerify(ctx, jwt) require.NoError(t, err) require.Equal(t, perms, adminPerms) From e020725b184fe6d71e21033851db07c2dfc306f9 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 23 Jan 2024 11:18:44 -0600 Subject: [PATCH 3/4] starting rpc last --- nodebuilder/module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodebuilder/module.go b/nodebuilder/module.go index 26dc1d9e33..f9948b2011 100644 --- a/nodebuilder/module.go +++ b/nodebuilder/module.go @@ -50,7 +50,6 @@ func ConstructModule(tp node.Type, network p2p.Network, cfg *Config, store Store state.ConstructModule(tp, &cfg.State, &cfg.Core), modhead.ConstructModule[*header.ExtendedHeader](tp, &cfg.Header), share.ConstructModule(tp, &cfg.Share), - rpc.ConstructModule(tp, &cfg.RPC), gateway.ConstructModule(tp, &cfg.Gateway), core.ConstructModule(tp, &cfg.Core), das.ConstructModule(tp, &cfg.DASer), @@ -58,6 +57,7 @@ func ConstructModule(tp node.Type, network p2p.Network, cfg *Config, store Store blob.ConstructModule(), node.ConstructModule(tp), prune.ConstructModule(tp), + rpc.ConstructModule(tp, &cfg.RPC), ) return fx.Module( From 85021e9d31c4673f30d9bddbf21746a5674be698 Mon Sep 17 00:00:00 2001 From: Ryan Date: Mon, 29 Jan 2024 09:38:55 +0100 Subject: [PATCH 4/4] adding comment --- nodebuilder/node/admin.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nodebuilder/node/admin.go b/nodebuilder/node/admin.go index 9e53026d56..f71af66081 100644 --- a/nodebuilder/node/admin.go +++ b/nodebuilder/node/admin.go @@ -39,6 +39,10 @@ func (m *module) Info(context.Context) (Info, error) { } func (m *module) Ready(context.Context) (bool, error) { + // Because the node uses FX to provide the RPC last, all services' lifecycles have been started by + // the point this endpoint is available. It is not 100% guaranteed at this point that all services + // are fully ready, but it is very high probability and all endpoints are available at this point + // regardless. return true, nil }