@@ -52,16 +52,6 @@ func (d *dashboardData) handleRollings() error {
5252 if err != nil {
5353 return errors .Wrap (err , "failed to do rollings" )
5454 }
55- for _ , rolling := range rollings {
56- rolling := rolling
57- eg .Go (func () error {
58- return d .swapRollingTables (rolling )
59- })
60- }
61- err = eg .Wait ()
62- if err != nil {
63- return errors .Wrap (err , "failed to swap rolling tables" )
64- }
6555 return nil
6656}
6757
@@ -87,23 +77,46 @@ func (d *dashboardData) fillUnsafeRolling(rolling edb.Rollings) error {
8777 }
8878 metrics .State .WithLabelValues ("dashboard_data_exporter_finished_epoch" ).Set (float64 (finishedEpoch ))
8979 // if finishedEpoch is not the same as the safeepoch we skip updating the rolling so resyncing after falling back is fast
90- if safeEpoch := d .latestSafeEpoch .Load (); finishedEpoch != safeEpoch {
91- d .log .Infof ("skipping rolling %s update, finished epoch %d, safe epoch %d" , rolling , finishedEpoch , safeEpoch )
92- return nil
93- }
94- rollingEpoch , err := edb .GetRollingLastEpoch (rolling )
80+ /*
81+ if safeEpoch := d.latestSafeEpoch.Load(); finishedEpoch != safeEpoch {
82+ d.log.Infof("skipping rolling %s update, finished epoch %d, safe epoch %d", rolling, finishedEpoch, safeEpoch)
83+ return nil
84+ }
85+ */
86+
87+ // check if we have work to do
88+ rollingGenerated , err := edb .CheckIfRollingIsGenerated (rolling , finishedEpoch )
9589 if err != nil {
96- return errors .Wrap (err , "failed to get rolling last epoch " )
90+ return errors .Wrap (err , "failed to check if rolling is generated " )
9791 }
98- metrics .State .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_epoch" , rolling )).Set (float64 (rollingEpoch ))
99- if rollingEpoch >= finishedEpoch {
100- d .log .Debugf ("rolling %s is up to date" , rolling )
92+ if rollingGenerated {
93+ d .log .Debugf ("rolling %s is already generated for epoch %d" , rolling , finishedEpoch )
10194 return nil
10295 }
96+
97+ // metrics crap
98+ defer func () {
99+ rollingEpoch , err := edb .GetRollingLastEpoch (rolling )
100+ if err != nil {
101+ d .log .Error (err , "failed to get rolling last epoch" , 0 )
102+ return
103+ }
104+ metrics .State .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_epoch" , rolling )).Set (float64 (rollingEpoch ))
105+ }()
103106 defer func () {
104107 metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_overall" , rolling )).Observe (time .Since (start ).Seconds ())
105108 }()
106- d .log .Infof ("rolling %s is outdated, latest epoch %d, latest finished epoch %d" , rolling , rollingEpoch , finishedEpoch )
109+
110+ // also cleanup crap
111+ defer func () {
112+ err := edb .NukeUnsafeRollingTable (rolling )
113+ if err != nil {
114+ d .log .Error (err , "failed to nuke unsafe rolling table" , 0 )
115+ }
116+ }()
117+
118+ //d.log.Infof("rolling %s is outdated, latest epoch %d, latest finished epoch %d", rolling, rollingEpoch, finishedEpoch)
119+ d .log .Infof ("rolling %s needs generation for epoch %d" , rolling , finishedEpoch )
107120
108121 now := time .Now ()
109122 // next, nuke the unsafe rolling tables to prepare them for us to fill them
@@ -112,6 +125,7 @@ func (d *dashboardData) fillUnsafeRolling(rolling edb.Rollings) error {
112125 return errors .Wrap (err , "failed to nuke unsafe rolling table" )
113126 }
114127 metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_nuke_unsafe" , rolling )).Observe (time .Since (now ).Seconds ())
128+
115129 // now we fetch the start & end for each pre-aggregated table we use
116130 minTs := utils .EpochToTime (uint64 (finishedEpoch )).Add (- rolling .GetDuration ())
117131 // we also need to add one epoch to the minTs because each epoch timestamp is the start of the epoch
@@ -141,6 +155,7 @@ func (d *dashboardData) fillUnsafeRolling(rolling edb.Rollings) error {
141155 metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_minmax" , table )).Observe (time .Since (now ).Seconds ())
142156 metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_minmax" , rolling )).Observe (time .Since (now ).Seconds ())
143157 }
158+
144159 // now the transfer logic for each source
145160 eg := errgroup.Group {}
146161 eg .SetLimit (int (utils .Config .DashboardExporter .RollingPartsInParallel ))
@@ -154,6 +169,10 @@ func (d *dashboardData) fillUnsafeRolling(rolling edb.Rollings) error {
154169 eg .Go (func () error {
155170 d .log .Infof ("transferring rolling source %s to rolling %s" , source , rolling )
156171 now := time .Now ()
172+ // add caching for bounded source reads that dont change? so hourly read for the 7d can be reused for up to 9 rolling gen, for example
173+ // daily could be reused for up to a day for >90d rollings
174+ // basically if a min and max is defined it can be cached
175+ // ye we should really be doing this
157176 err := edb .TransferRollingSourceToRolling (rolling , source , * minmax )
158177 if err != nil {
159178 return errors .Wrap (err , "failed to transfer rolling source to rolling" )
@@ -170,28 +189,21 @@ func (d *dashboardData) fillUnsafeRolling(rolling edb.Rollings) error {
170189 if err != nil {
171190 return errors .Wrap (err , "failed to transfer all rolling sources" )
172191 }
173- return nil
174- }
175192
176- func (d * dashboardData ) swapRollingTables (rolling edb.Rollings ) error {
177- now := time .Now ()
178- // swap or not, we want unsafe clean so clickhouse doesnt waste compute on it. if it fails the next attempt would nuke it at startup anyways
179- defer func () {
180- err := edb .NukeUnsafeRollingTable (rolling )
181- if err != nil {
182- d .log .Error (err , "failed to nuke unsafe rolling table" , 0 )
183- }
184- }()
185- err := edb .SwapRollingTables (rolling )
193+ // now we swap the tables
194+ err = edb .SwapRollingTables (rolling )
186195 if err != nil {
187196 return errors .Wrap (err , "failed to swap rolling tables" )
188197 }
189- metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_swap" , rolling )).Observe (time .Since (now ).Seconds ()) // update metric after run
198+ metrics .TaskDuration .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_swap" , rolling )).Observe (time .Since (now ).Seconds ())
190199
191- rollingEpoch , err := edb .GetRollingLastEpoch (rolling )
200+ // mark rolling as generated for this epoch
201+ err = edb .MarkRollingAsGenerated (rolling , finishedEpoch )
192202 if err != nil {
193- d . log . Error (err , "failed to get rolling last epoch" , 0 )
203+ return errors . Wrap (err , "failed to mark rolling as generated" )
194204 }
195- metrics .State .WithLabelValues (fmt .Sprintf ("dashboard_data_exporter_rolling_%s_epoch" , rolling )).Set (float64 (rollingEpoch ))
205+
206+ d .log .Infof ("completed rolling %s generation for epoch %d in %s" , rolling , finishedEpoch , time .Since (start ))
207+
196208 return nil
197209}
0 commit comments