Skip to content

Commit

Permalink
[ADDED] Cluster role in serverz endpoint
Browse files Browse the repository at this point in the history
A new field indicates the RAFT role of the node when running in
clustered mode. The possible values are `Leader`, `Follower` or
`Candidate`.

Resolves #792

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
  • Loading branch information
kozlovic committed Apr 16, 2019
1 parent 8c0d26c commit 4f6c6a1
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,28 @@ various general statistics.
}
```

In clustering mode, there is an additional field that indicates the RAFT role of the given node.
Here is an example:
```
{
"cluster_id": "test-cluster",
"server_id": "5bJdRWJW4dSxrfjKSUOgOH",
"version": "0.12.2",
"go": "go1.12.1",
"state": "CLUSTERED",
"cluster_role": "Leader",
"now": "2019-04-15T19:25:39.350491-06:00",
"start_time": "2019-04-15T19:25:30.75881-06:00",
"uptime": "8s",
"clients": 0,
"subscriptions": 0,
"channels": 0,
"total_msgs": 0,
"total_bytes": 0
}
```
The possible values are: `Leader`, `Follower` or `Candidate`.

#### /storez

The endpoint [http://localhost:8222/streaming/storez](http://localhost:8222/streaming/storez) reports
Expand Down
6 changes: 6 additions & 0 deletions server/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Serverz struct {
Version string `json:"version"`
GoVersion string `json:"go"`
State string `json:"state"`
ClusterRole string `json:"cluster_role,omitempty"`
Now time.Time `json:"now"`
Start time.Time `json:"start_time"`
Uptime string `json:"uptime"`
Expand Down Expand Up @@ -184,8 +185,12 @@ func (s *StanServer) handleServerz(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("Error getting information about channels state: %v", err), http.StatusInternalServerError)
return
}
var clusterRole string
s.mu.RLock()
state := s.state
if s.raft != nil {
clusterRole = s.raft.State().String()
}
s.mu.RUnlock()
s.monMu.RLock()
numSubs := s.numSubs
Expand Down Expand Up @@ -214,6 +219,7 @@ func (s *StanServer) handleServerz(w http.ResponseWriter, r *http.Request) {
Version: VERSION,
GoVersion: runtime.Version(),
State: state.String(),
ClusterRole: clusterRole,
Now: now,
Start: s.startTime,
Uptime: myUptime(now.Sub(s.startTime)),
Expand Down
57 changes: 57 additions & 0 deletions server/monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"testing"
"time"

"github.com/hashicorp/raft"
natsd "github.com/nats-io/gnatsd/server"
natsdTest "github.com/nats-io/gnatsd/test"
"github.com/nats-io/go-nats"
Expand Down Expand Up @@ -1159,3 +1160,59 @@ func TestMonitorDurableSubs(t *testing.T) {
}
}
}

func TestMonitorClusterRole(t *testing.T) {
nOpts := defaultMonitorOptions
for _, test := range []struct {
name string
expectedRole string
n1Opts *natsd.Options
n2Opts *natsd.Options
}{
{
"leader",
raft.Leader.String(),
&nOpts,
nil,
},
{
"follower",
raft.Follower.String(),
nil,
&nOpts,
},
} {
t.Run(test.name, func(t *testing.T) {
resetPreviousHTTPConnections()

cleanupDatastore(t)
defer cleanupDatastore(t)
cleanupRaftLog(t)
defer cleanupRaftLog(t)

// For this test, use a central NATS server.
ns := natsdTest.RunDefaultServer()
defer ns.Shutdown()

s1sOpts := getTestDefaultOptsForClustering("a", true)
s1 := runServerWithOpts(t, s1sOpts, test.n1Opts)
defer s1.Shutdown()

s2sOpts := getTestDefaultOptsForClustering("b", false)
s2 := runServerWithOpts(t, s2sOpts, test.n2Opts)
defer s2.Shutdown()

getLeader(t, 10*time.Second, s1, s2)

resp, body := getBody(t, ServerPath, expectedJSON)
resp.Body.Close()
sz := Serverz{}
if err := json.Unmarshal(body, &sz); err != nil {
t.Fatalf("Got an error unmarshalling the body: %v", err)
}
if sz.ClusterRole != test.expectedRole {
t.Fatalf("Expected role to be %v, gt %v", test.expectedRole, sz.ClusterRole)
}
})
}
}

0 comments on commit 4f6c6a1

Please sign in to comment.