@ -343,7 +343,6 @@ func convertPoolChartsResults(raw *redis.ZSliceCmd) []*PoolCharts {
return reverse
return reverse
}
}
func ( r * RedisClient ) GetNetCharts ( netHashLen int64 ) ( stats [ ] * NetCharts , err error ) {
func ( r * RedisClient ) GetNetCharts ( netHashLen int64 ) ( stats [ ] * NetCharts , err error ) {
tx := r . client . Multi ( )
tx := r . client . Multi ( )
defer tx . Close ( )
defer tx . Close ( )
@ -1105,30 +1104,41 @@ func convertStringMap(m map[string]string) map[string]interface{} {
return result
return result
}
}
// WARNING: Must run it periodically to flush out of window hashrate entries
// FlushStaleStats deletes all stale statistics in Redis.
func ( r * RedisClient ) FlushStaleStats ( window , largeWindow time . Duration ) ( int64 , error ) {
// window defines the duration after which the statistics become stale.
// largeWindow defines the duration after which the statistics are permanently deleted.
func ( r * RedisClient ) FlushStaleStats ( staleDuration , largeWindow time . Duration ) ( int64 , error ) {
// Convert the current timestamp to seconds
now := util . MakeTimestamp ( ) / 1000
now := util . MakeTimestamp ( ) / 1000
max := fmt . Sprint ( "(" , now - int64 ( window / time . Second ) )
// Define the maximum expiry date for stale statistics
total , err := r . client . ZRemRangeByScore ( r . formatKey ( "hashrate" ) , "-inf" , max ) . Result ( )
maxStale := fmt . Sprint ( "(" , now - int64 ( staleDuration / time . Second ) )
// Delete all stale statistics from the "hashrate" hash
total , err := r . client . ZRemRangeByScore ( r . formatKey ( "hashrate" ) , "-inf" , maxStale ) . Result ( )
if err != nil {
if err != nil {
return total , err
return total , err
}
}
var c int64
var cursor int64
// Use a map to ensure that each miner is only processed once
miners := make ( map [ string ] struct { } )
miners := make ( map [ string ] struct { } )
max = fmt . Sprint ( "(" , now - int64 ( largeWindow / time . Second ) )
// Define the maximum expiry date for the statistics to be deleted permanently
maxFinal := fmt . Sprint ( "(" , now - int64 ( largeWindow / time . Second ) )
// Iterate over all hash keys starting with "hashrate", and delete all stale statistics for each miner
for {
for {
var keys [ ] string
var keys [ ] string
var err error
var err error
c , keys , err = r . client . Scan ( c , r . formatKey ( "hashrate" , "*" ) , 100 ) . Result ( )
cursor , keys , err = r . client . Scan ( cursor , r . formatKey ( "hashrate" , "*" ) , 100 ) . Result ( )
if err != nil {
if err != nil {
return total , err
return total , err
}
}
for _ , row := range keys {
for _ , key := range keys {
login := strings . Split ( row , ":" ) [ 2 ]
// Extract the miner name from the key
login := strings . Split ( key , ":" ) [ 2 ]
if _ , ok := miners [ login ] ; ! ok {
if _ , ok := miners [ login ] ; ! ok {
n , err := r . client . ZRemRangeByScore ( r . formatKey ( "hashrate" , login ) , "-inf" , max ) . Result ( )
// Delete all stale statistics for this miner
n , err := r . client . ZRemRangeByScore ( r . formatKey ( "hashrate" , login ) , "-inf" , maxFinal ) . Result ( )
if err != nil {
if err != nil {
return total , err
return total , err
}
}
@ -1136,7 +1146,8 @@ func (r *RedisClient) FlushStaleStats(window, largeWindow time.Duration) (int64,
total += n
total += n
}
}
}
}
if c == 0 {
// If we've processed all keys, exit the loop
if cursor == 0 {
break
break
}
}
}
}