/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 ĠAt Large ĠResearch Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ċ Ġ* Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE Ċ Ġ* ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġorg . opend c . compute . service . internal Ċ Ċ import Ġio . op entelemetry . api . metrics . Meter Ċ import Ġkotlinx . coroutines .* Ċ import Ġmu . Kotlin Logging Ċ import Ġorg . opend c . compute . api .* Ċ import Ġorg . opend c . compute . service . Compute Service Ċ import Ġorg . opend c . compute . service . driver . Host Ċ import Ġorg . opend c . compute . service . driver . Host Listener Ċ import Ġorg . opend c . compute . service . driver . Host State Ċ import Ġorg . opend c . compute . service . scheduler . Compute Scheduler Ċ import Ġorg . opend c . utils . Timer Scheduler Ċ import Ġjava . time . Clock Ċ import Ġjava . util .* Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . math . max Ċ Ċ /** Ċ Ġ* ĠInternal Ġimplementation Ġof Ġthe ĠOpen DC ĠCompute Ġservice . Ċ Ġ* Ċ Ġ* Ġ@ param Ġcontext ĠThe Ġ[ Coroutine Context ] Ġto Ġuse . Ċ Ġ* Ġ@ param Ġclock ĠThe Ġclock Ġinstance Ġto Ġkeep Ġtrack Ġof Ġtime . Ċ Ġ*/ Ċ internal Ġclass ĠCompute ServiceImpl ( ĊĠĠĠ Ġprivate Ġval Ġcontext : ĠCor outine Context , ĊĠĠĠ Ġprivate Ġval Ġclock : ĠClock , ĊĠĠĠ Ġprivate Ġval Ġmeter : ĠMeter , ĊĠĠĠ Ġprivate Ġval Ġscheduler : ĠCompute Scheduler , ĊĠĠĠ Ġprivate Ġval Ġscheduling Quantum : ĠLong Ċ ) Ġ: ĠCompute Service , ĠHost Listener Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Coroutine Scope ] Ġof Ġthe Ġservice Ġbounded Ġby Ġthe Ġlifecycle Ġof Ġthe Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġscope Ġ= ĠCor outine Scope ( context Ġ+ ĠJob ()) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġlogger Ġinstance Ġof Ġthis Ġserver . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Random ] Ġinstance Ġused Ġto Ġgenerate Ġunique Ġidentifiers Ġfor Ġthe Ġobjects . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġrandom Ġ= ĠRandom ( 0 ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġmapping Ġfrom Ġhost Ġto Ġhost Ġview . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġhost To View Ġ= Ġmutable Map Of < Host , ĠHost View >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġavailable Ġhyper vis ors . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġavailable Hosts : ĠMutable Set < Host View > Ġ= Ġmutable Set Of () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġservers Ġthat Ġshould Ġbe Ġlaunched Ġby Ġthe Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġqueue : ĠDe que < Scheduling Request > Ġ= ĠArray Deque () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġactive Ġservers Ġin Ġthe Ġsystem . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġactive Servers : ĠMutable Map < Server , ĠHost > Ġ= Ġmutable Map Of () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġregistered Ġfl avors Ġfor Ġthis Ġcompute Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġval Ġfl avors Ġ= Ġmutable Map Of < UUID , ĠInternal Flavor >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġregistered Ġimages Ġfor Ġthis Ġcompute Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġval Ġimages Ġ= Ġmutable Map Of < UUID , ĠInternal Image >() ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġregistered Ġservers Ġfor Ġthis Ġcompute Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġservers Ġ= Ġmutable Map Of < UUID , ĠInternal Server >() ĊĊĠĠĠ Ġprivate Ġvar Ġmax Co res Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġvar Ġmax Memory Ġ= Ġ 0 L ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġservers Ġthat Ġhave Ġbeen Ġsubmitted Ġto Ġthe Ġservice Ġfor Ġprovisioning . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ submitted Servers Ġ= Ġmeter . long Counter Builder (" servers . submitted ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġstart Ġrequests ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġservers Ġthat Ġfailed Ġto Ġbe Ġscheduled . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ un scheduled Servers Ġ= Ġmeter . long Counter Builder (" servers . un scheduled ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġun scheduled Ġservers ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġservers Ġthat Ġare Ġwaiting Ġto Ġbe Ġprovision ed . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ waiting Servers Ġ= Ġmeter . long UpDown Counter Builder (" servers . waiting ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġservers Ġwaiting Ġto Ġbe Ġprovision ed ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġservers Ġthat Ġare Ġwaiting Ġto Ġbe Ġprovision ed . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ running Servers Ġ= Ġmeter . long UpDown Counter Builder (" servers . active ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġservers Ġcurrently Ġrunning ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġservers Ġthat Ġhave Ġfinished Ġrunning . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ finished Servers Ġ= Ġmeter . long Counter Builder (" servers . finished ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġservers Ġthat Ġfinished Ġrunning ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġhosts Ġregistered Ġat Ġthe Ġcompute Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ host Count Ġ= Ġmeter . long UpDown Counter Builder (" hosts . total ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġhosts ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġnumber Ġof Ġavailable Ġhosts Ġregistered Ġat Ġthe Ġcompute Ġservice . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġ_ available Host Count Ġ= Ġmeter . long UpDown Counter Builder (" hosts . available ") ĊĠĠĠĠĠĠĠ Ġ. setDescription (" Number Ġof Ġavailable Ġhosts ") ĊĠĠĠĠĠĠĠ Ġ. set Unit (" 1 ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠThe Ġ[ Timer Scheduler ] Ġto Ġuse Ġfor Ġscheduling Ġthe Ġscheduler Ġcycles . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġtimer Scheduler : ĠTimer Scheduler < Unit > Ġ= ĠTimer Scheduler ( scope . coroutine Context , Ġclock ) ĊĊĠĠĠ Ġoverride Ġval Ġhosts : ĠSet < Host > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġhost To View . keys ĊĊĠĠĠ Ġoverride Ġval Ġhost Count : ĠInt ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġhost To View . size ĊĊĠĠĠ Ġoverride Ġfun Ġnew Client (): ĠCompute Client Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck ( scope . isActive ) Ġ{ Ġ" Service Ġis Ġalready Ġclosed " Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġobject Ġ: ĠCompute Client Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġvar Ġis Closed : ĠBoolean Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġquery Fl avors (): ĠList < Flavor > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfl avors . values . map Ġ{ ĠClient Flavor ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind Flavor ( id : ĠUUID ): ĠFl avor ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfl avors [ id ]?. let Ġ{ ĠClient Flavor ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġnew Flavor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcpu Count : ĠInt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmemory Size : ĠLong , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlabels : ĠMap < String , ĠString >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeta : ĠMap < String , ĠAny > ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠFl avor Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuid Ġ= ĠUUID ( clock . millis (), Ġrandom . next Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflavor Ġ= ĠInternal Flavor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Compute ServiceImpl , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcpu Count , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmemory Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlabels , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeta ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfl avors [ uid ] Ġ= Ġflavor ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠClient Flavor ( flavor ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġquery Images (): ĠList < Image > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġimages . values . map Ġ{ ĠClient Image ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind Image ( id : ĠUUID ): ĠImage ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġimages [ id ]?. let Ġ{ ĠClient Image ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġnew Image ( name : ĠString , Ġlabels : ĠMap < String , ĠString >, Ġmeta : ĠMap < String , ĠAny >): ĠImage Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuid Ġ= ĠUUID ( clock . millis (), Ġrandom . next Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimage Ġ= ĠInternal Image ( this @ Compute ServiceImpl , Ġuid , Ġname , Ġlabels , Ġmeta ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimages [ uid ] Ġ= Ġimage ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠClient Image ( image ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġnew Server ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġimage : ĠImage , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflavor : ĠFl avor , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlabels : ĠMap < String , ĠString >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeta : ĠMap < String , ĠAny >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstart : ĠBoolean ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ): ĠServer Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuid Ġ= ĠUUID ( clock . millis (), Ġrandom . next Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġserver Ġ= ĠInternal Server ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis @ Compute ServiceImpl , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuid , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( fl avors [ flavor . uid ]) Ġ{ Ġ" Unknown Ġflavor " Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( images [ image . uid ]) Ġ{ Ġ" Unknown Ġimage " Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlabels . to Mutable Map (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmeta . to Mutable Map () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġservers [ uid ] Ġ= Ġserver ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( start ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserver . start () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠClient Server ( server ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind Server ( id : ĠUUID ): ĠServer ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġservers [ id ]?. let Ġ{ ĠClient Server ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġquery Servers (): ĠList < Server > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is Closed ) Ġ{ Ġ" Client Ġis Ġalready Ġclosed " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġservers . values . map Ġ{ ĠClient Server ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Closed Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Compute Client " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġadd Host ( host : ĠHost ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġhost Ġis Ġalready Ġknown ĊĠĠĠĠĠĠĠ Ġif Ġ( host Ġin Ġhost To View ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġhv Ġ= ĠHost View ( host ) ĊĠĠĠĠĠĠĠ Ġmax Co res Ġ= Ġmax ( max Co res , Ġhost . model . cpu Count ) ĊĠĠĠĠĠĠĠ Ġmax Memory Ġ= Ġmax ( max Memory , Ġhost . model . memory Size ) ĊĠĠĠĠĠĠĠ Ġhost To View [ host ] Ġ= Ġhv ĊĊĠĠĠĠĠĠĠ Ġif Ġ( host . state Ġ== ĠHost State . UP ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ available Host Count . add ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġavailable Hosts Ġ+= Ġhv ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġscheduler . add Host ( hv ) ĊĠĠĠĠĠĠĠ Ġ_ host Count . add ( 1 ) ĊĠĠĠĠĠĠĠ Ġhost . addListener ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġremove Host ( host : ĠHost ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġview Ġ= Ġhost To View . remove ( host ) ĊĠĠĠĠĠĠĠ Ġif Ġ( view Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( available Hosts . remove ( view )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ available Host Count . add (- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscheduler . remove Host ( view ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhost . remove Listener ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ host Count . add (- 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ Ġscope . cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġschedule ( server : ĠInternal Server ): ĠS cheduling Request Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Enqueue ing Ġserver Ġ${ server . uid } Ġto Ġbe Ġassigned Ġto Ġhost ." Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠS cheduling Request ( server ) ĊĠĠĠĠĠĠĠ Ġqueue . add ( request ) ĊĠĠĠĠĠĠĠ Ġ_ submitted Servers . add ( 1 ) ĊĠĠĠĠĠĠĠ Ġ_ waiting Servers . add ( 1 ) ĊĠĠĠĠĠĠĠ Ġrequest Scheduling Cycle () ĊĠĠĠĠĠĠĠ Ġreturn Ġrequest ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdelete ( flavor : ĠInternal Flavor ) Ġ{ ĊĠĠĠĠĠĠĠ Ġfl avors . remove ( flavor . uid ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdelete ( image : ĠInternal Image ) Ġ{ ĊĠĠĠĠĠĠĠ Ġimages . remove ( image . uid ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdelete ( server : ĠInternal Server ) Ġ{ ĊĠĠĠĠĠĠĠ Ġservers . remove ( server . uid ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIndic ate Ġthat Ġa Ġnew Ġscheduling Ġcycle Ġis Ġneeded Ġdue Ġto Ġa Ġchange Ġto Ġthe Ġservice 's Ġstate . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġrequest Scheduling Cycle () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠB ail Ġout Ġin Ġcase Ġwe Ġhave Ġalready Ġrequested Ġa Ġnew Ġcycle Ġor Ġthe Ġqueue Ġis Ġempty . ĊĠĠĠĠĠĠĠ Ġif Ġ( timer Scheduler . is Timer Active ( Unit ) Ġ|| Ġqueue . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġassume Ġthat Ġthe Ġprovision er Ġruns Ġat Ġa Ġfixed Ġslot Ġevery Ġtime Ġquantum Ġ( e . g Ġt = 0 , Ġt = 6 0 , Ġt = 1 2 0 ). ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġimportant Ġbecause Ġthe Ġslices Ġof Ġthe ĠVMs Ġneed Ġto Ġbe Ġaligned . ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġcalculate Ġhere Ġthe Ġdelay Ġuntil Ġthe Ġnext Ġscheduling Ġslot . ĊĠĠĠĠĠĠĠ Ġval Ġdelay Ġ= Ġscheduling Quantum Ġ- Ġ( clock . millis () Ġ% Ġscheduling Quantum ) ĊĊĠĠĠĠĠĠĠ Ġtimer Scheduler . start Single Timer ( Unit , Ġdelay ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Schedule () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRun Ġa Ġsingle Ġscheduling Ġiteration . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġdo Schedule () Ġ{ ĊĠĠĠĠĠĠĠ Ġwhile Ġ( queue . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= Ġqueue . peek () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( request . is Cancelled ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . poll () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ waiting Servers . add (- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġserver Ġ= Ġrequest . server ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhv Ġ= Ġscheduler . select ( request . server ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hv Ġ== Ġnull Ġ|| Ġ! hv . host . can Fit ( server )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . trace Ġ{ Ġ" Server Ġ$ server Ġselected Ġfor Ġscheduling Ġbut Ġno Ġcapacity Ġavailable Ġfor Ġit Ġat Ġthe Ġmoment " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( server . flavor . memory Size Ġ> Ġmax Memory Ġ|| Ġserver . flavor . cpu Count Ġ> Ġmax Co res ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove Ġthe Ġincoming Ġimage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . poll () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ waiting Servers . add (- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ un scheduled Servers . add ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn (" Failed Ġto Ġspawn Ġ$ server : Ġdoes Ġnot Ġfit Ġ[ ${ clock . millis ()} ]") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserver . state Ġ= ĠServer State . ERROR ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhost Ġ= Ġhv . host ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRemove Ġrequest Ġfrom Ġqueue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġqueue . poll () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ waiting Servers . add (- 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" Assigned Ġserver Ġ$ server Ġto Ġhost Ġ$ host ." Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSpec ul atively Ġupdate Ġthe Ġhyper visor Ġview Ġinformation Ġto Ġprevent Ġother Ġimages Ġin Ġthe Ġqueue Ġfrom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdec iding Ġon Ġstale Ġvalues . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhv . instance Count ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhv . provision ed Co res Ġ+= Ġserver . flavor . cpu Count ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhv . available Memory Ġ-= Ġserver . flavor . memory Size Ġ// ĠXXX ĠTemporary Ġhack ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġscope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġserver . host Ġ= Ġhost ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhost . spawn ( server ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactive Servers [ server ] Ġ= Ġhost ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error (" Failed Ġto Ġdeploy ĠVM ", Ġe ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . instance Count -- ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . provision ed Co res Ġ-= Ġserver . flavor . cpu Count ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . available Memory Ġ+= Ġserver . flavor . memory Size ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġrequest Ġto Ġschedule Ġan Ġ[ Internal Server ] Ġonto Ġone Ġof Ġthe Ġ[ Host ] s . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġdata Ġclass ĠS cheduling Request ( val Ġserver : ĠInternal Server ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠA Ġflag Ġto Ġindicate Ġthat Ġthe Ġrequest Ġis Ġcancelled . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġvar Ġis Cancelled : ĠBoolean Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon StateChanged ( host : ĠHost , ĠnewState : ĠHost State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( newState ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHost State . UP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ"[ ${ clock . millis ()} ] ĠHost Ġ${ host . uid } Ġstate Ġchanged : Ġ$ newState " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhv Ġ= Ġhost To View [ host ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hv Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCor ner Ġcase Ġfor Ġwhen Ġthe Ġhyper visor Ġalready Ġexists ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġavailable Hosts Ġ+= Ġhv ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ available Host Count . add ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe - schedule Ġon Ġthe Ġnew Ġmachine ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Scheduling Cycle () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHost State . DOWN Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ"[ ${ clock . millis ()} ] ĠHost Ġ${ host . uid } Ġstate Ġchanged : Ġ$ newState " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhv Ġ= Ġhost To View [ host ] Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġavailable Hosts Ġ-= Ġhv ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ available Host Count . add (- 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Scheduling Cycle () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon StateChanged ( host : ĠHost , Ġserver : ĠServer , ĠnewState : ĠServer State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( server Ġis ĠInternal Server ) Ġ{ Ġ" Invalid Ġserver Ġtype Ġpassed Ġto Ġservice " Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( server . host Ġ!= Ġhost ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġcan Ġhappen Ġwhen Ġa Ġserver Ġis Ġre scheduled Ġand Ġstarted Ġon Ġanother Ġmachine , Ġwhile Ġbeing Ġdeleted Ġfrom ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġold Ġmachine . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġserver . state Ġ= ĠnewState ĊĊĠĠĠĠĠĠĠ Ġif Ġ( newState Ġ== ĠServer State . RUNNING ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ running Servers . add ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( newState Ġ== ĠServer State . TERMIN ATED Ġ|| ĠnewState Ġ== ĠServer State . DELETED ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ"[ ${ clock . millis ()} ] ĠServer Ġ${ server . uid } Ġ${ server . name } Ġ${ server . flavor } Ġfinished ." Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġactive Servers Ġ-= Ġserver ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ running Servers . add (- 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ_ finished Servers . add ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhv Ġ= Ġhost To View [ host ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( hv Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . provision ed Co res Ġ-= Ġserver . flavor . cpu Count ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . instance Count -- ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhv . available Memory Ġ+= Ġserver . flavor . memory Size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . error Ġ{ Ġ" Unknown Ġhost Ġ$ host " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġto Ġre schedule Ġif Ġneeded ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Scheduling Cycle () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ