Skip to content

Commit

Permalink
Network: Support simple liveness check via http on gossip server port. (
Browse files Browse the repository at this point in the history
  • Loading branch information
gmalouf authored Mar 7, 2024
1 parent e7ee984 commit 86ae7e6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
5 changes: 5 additions & 0 deletions node/follower_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ func MakeFollower(log logging.Logger, rootDir string, cfg config.Local, phoneboo
}

node.ledger.RegisterBlockListeners(blockListeners)

if cfg.IsGossipServer() {
rpcs.MakeHealthService(node.net)
}

node.blockService = rpcs.MakeBlockService(node.log, cfg, node.ledger, p2pNode, node.genesisID)
node.catchupBlockAuth = blockAuthenticatorImpl{Ledger: node.ledger, AsyncVoteVerifier: agreement.MakeAsyncVoteVerifier(node.lowPriorityCryptoVerificationPool)}
node.catchupService = catchup.MakeService(node.log, node.config, p2pNode, node.ledger, node.catchupBlockAuth, make(chan catchup.PendingUnmatchedCertificate), node.lowPriorityCryptoVerificationPool)
Expand Down
5 changes: 5 additions & 0 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ func MakeFull(log logging.Logger, rootDir string, cfg config.Local, phonebookAdd
return nil, err
}

// The health service registers itself with the network
if cfg.IsGossipServer() {
rpcs.MakeHealthService(node.net)
}

node.blockService = rpcs.MakeBlockService(node.log, cfg, node.ledger, p2pNode, node.genesisID)
node.ledgerService = rpcs.MakeLedgerService(cfg, node.ledger, p2pNode, node.genesisID)
rpcs.RegisterTxService(node.transactionPool, p2pNode, node.genesisID, cfg.TxPoolSize, cfg.TxSyncServeResponseSize)
Expand Down
41 changes: 41 additions & 0 deletions rpcs/healthService.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (C) 2019-2024 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package rpcs

import (
"github.com/algorand/go-algorand/network"
"net/http"
)

// HealthServiceStatusPath is the path to register HealthService as a handler for when using gorilla/mux
const HealthServiceStatusPath = "/status"

// HealthService is a service that provides health information endpoints for the node
type HealthService struct{}

// MakeHealthService creates a new HealthService and registers it with the provided network if enabled
func MakeHealthService(net network.GossipNode) HealthService {
service := HealthService{}

net.RegisterHTTPHandler(HealthServiceStatusPath, service)

return service
}

func (h HealthService) ServeHTTP(writer http.ResponseWriter, _ *http.Request) {
writer.WriteHeader(http.StatusOK)
}
52 changes: 52 additions & 0 deletions rpcs/healthService_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (C) 2019-2024 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.

package rpcs

import (
"github.com/algorand/go-algorand/network"
"github.com/algorand/go-algorand/test/partitiontest"
"github.com/stretchr/testify/require"
"io"
"net/http"
"path"
"testing"
)

func TestHealthService_ServeHTTP(t *testing.T) {
partitiontest.PartitionTest(t)

nodeA := &basicRPCNode{}
nodeA.start()
defer nodeA.stop()

_ = MakeHealthService(nodeA)

parsedURL, err := network.ParseHostOrURL(nodeA.rootURL())
require.NoError(t, err)

client := http.Client{}

parsedURL.Path = path.Join(parsedURL.Path, HealthServiceStatusPath)

response, err := client.Get(parsedURL.String())
require.NoError(t, err)

require.Equal(t, http.StatusOK, response.StatusCode)
bodyData, err := io.ReadAll(response.Body)
require.NoError(t, err)
require.Empty(t, bodyData)
}

0 comments on commit 86ae7e6

Please sign in to comment.