// // Copyright 2019 SenX S.A.S. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, version 3. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see // <% SAVE '.context' STORE 'lastarchive.attr' '.lastarchive' MACROCONFIGDEFAULT '.lastarchive' CSTORE 'lastpurge.attr' '.lastpurge' MACROCONFIGDEFAULT '.lastpurge' CSTORE [ 'RTOKEN' 'WTOKEN' 'CLASS_SELECTOR' 'LABELS_SELECTOR' 'ARCHIVE_MACRO' 'PURGE_MACRO' 'MIN_DELAY' ] STORE // Add the lastarchive selector to the labels selectors $LABELS_SELECTOR '~.*' $.lastarchive PUT DROP // FIND the GTS [ $RTOKEN $CLASS_SELECTOR $LABELS_SELECTOR ] FIND // Stop now if there are no matching GTS DUP SIZE 0 == <% STOP %> IFT // // Retrieve GTS to archive and extract the oldest archived period // () SWAP <% ATTRIBUTES $.lastarchive GET +! %> FOREACH SET-> LSORT 0 GET 'lastarchive' STORE // // Compute the next archival period // $lastarchive @senx/arch/period [ NULL NULL 'nextperiod' 'prevperiod' ] STORE $nextperiod @senx/arch/period [ 'start' 'end' NULL NULL ] STORE // // FETCH data to archive - we only select those with the oldest lastarchive attribute value // [ $RTOKEN $CLASS_SELECTOR $LABELS_SELECTOR $lastarchive $.lastarchive PUT ] FIND // Iterate over GTS to archive <% <% 'gts' STORE // Extract last purge $gts ATTRIBUTES $.lastpurge GET 'lastpurge' STORE // Extract selector $gts TOSELECTOR 'sel' STORE // Fetch data to archive { 'token' $RTOKEN 'selector' $sel 'start' $start 'end' $end } FETCH 'fetched' STORE // // Only proceed if the last archived period was also purged // and if the minimum delay has elapsed since the end of the // period to archive // // Keep track of the last archived period $lastarchive 'lastarchived' STORE // Only archive if the last archived period was also purged // This ensures that we do not have colliding archive/purge operations $lastpurge $lastarchive == // if less then $MIN_DELAY has elapsed since the end of the period to archive, bailout NOW $end - $MIN_DELAY >= AND <% // // Archive the data using the provided macro // We pass the GTS to archive and the archival period // $fetched SIZE 1 == <% $fetched 0 GET $nextperiod $ARCHIVE_MACRO EVAL %> IFT // Update metadata to update the lastarchive attribute $gts { $.lastarchive $nextperiod } SETATTRIBUTES // Update $gts so we have the correct attributes when marking the purge 'gts' STORE $gts $WTOKEN META // Update the last archived period $nextperiod 'lastarchived' STORE %> IFT // // Perform the purge if nextpurge is <= lastarchived // This and the test before archiving ensures there is no archive/purge collision // $lastpurge @senx/arch/period [ NULL NULL 'nextpurge' NULL ] STORE $nextpurge $lastarchived <= <% $gts $nextpurge $PURGE_MACRO EVAL // Update metadata to update the lastpurge attribute $gts { $.lastpurge $nextpurge } SETATTRIBUTES $WTOKEN META %> IFT %> <% %> <% %> TRY // We wrap the handling of each GTS in a TRY call so we do not abort the whole process for a single GTS failure %> FOREACH $.context RESTORE %>