@@ -3,8 +3,10 @@ package reindexer
33import (
44 "context"
55 "encoding/json"
6+ "errors"
67 "fmt"
78 "regexp"
9+ "time"
810
911 log "github.com/sirupsen/logrus"
1012
@@ -13,6 +15,35 @@ import (
1315 es7 "github.com/olivere/elastic/v7"
1416)
1517
18+ func postReIndex (ctx context.Context , sourceIndex , newIndexName string ) error {
19+ // Fetch all the aliases of old index
20+ alias , err := aliasesOf (ctx , sourceIndex )
21+
22+ var aliases = []string {}
23+ if err != nil {
24+ return errors .New (`error fetching aliases of index ` + sourceIndex + "\n " + err .Error ())
25+ }
26+
27+ if alias == "" {
28+ aliases = append (aliases , sourceIndex )
29+ } else {
30+ aliases = append (aliases , alias )
31+ }
32+
33+ // Delete old index
34+ err = deleteIndex (ctx , sourceIndex )
35+ if err != nil {
36+ return errors .New (`error deleting source index ` + sourceIndex + "\n " + err .Error ())
37+ }
38+ // Set aliases of old index to the new index.
39+ err = setAlias (ctx , newIndexName , aliases ... )
40+ if err != nil {
41+ return errors .New (`error setting alias for ` + newIndexName + "\n " + err .Error ())
42+ }
43+
44+ return nil
45+ }
46+
1647// Reindex Inplace: https://www.elastic.co/guide/en/elasticsearch/reference/current/reindex-upgrade-inplace.html
1748//
1849// 1. Create a new index and copy the mappings and settings from the old index.
@@ -116,53 +147,31 @@ func reindex(ctx context.Context, sourceIndex string, config *reindexConfig, wai
116147 Destination (dest ).
117148 WaitForCompletion (waitForCompletion )
118149
119- // If wait_for_completion = true, then we carry out the task synchronously along with three more steps:
120- // - fetch any aliases of the old index
121- // - delete the old index
122- // - set the aliases of the old index to the new index
123150 if waitForCompletion {
124151 response , err := reindex .Do (ctx )
125152 if err != nil {
126153 return nil , err
127154 }
128155
129156 if destinationIndex == "" {
130- // Fetch all the aliases of old index
131- alias , err := aliasesOf (ctx , sourceIndex )
132-
133- var aliases = []string {}
157+ err = postReIndex (ctx , sourceIndex , newIndexName )
134158 if err != nil {
135- return nil , fmt .Errorf (`error fetching aliases of index "%s": %v` , sourceIndex , err )
136- }
137-
138- if alias == "" {
139- aliases = append (aliases , sourceIndex )
140- } else {
141- aliases = append (aliases , alias )
142- }
143-
144- // Delete old index
145- err = deleteIndex (ctx , sourceIndex )
146- if err != nil {
147- return nil , fmt .Errorf (`error deleting index "%s": %v\n` , sourceIndex , err )
148- }
149- // Set aliases of old index to the new index.
150- err = setAlias (ctx , newIndexName , aliases ... )
151- if err != nil {
152- return nil , fmt .Errorf (`error setting alias "%s" for index "%s"` , sourceIndex , newIndexName )
159+ return nil , err
153160 }
154161 }
155162
156163 return json .Marshal (response )
157164 }
158-
159- // If wait_for_completion = false, we carry out the reindexing asynchronously and return the task ID.
165+ // If wait_for_completion = false, we carry out the re-indexing asynchronously and return the task ID.
166+ log . Println ( logTag , fmt . Sprintf ( " Data is > %d so using async reindex" , IndexStoreSize ))
160167 response , err := reindex .DoAsync (context .Background ())
161168 if err != nil {
162169 return nil , err
163170 }
164171 taskID := response .TaskId
165172
173+ go asyncReIndex (taskID , sourceIndex , newIndexName )
174+
166175 // Get the reindex task by ID
167176 task , err := util .GetClient7 ().TasksGetTask ().TaskId (taskID ).Do (context .Background ())
168177 if err != nil {
@@ -383,3 +392,59 @@ func getAliasIndexMap(ctx context.Context) (map[string]string, error) {
383392
384393 return res , nil
385394}
395+
396+ func getIndexSize (ctx context.Context , indexName string ) (int64 , error ) {
397+ var res int64
398+ index := classify .GetAliasIndex (indexName )
399+ if index == "" {
400+ index = indexName
401+ }
402+ stats , err := util .GetClient7 ().IndexStats (indexName ).Do (ctx )
403+ if err != nil {
404+ return res , err
405+ }
406+ res = stats .Indices [index ].Primaries .Store .SizeInBytes
407+ return res , nil
408+ }
409+
410+ func isTaskCompleted (ctx context.Context , taskID string ) (bool , error ) {
411+ res := false
412+
413+ status , err := util .GetClient7 ().TasksGetTask ().TaskId (taskID ).Do (ctx )
414+ if err != nil {
415+ log .Errorln (logTag , " Get task status error" , err )
416+ return res , err
417+ }
418+
419+ res = status .Completed
420+ return res , nil
421+ }
422+
423+ // go routine to track async re-indexing process for a given source and destination index.
424+ // it checks every 30s if task is completed or not.
425+ func asyncReIndex (taskID , source , destination string ) {
426+ SetCurrentProcess (taskID , source , destination )
427+ isCompleted := make (chan bool , 1 )
428+ ticker := time .Tick (30 * time .Second )
429+ ctx := context .Background ()
430+
431+ for {
432+ select {
433+ case <- ticker :
434+ ok , _ := isTaskCompleted (ctx , taskID )
435+ log .Println (logTag , " " + taskID + " task is still re-indexing data..." )
436+ if ok {
437+ isCompleted <- true
438+ }
439+ case <- isCompleted :
440+ log .Println (logTag , taskID + " task completed successfully" )
441+ // remove process from current cache
442+ RemoveCurrentProcess (taskID )
443+ err := postReIndex (ctx , source , destination )
444+ if err != nil {
445+ log .Errorln (logTag , " post re-indexing error: " , err )
446+ }
447+ return
448+ }
449+ }
450+ }
0 commit comments