package Ġai . plat on . pulsar . crawl . fetch Ċ Ċ import Ġai . plat on . pulsar . common . DateTime s Ċ import Ġai . plat on . pulsar . common . config . Parameterized Ċ import Ġai . plat on . pulsar . common . config . Params Ċ import Ġai . plat on . pulsar . crawl . common . URL Util Ċ import Ġai . plat on . pulsar . crawl . fetch . data . Pool Id Ċ import Ġorg . apache . commons . collections 4 . queue . Circular Fifo Queue Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . text . Decimal Format Ċ import Ġjava . time . Duration Ċ import Ġjava . time . Instant Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . Concurrent Linked Queue Ċ Ċ /** Ċ Ġ* ĠThis Ġclass Ġhandles ĠFetch Tasks Ġwhich Ġcome Ġfrom Ġthe Ġsame Ġhost ĠID Ġ( be Ġit Ċ Ġ* Ġa Ġproto / hostname Ġor Ġproto / IP Ġpair ). Ċ Ġ* Ċ Ġ* ĠIt Ġalso Ġkeeps Ġtrack Ġof Ġrequests Ġin Ġprogress Ġand Ġelapsed Ġtime Ġbetween Ġrequests . Ċ Ġ*/ Ċ class ĠTask Pool ( val Ġid : ĠPool Id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠHost Ġgroup Ġmode Ġ: Ġcan Ġbe Ġby Ġip , Ġby Ġhost Ġor Ġby Ġdomain Ġ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Mode : ĠURL Util . Group Mode , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠMax Ġthread Ġcount Ġfor Ġthis Ġqueue Ġ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġallowed Threads : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠC rawl Ġdelay Ġfor Ġthe Ġqueue Ġ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġcrawl Delay : ĠDuration , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠMin imal Ġcrawl Ġdelay Ġfor Ġthe Ġqueue Ġ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġmin C rawl Delay : ĠDuration , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠOnce Ġtimeout , Ġthe Ġpending Ġitems Ġshould Ġbe Ġput Ġto Ġthe Ġready Ġqueue Ġagain Ġ Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġpending Timeout : ĠDuration Ċ ) Ġ: ĠComparable < Task Pool >, ĠParameter ized Ġ{ ĊĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Task Pool :: class . java ) ĊĊĠĠĠ Ġ/** ĠHold Ġall Ġtasks Ġready Ġto Ġfetch Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġready Tasks Ġ= ĠConcurrent Linked Queue < Job Fetch Task >() ĊĠĠĠ Ġ/** ĠHold Ġall Ġtasks Ġare Ġfetching Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġpending Tasks Ġ= ĠConcurrent HashMap < Int , ĠJob Fetch Task >() ĊĠĠĠ Ġ/** ĠIf Ġa Ġtask Ġcosts Ġmore Ġthen Ġthis Ġduration , Ġit 's Ġa Ġslow Ġtask Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġslow Task Threshold Ġ= ĠDuration . of Minutes ( 2 ) ĊĠĠĠ Ġ/** ĠRecord Ġtiming Ġcost Ġof Ġslow Ġtasks Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġslow Tasks Recorder Ġ= ĠCircular Fifo Queue < Duration >( REC ENT _ TASK S _ COUNT _ LIMIT ) ĊĊĠĠĠ Ġ/** ĠNext Ġfetch Ġtime Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġnext Fetch Time Ġ= ĠInstant . now () ĊĠĠĠ Ġprivate Ġvar Ġrecent Finished Tasks Ġ= Ġ 1 ĊĠĠĠ Ġprivate Ġvar Ġrecent Fetch Millis : ĠLong Ġ= Ġ 1 ĊĠĠĠ Ġprivate Ġvar Ġtotal Finished Tasks Ġ= Ġ 1 ĊĠĠĠ Ġprivate Ġvar Ġtotal Fetch Millis : ĠLong Ġ= Ġ 1 ĊĠĠĠ Ġprivate Ġvar Ġunreachable Tasks Ġ= Ġ 0 ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġa Ġfetch Ġqueue Ġis Ġinactive , Ġthe Ġqueue Ġdoes Ġnot Ġaccept Ġany Ġtasks , Ġnor Ġserve Ġany Ġrequests , ĊĠĠĠĠ Ġ* Ġbut Ġstill Ġhold Ġpending Ġtasks , Ġwaiting Ġto Ġfinish ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġvar Ġstatus Ġ= ĠStatus . ACTIVITY ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġval Ġpriority : ĠInt Ġget () Ġ= Ġid . priority ĊĠĠĠ Ġval Ġprotocol : ĠString Ġget () Ġ= Ġid . protocol ĊĠĠĠ Ġval Ġhost : ĠString Ġget () Ġ= Ġid . host ĊĠĠĠ Ġval Ġis Slow : ĠBoolean Ġget () Ġ= Ġis Slow ( Duration . of Seconds ( 1 )) ĊĠĠĠ Ġval ĠisActive : ĠBoolean Ġget () Ġ= Ġthis . status Ġ== ĠStatus . ACTIVITY ĊĠĠĠ Ġval Ġis Inactive : ĠBoolean Ġget () Ġ= Ġthis . status Ġ== ĠStatus . IN ACTIVITY ĊĠĠĠ Ġval Ġis Ret ired : ĠBoolean Ġget () Ġ= Ġthis . status Ġ== ĠStatus . RE TI RED ĊĊĠĠĠ Ġval Ġnum Ready Tasks : ĠInt Ġget () Ġ= Ġready Tasks . size ĊĠĠĠ Ġval Ġnum Pending Tasks : ĠInt Ġget () Ġ= Ġpending Tasks . size ĊĠĠĠ Ġval Ġnum Total Finished Tasks : ĠInt Ġget () Ġ= Ġtotal Finished Tasks ĊĠĠĠ Ġval Ġnum Slow Tasks : ĠInt Ġget () Ġ= Ġsynchronized ( slow Tasks Recorder ) Ġ{ Ġslow Tasks Recorder . size Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAverage Ġcost Ġin Ġseconds ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġaverage Time : ĠDouble Ġget () Ġ= Ġtotal Fetch Millis . toDouble () Ġ/ Ġ 1 0 0 0 . 0 Ġ/ Ġtotal Finished Tasks . toDouble () ĊĠĠĠ Ġval Ġaverage Recent Time Cost : ĠDouble Ġget () Ġ= Ġrecent Fetch Millis . toDouble () Ġ/ Ġ 1 0 0 0 . 0 Ġ/ Ġrecent Finished Tasks . toDouble () ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAverage Ġfinished Ġtasks Ġper Ġsecond ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġaverage T ps : ĠDouble Ġget () Ġ= Ġtotal Finished Tasks Ġ/ Ġ( total Fetch Millis Ġ/ Ġ 1 0 0 0 . 0 ) ĊĠĠĠ Ġval Ġaverage Recent T ps : ĠDouble Ġget () Ġ= Ġrecent Finished Tasks Ġ/ Ġ( recent Fetch Millis Ġ/ Ġ 1 0 0 0 . 0 ) ĊĊĠĠĠ Ġval Ġtime Report : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĠString . format ("% 1 $ 4 0 s Ġ-> Ġaverage Time Ġ: Ġ% 2 $. 2 fs / p , Ġav a Th o Rate Ġ: Ġ% 3 $. 2 fp / s ", Ġid , Ġaverage Time , Ġaverage T ps ) ĊĊĠĠĠ Ġenum Ġclass ĠStatus Ġ{ ĊĠĠĠĠĠĠĠ ĠACT IVITY , ĠIN ACTIVITY , ĠRET I RED ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Params (): ĠParams Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdf Ġ= ĠDecimal Format (" ### 0 . ## ") ĊĊĠĠĠĠĠĠĠ Ġreturn ĠParams . of ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" className ", Ġjava Class . simple Name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" status ", Ġstatus , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" id ", Ġid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" allowed Threads ", Ġallowed Threads , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" pending Tasks ", Ġpending Tasks . size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" crawl Delay ", Ġcrawl Delay , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" min C rawl Delay ", Ġmin C rawl Delay , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" now ", ĠDateTime s . now (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" next Fetch Time ", ĠDateTime s . format ( next Fetch Time ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ave Time Cost ( s )", Ġdf . format ( average Time ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ave Th o Rate ( s )", Ġdf . format ( average T ps ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ready Tasks ", Ġnum Ready Tasks , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" pending Tasks ", Ġnum Pending Tasks , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" f insi hed Tasks ", Ġnum Total Finished Tasks , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" unreachable Tasks ", Ġunreachable Tasks ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠPro duce Ġa Ġtask Ġto Ġthis Ġqueue . ĠRet ired Ġqueues Ġdo Ġnot Ġaccept Ġany Ġtasks Ġ Ġ*/ ĊĠĠĠ Ġfun Ġproduce ( task : ĠJob Fetch Task ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( status Ġ!= ĠStatus . ACTIVITY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( task . priority Ġ!= Ġid . priority Ġ|| Ġtask . host Ġ!= Ġid . host ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Queue Ġid Ġmis matches Ġwith ĠFetch Task Ġ#$ task ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġready Tasks . add ( task ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠAsk Ġa Ġtask Ġfrom Ġthis Ġqueue . ĠRet ired Ġqueues Ġdo Ġnot Ġassign Ġany Ġtasks Ġ Ġ*/ ĊĠĠĠ Ġfun Ġconsume (): ĠJob Fetch Task ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( status Ġ!= ĠStatus . ACTIVITY ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( allowed Threads Ġ> Ġ 0 Ġ&& Ġpending Tasks . size Ġ>= Ġallowed Threads ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠ Ġif Ġ( now . is Before ( next Fetch Time )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsize 0 Ġ= Ġready Tasks . size ĊĠĠĠĠĠĠĠ Ġval Ġfetch Task Ġ= Ġready Tasks . poll () ĊĠĠĠĠĠĠĠ Ġif Ġ( fetch Task Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( size 0 Ġ== Ġready Tasks . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn (" Ready Ġtasks Ġdoes Ġnot Ġreduce Ġit 's Ġsize ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhang Up ( fetch Task , Ġnow ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfetch Task ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfinish ( itemId : ĠInt , Ġas ap : ĠBoolean ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġitem Ġ= Ġpending Tasks [ itemId ] ĊĠĠĠĠĠĠĠ Ġreturn Ġitem Ġ!= Ġnull Ġ&& Ġfinish ( item , Ġas ap ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠNote Ġ: ĠWe Ġhave Ġset Ġresponse Ġtime Ġfor Ġeach Ġpage , Ġ@ see Ġ{ Http Base # get Protocol Output } ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġfinish ( fetch Task : ĠJob Fetch Task , Ġas ap : ĠBoolean ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġpending Tasks . remove ( fetch Task . itemId ) ĊĊĠĠĠĠĠĠĠ Ġval Ġfinish Time Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠ Ġset Next Fetch Time ( finish Time , Ġas ap ) ĊĊĠĠĠĠĠĠĠ Ġval Ġelapsed Ġ= ĠDuration . between ( fetch Task . pending Start , Ġfinish Time ) ĊĠĠĠĠĠĠĠ Ġif Ġ( elapsed Ġ> Ġslow Task Threshold ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsynchronized ( slow Tasks Recorder ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġslow Tasks Recorder . add ( elapsed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ++ recent Finished Tasks ĊĠĠĠĠĠĠĠ Ġrecent Fetch Millis Ġ+= Ġelapsed . to Millis () ĊĠĠĠĠĠĠĠ Ġif Ġ( recent Finished Tasks Ġ> ĠREC ENT _ TASK S _ COUNT _ LIMIT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrecent Finished Tasks Ġ= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrecent Fetch Millis Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ++ total Finished Tasks ĊĠĠĠĠĠĠĠ Ġtotal Fetch Millis Ġ+= Ġelapsed . to Millis () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Pending Task ( item ID : ĠInt ): ĠJob Fetch Task ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġpending Tasks [ item ID ] ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠH ang Ġup Ġthe Ġtask Ġand Ġwait Ġfor Ġcompletion . ĠMove Ġthe Ġfetch Ġtask Ġto Ġpending Ġqueue . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhang Up ( fetch Task : ĠJob Fetch Task , Ġnow : ĠInstant ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfetch Task . pending Start Ġ= Ġnow ĊĠĠĠĠĠĠĠ Ġpending Tasks [ fetch Task . itemId ] Ġ= Ġfetch Task ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Tasks (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġhas Ready Tasks () Ġ|| Ġhas Pending Tasks () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Ready Tasks (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ! ready Tasks . isEmpty () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Pending Tasks (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ! pending Tasks . isEmpty () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġpending Task Exists ( itemId : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġpending Tasks . containsKey ( itemId ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġis Slow ( threshold : ĠDuration ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġaverage Recent Time Cost Ġ> Ġthreshold . seconds ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġenable () Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . status Ġ= ĠStatus . ACTIVITY ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdisable () Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . status Ġ= ĠStatus . IN ACTIVITY ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġret ire () Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . status Ġ= ĠStatus . RE TI RED ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclear Ready Queue (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġready Tasks . size ĊĠĠĠĠĠĠĠ Ġready Tasks . clear () ĊĠĠĠĠĠĠĠ Ġreturn Ġcount ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclear Pending Queue (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġpending Tasks . size ĊĠĠĠĠĠĠĠ Ġpending Tasks . clear () ĊĠĠĠĠĠĠĠ Ġreturn Ġcount ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclear Pending Tasks If F ew ( threshold : ĠInt ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcount Ġ= Ġpending Tasks . size ĊĊĠĠĠĠĠĠĠ Ġif Ġ( count Ġ> Ġthreshold ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( pending Tasks . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnow Ġ= ĠInstant . now () ĊĠĠĠĠĠĠĠ Ġval Ġreport Ġ= Ġpending Tasks . values . take ( threshold ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. join ToString ("\ n ", Ġ" Clear ing Ġslow Ġpending Ġitems Ġ: Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġit . url String Ġ+ Ġ" Ġ: Ġ" Ġ+ ĠDuration . between ( it . pending Start , Ġnow ) Ġ} ĊĠĠĠĠĠĠĠ Ġlog . info ( report ) ĊĊĠĠĠĠĠĠĠ Ġpending Tasks . clear () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcount ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdump ( drop : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . info (" Dump Ġpool Ġ| Ġ" Ġ+ Ġparams . format As Line ()) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( drop Ġ&& Ġready Tasks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlimit Ġ= Ġ 2 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġreport Ġ= Ġ" Drop Ġthe Ġfollowing Ġtasks Ġ: Ġ" ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfetch Task : ĠJob Fetch Task ? Ġ= Ġready Tasks . poll () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( fetch Task Ġ!= Ġnull Ġ&& Ġ++ i Ġ<= Ġlimit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Ġ+= Ġ" Ġ Ġ" Ġ+ Ġi Ġ+ Ġ". Ġ" Ġ+ Ġfetch Task . url String Ġ+ Ġ"\ t " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfetch Task Ġ= Ġready Tasks . poll () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info ( report ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġset Next Fetch Time ( finish Time : ĠInstant , Ġas ap : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġnext Fetch Time Ġ= Ġif Ġ(! as ap ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish Time . plus ( if Ġ( allowed Threads Ġ> Ġ 1 ) Ġmin C rawl Delay Ġelse Ġcrawl Delay ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish Time ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġother Ġis ĠTask Pool Ġ&& Ġid Ġ== Ġother . id ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠhashCode (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġid . hashCode () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġcompare To ( other : ĠTask Pool ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġid . compareTo ( other . id ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġid . toString () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠREC ENT _ TASK S _ COUNT _ LIMIT Ġ= Ġ 1 0 0 ĊĠĠĠ Ġ} Ċ } Ċ