@@ -92,8 +92,14 @@ var DailyLeaderboard = (function() {
9292
9393 var headBlock = dgp . head_block_number ;
9494 var targetStart = Math . max ( 1 , headBlock - WINDOW_BLOCKS + 1 ) ;
95+ var hasResumeBuild = ! _snapshot . ready && _snapshot . buildInProgress && _snapshot . windowStartBlock === targetStart && _snapshot . windowEndBlock === headBlock ;
9596 var needsFullBuild = ! _snapshot . ready || ! _snapshot . windowEndBlock || ! _snapshot . characters ;
9697
98+ if ( hasResumeBuild ) {
99+ _resumeBuild ( targetStart , headBlock , callback ) ;
100+ return ;
101+ }
102+
97103 if ( needsFullBuild ) {
98104 _buildWindow ( targetStart , headBlock , callback ) ;
99105 return ;
@@ -114,6 +120,7 @@ var DailyLeaderboard = (function() {
114120 _setSnapshot ( {
115121 loading : true ,
116122 ready : false ,
123+ buildInProgress : true ,
117124 progressPct : 0 ,
118125 statusText : Helpers . t ( 'leaderboard_loading_status' , { percent : 0 } ) ,
119126 windowStartBlock : startBlock ,
@@ -125,19 +132,71 @@ var DailyLeaderboard = (function() {
125132 } ) ;
126133
127134 DailyLeaderboardStorage . clearAll ( function ( ) {
135+ _persistProgressMeta ( startBlock , endBlock , startBlock - 1 , 0 , { } , { } , function ( ) {
136+ var ctx = {
137+ startBlock : startBlock ,
138+ endBlock : endBlock ,
139+ totalBlocks : Math . max ( 1 , endBlock - startBlock + 1 ) ,
140+ players : { } ,
141+ characters : { } ,
142+ processedBlocks : 0
143+ } ;
144+
145+ _scanRange ( ctx , startBlock , endBlock , function ( err ) {
146+ _loading = false ;
147+ if ( err ) {
148+ callback ( err , _snapshot ) ;
149+ return ;
150+ }
151+ _finalizeSnapshot ( ctx , startBlock , endBlock , callback ) ;
152+ } ) ;
153+ } ) ;
154+ } ) ;
155+ }
156+
157+ function _resumeBuild ( startBlock , endBlock , callback ) {
158+ _loading = true ;
159+ DailyLeaderboardStorage . getBlockContributionsInRange ( startBlock , endBlock , function ( err , blocks ) {
160+ if ( err ) {
161+ _loading = false ;
162+ _buildWindow ( startBlock , endBlock , callback ) ;
163+ return ;
164+ }
165+
166+ var resumedPlayers = _cloneObject ( _snapshot . players || { } ) ;
167+ var highestScanned = _snapshot . lastScannedBlock || ( startBlock - 1 ) ;
168+ if ( ( ! _snapshot . players || ! Object . keys ( _snapshot . players ) . length ) && blocks && blocks . length ) {
169+ resumedPlayers = { } ;
170+ for ( var i = 0 ; i < blocks . length ; i ++ ) {
171+ _reapplyBlockContribution ( resumedPlayers , blocks [ i ] ) ;
172+ if ( ( blocks [ i ] . blockNum || 0 ) > highestScanned ) highestScanned = blocks [ i ] . blockNum || highestScanned ;
173+ }
174+ }
175+
176+ var processedBlocks = Math . max ( 0 , highestScanned - startBlock + 1 ) ;
128177 var ctx = {
129178 startBlock : startBlock ,
130179 endBlock : endBlock ,
131180 totalBlocks : Math . max ( 1 , endBlock - startBlock + 1 ) ,
132- players : { } ,
133- characters : { } ,
134- processedBlocks : 0
181+ players : resumedPlayers ,
182+ characters : _cloneObject ( _snapshot . characters || { } ) ,
183+ processedBlocks : processedBlocks
135184 } ;
136185
137- _scanRange ( ctx , startBlock , endBlock , function ( err ) {
186+ _setSnapshot ( {
187+ loading : true ,
188+ ready : false ,
189+ buildInProgress : true ,
190+ players : resumedPlayers ,
191+ characters : ctx . characters ,
192+ progressPct : Math . max ( 0 , Math . min ( 100 , Math . floor ( processedBlocks * 100 / ctx . totalBlocks ) ) ) ,
193+ statusText : Helpers . t ( 'leaderboard_loading_status' , { percent : Math . max ( 0 , Math . min ( 100 , Math . floor ( processedBlocks * 100 / ctx . totalBlocks ) ) ) } )
194+ } ) ;
195+
196+ _scanRange ( ctx , highestScanned + 1 , endBlock , function ( scanErr ) {
138197 _loading = false ;
139- if ( err ) {
140- callback ( err , _snapshot ) ;
198+ if ( scanErr ) {
199+ callback ( scanErr , _snapshot ) ;
141200 return ;
142201 }
143202 _finalizeSnapshot ( ctx , startBlock , endBlock , callback ) ;
@@ -419,11 +478,27 @@ var DailyLeaderboard = (function() {
419478 }
420479 }
421480
481+ function _reapplyBlockContribution ( players , blockContrib ) {
482+ if ( ! blockContrib || ! blockContrib . players ) return ;
483+ for ( var account in blockContrib . players ) {
484+ if ( ! blockContrib . players . hasOwnProperty ( account ) ) continue ;
485+ var entry = blockContrib . players [ account ] ;
486+ if ( ! players [ account ] ) {
487+ players [ account ] = { account : account , name : ( entry && entry . name ) || account , xp24h : 0 , hunts24h : 0 , lastSeenBlock : blockContrib . blockNum || 0 } ;
488+ }
489+ players [ account ] . name = ( entry && entry . name ) || players [ account ] . name || account ;
490+ players [ account ] . xp24h += ( entry && entry . xp ) || 0 ;
491+ players [ account ] . hunts24h += ( entry && entry . hunts ) || 0 ;
492+ players [ account ] . lastSeenBlock = blockContrib . blockNum || players [ account ] . lastSeenBlock || 0 ;
493+ }
494+ }
495+
422496 function _finalizeSnapshot ( ctx , startBlock , endBlock , callback ) {
423497 var rows = _buildRows ( ctx . players || { } ) ;
424498 var meta = {
425499 ready : true ,
426500 loading : false ,
501+ buildInProgress : false ,
427502 progressPct : 100 ,
428503 statusText : '' ,
429504 windowStartBlock : startBlock ,
@@ -467,10 +542,15 @@ var DailyLeaderboard = (function() {
467542 var pct = Math . max ( 0 , Math . min ( 100 , Math . floor ( ctx . processedBlocks * 100 / ctx . totalBlocks ) ) ) ;
468543 _setSnapshot ( {
469544 loading : true ,
545+ buildInProgress : ! _snapshot . ready ,
470546 progressPct : pct ,
471547 lastScannedBlock : currentBlock ,
472548 statusText : Helpers . t ( 'leaderboard_loading_status' , { percent : pct } )
473549 } ) ;
550+
551+ if ( ! _snapshot . ready && ( ctx . processedBlocks % 25 === 0 || currentBlock >= ctx . endBlock ) ) {
552+ _persistProgressMeta ( ctx . startBlock , ctx . endBlock , currentBlock , pct , ctx . players , ctx . characters , function ( ) { } ) ;
553+ }
474554 }
475555
476556 function _setSnapshot ( patch ) {
@@ -485,6 +565,7 @@ var DailyLeaderboard = (function() {
485565 var snapshot = _emptySnapshot ( ) ;
486566 snapshot = _merge ( snapshot , meta || { } ) ;
487567 snapshot . ready = ! ! snapshot . ready ;
568+ snapshot . buildInProgress = ! ! snapshot . buildInProgress && ! snapshot . ready ;
488569 snapshot . loading = false ;
489570 snapshot . players = snapshot . players || { } ;
490571 snapshot . characters = snapshot . characters || { } ;
@@ -513,6 +594,26 @@ var DailyLeaderboard = (function() {
513594 return JSON . parse ( JSON . stringify ( input ) ) ;
514595 }
515596
597+ function _persistProgressMeta ( startBlock , endBlock , lastScannedBlock , progressPct , players , characters , callback ) {
598+ callback = callback || function ( ) { } ;
599+ DailyLeaderboardStorage . setMeta ( {
600+ ready : false ,
601+ loading : false ,
602+ buildInProgress : true ,
603+ progressPct : progressPct || 0 ,
604+ statusText : Helpers . t ( 'leaderboard_loading_status' , { percent : progressPct || 0 } ) ,
605+ windowStartBlock : startBlock ,
606+ windowEndBlock : endBlock ,
607+ lastScannedBlock : lastScannedBlock ,
608+ lastUpdatedAt : Date . now ( ) ,
609+ players : players || { } ,
610+ characters : characters || { } ,
611+ rows : _buildRows ( players || { } )
612+ } , function ( ) {
613+ callback ( ) ;
614+ } ) ;
615+ }
616+
516617 return {
517618 init : init ,
518619 subscribe : subscribe ,
0 commit comments