From 9954bdd340735ea5f7576b781e3889523d0ea106 Mon Sep 17 00:00:00 2001 From: Charlie Andrews Date: Mon, 9 Oct 2017 17:07:39 -0500 Subject: [PATCH] Add /recalculatecaches endpoint for triggering the recalculating of caches on demand --- handler.go | 6 ++++++ handler_test.go | 16 ++++++++++++++++ holder.go | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/handler.go b/handler.go index d8463862a..b90d6be83 100644 --- a/handler.go +++ b/handler.go @@ -134,6 +134,7 @@ func NewRouter(handler *Handler) *mux.Router { router.HandleFunc("/slices/max", handler.handleGetSliceMax).Methods("GET") router.HandleFunc("/status", handler.handleGetStatus).Methods("GET") router.HandleFunc("/version", handler.handleGetVersion).Methods("GET") + router.HandleFunc("/recalculatecaches", handler.handleRecalculateCaches).Methods("POST") // TODO: Apply MethodNotAllowed statuses to all endpoints. // Ideally this would be automatic, as described in this (wontfix) ticket: @@ -1962,6 +1963,11 @@ func (h *Handler) InputJSONDataParser(req map[string]interface{}, index *Index, return setBits, nil } +func (h *Handler) handleRecalculateCaches(w http.ResponseWriter, r *http.Request) { + h.Holder.RecalculateCaches() + w.WriteHeader(http.StatusNoContent) +} + // GetTimeStamp retrieves unix timestamp from Input data. func GetTimeStamp(data map[string]interface{}, timeField string) (int64, error) { tmstamp, ok := data[timeField] diff --git a/handler_test.go b/handler_test.go index 6e8ebab88..a57c0da50 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1782,3 +1782,19 @@ func MustReadAll(r io.Reader) []byte { } return buf } + +func TestHandler_RecalculateCaches(t *testing.T) { + hldr := test.MustOpenHolder() + defer hldr.Close() + + h := test.NewHandler() + h.Holder = hldr.Holder + h.Cluster = test.NewCluster(1) + + w := httptest.NewRecorder() + h.ServeHTTP(w, test.MustNewHTTPRequest("POST", "/recalculatecaches", nil)) + if w.Code != http.StatusNoContent { + t.Fatalf("unexpected status code: %d", w.Code) + } + +} diff --git a/holder.go b/holder.go index 0cf5f6901..31aee1c21 100644 --- a/holder.go +++ b/holder.go @@ -361,6 +361,28 @@ func (h *Holder) flushCaches() { } } +// RecalculateCaches calls RecalculateCache on every fragment of every frame of +// every index. This is probably not practical to call in real-world workloads, +// but makes writing integration tests much eaiser, since one doesn't have to +// wait 10 seconds after setting bits to get expected response. +func (h *Holder) RecalculateCaches() { + for _, index := range h.Indexes() { + for _, frame := range index.Frames() { + for _, view := range frame.Views() { + for _, fragment := range view.Fragments() { + select { + case <-h.closing: + return + default: + } + + fragment.RecalculateCache() + } + } + } + } +} + // setFileLimit attempts to set the open file limit to the FileLimit constant defined above. func (h *Holder) setFileLimit() { oldLimit := &syscall.Rlimit{}