github.com/bosssauce/ponzu@v0.11.1-0.20200102001432-9bc41b703131/system/api/analytics/batch.go (about)

     1  package analytics
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  	"time"
     7  
     8  	"github.com/boltdb/bolt"
     9  )
    10  
    11  // batchInsert is effectively a specialized version of SetContentMulti from the
    12  // db package, iterating over a []apiRequest instead of []url.Values
    13  func batchInsert(requests chan apiRequest) error {
    14  	var reqs []apiRequest
    15  	batchSize := len(requestChan)
    16  
    17  	for i := 0; i < batchSize; i++ {
    18  		reqs = append(reqs, <-requestChan)
    19  	}
    20  
    21  	err := store.Update(func(tx *bolt.Tx) error {
    22  		b, err := tx.CreateBucketIfNotExists([]byte("__requests"))
    23  		if err != nil {
    24  			return err
    25  		}
    26  
    27  		for _, apiReq := range reqs {
    28  			// get the next available ID and convert to string
    29  			// also set effectedID to int of ID
    30  			id, err := b.NextSequence()
    31  			if err != nil {
    32  				return err
    33  			}
    34  			cid := strconv.FormatUint(id, 10)
    35  
    36  			j, err := json.Marshal(apiReq)
    37  			if err != nil {
    38  				return err
    39  			}
    40  
    41  			err = b.Put([]byte(cid), j)
    42  			if err != nil {
    43  				return err
    44  			}
    45  		}
    46  
    47  		return nil
    48  
    49  	})
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  // batchPrune takes a duration to evaluate apiRequest dates against. If any of
    58  // the apiRequest timestamps are before the threshold, they are removed.
    59  // TODO: add feature to alternatively backup old analytics to cloud
    60  func batchPrune(threshold time.Duration) error {
    61  	now := time.Now()
    62  	today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.UTC)
    63  	max := today.Add(threshold)
    64  
    65  	// iterate through all request data
    66  	err := store.Update(func(tx *bolt.Tx) error {
    67  		b := tx.Bucket([]byte("__requests"))
    68  
    69  		err := b.ForEach(func(k, v []byte) error {
    70  			var r apiRequest
    71  			err := json.Unmarshal(v, &r)
    72  			if err != nil {
    73  				return err
    74  			}
    75  
    76  			// delete if timestamp is below or equal to max
    77  			ts := time.Unix(r.Timestamp/1000, 0)
    78  			if ts.Equal(max) || ts.Before(max) {
    79  				err := b.Delete(k)
    80  				if err != nil {
    81  					return err
    82  				}
    83  			}
    84  
    85  			return nil
    86  		})
    87  		if err != nil {
    88  			return err
    89  		}
    90  
    91  		return nil
    92  	})
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	return nil
    98  }