diff --git a/server/monitor.go b/server/monitor.go index b71ea35d..992b0f8a 100644 --- a/server/monitor.go +++ b/server/monitor.go @@ -47,35 +47,6 @@ type ConnInfo struct { Subs []string `json:"subscriptions_list,omitempty"` } -// Helper types to sort by ConnInfo values -type Pair struct { - Key int - Val int -} - -type Pairs []Pair - -func (d Pairs) Len() int { - return len(d) -} -func (d Pairs) Swap(i, j int) { - d[i], d[j] = d[j], d[i] -} -func (d Pairs) Less(i, j int) bool { - return d[i].Val < d[j].Val -} - -type SortOpt string - -const ( - ByCid SortOpt = "cid" - BySubs = "subs" - ByOutMsgs = "msgs_to" - ByInMsgs = "msgs_from" - ByOutBytes = "bytes_to" - ByInBytes = "bytes_from" -) - const DefaultConnListSize = 1024 // HandleConnz process HTTP requests for connection information. @@ -96,34 +67,27 @@ func (s *Server) HandleConnz(w http.ResponseWriter, r *http.Request) { s.mu.Lock() c.NumConns = len(s.clients) - // Filter key value pairs used for sorting in another structure - pairs := make(Pairs, c.NumConns) - + // Copy the keys to sort by them + pairs := make([]Pair, c.NumConns) i := 0 - for index, client := range s.clients { - switch sortOpt { - case ByCid: - pairs[i] = Pair{Key: int(index), Val: int(client.cid)} - case BySubs: - pairs[i] = Pair{Key: int(index), Val: int(client.subs.Count())} - case ByOutMsgs: - pairs[i] = Pair{Key: int(index), Val: int(client.outMsgs)} - case ByInMsgs: - pairs[i] = Pair{Key: int(index), Val: int(client.inMsgs)} - case ByOutBytes: - pairs[i] = Pair{Key: int(index), Val: int(client.outBytes)} - case ByInBytes: - pairs[i] = Pair{Key: int(index), Val: int(client.inBytes)} - default: - // Just get the unsorted keys - pairs[i] = Pair{Key: int(index)} - } + for k, v := range s.clients { + pairs[i] = Pair{Key: k, Val: v} i++ } - // Return in descending order - if len(pairs) > 0 { - sort.Sort(sort.Reverse(pairs)) + switch sortOpt { + case byCid: + sort.Sort(ByCid(pairs)) + case bySubs: + sort.Sort(sort.Reverse(BySubs(pairs))) + case byOutMsgs: + sort.Sort(sort.Reverse(ByOutMsgs(pairs))) + case byInMsgs: + sort.Sort(sort.Reverse(ByInMsgs(pairs))) + case byOutBytes: + sort.Sort(sort.Reverse(ByOutBytes(pairs))) + case byInBytes: + sort.Sort(sort.Reverse(ByInBytes(pairs))) } i = 0 diff --git a/server/monitor_sort_opts.go b/server/monitor_sort_opts.go new file mode 100644 index 00000000..46adcfdc --- /dev/null +++ b/server/monitor_sort_opts.go @@ -0,0 +1,92 @@ +// Copyright 2013-2015 Apcera Inc. All rights reserved. + +package server + +// Helper types to sort by ConnInfo values +type SortOpt string + +const ( + byCid SortOpt = "cid" + bySubs = "subs" + byOutMsgs = "msgs_to" + byInMsgs = "msgs_from" + byOutBytes = "bytes_to" + byInBytes = "bytes_from" +) + +type Pair struct { + Key uint64 + Val *client +} + +type ByCid []Pair + +func (d ByCid) Len() int { + return len(d) +} +func (d ByCid) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d ByCid) Less(i, j int) bool { + return d[uint64(i)].Val.cid < d[uint64(j)].Val.cid +} + +type BySubs []Pair + +func (d BySubs) Len() int { + return len(d) +} +func (d BySubs) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d BySubs) Less(i, j int) bool { + return d[uint64(i)].Val.subs.Count() < d[uint64(j)].Val.subs.Count() +} + +type ByOutMsgs []Pair + +func (d ByOutMsgs) Len() int { + return len(d) +} +func (d ByOutMsgs) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d ByOutMsgs) Less(i, j int) bool { + return d[uint64(i)].Val.outMsgs < d[uint64(j)].Val.outMsgs +} + +type ByInMsgs []Pair + +func (d ByInMsgs) Len() int { + return len(d) +} +func (d ByInMsgs) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d ByInMsgs) Less(i, j int) bool { + return d[uint64(i)].Val.inMsgs < d[uint64(j)].Val.inMsgs +} + +type ByOutBytes []Pair + +func (d ByOutBytes) Len() int { + return len(d) +} +func (d ByOutBytes) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d ByOutBytes) Less(i, j int) bool { + return d[uint64(i)].Val.outBytes < d[uint64(j)].Val.outBytes +} + +type ByInBytes []Pair + +func (d ByInBytes) Len() int { + return len(d) +} +func (d ByInBytes) Swap(i, j int) { + d[uint64(i)], d[uint64(j)] = d[uint64(j)], d[uint64(i)] +} +func (d ByInBytes) Less(i, j int) bool { + return d[uint64(i)].Val.inBytes < d[uint64(j)].Val.inBytes +} diff --git a/server/monitor_test.go b/server/monitor_test.go index d8fd0251..e95b6c7d 100644 --- a/server/monitor_test.go +++ b/server/monitor_test.go @@ -354,10 +354,10 @@ func TestConnzSortedByCid(t *testing.T) { t.Fatalf("Got an error unmarshalling the body: %v\n", err) } - if c.Conns[0].Cid < c.Conns[1].Cid || - c.Conns[1].Cid < c.Conns[2].Cid || - c.Conns[2].Cid < c.Conns[3].Cid { - t.Fatalf("Expected conns sorted in descending order by cid, got %v < %v\n", c.Conns[0].Cid, c.Conns[3].Cid) + if c.Conns[0].Cid > c.Conns[1].Cid || + c.Conns[1].Cid > c.Conns[2].Cid || + c.Conns[2].Cid > c.Conns[3].Cid { + t.Fatalf("Expected conns sorted in ascending order by cid, got %v < %v\n", c.Conns[0].Cid, c.Conns[3].Cid) } } @@ -400,7 +400,7 @@ func TestConnzSortedByBytesAndMsgs(t *testing.T) { if c.Conns[0].OutBytes < c.Conns[1].OutBytes || c.Conns[0].OutBytes < c.Conns[2].OutBytes || c.Conns[0].OutBytes < c.Conns[3].OutBytes { - t.Fatalf("Expected conns sorted in descending order by bytes from, got %v < one of [%v, %v, %v]\n", + t.Fatalf("Expected conns sorted in descending order by bytes to, got %v < one of [%v, %v, %v]\n", c.Conns[0].OutBytes, c.Conns[1].OutBytes, c.Conns[2].OutBytes, c.Conns[3].OutBytes) }