@@ -40,7 +40,8 @@ type ilpParams struct {
4040 NodeLabels map [string ][]string `json:"node_labels"` // Labels per node
4141 TaskLabels map [string ][]string `json:"task_labels"` // Labels per task
4242
43- ExecTime map [string ]float64 `json:"exectime"` // map[json.dumps((task, node))] = time
43+ ExecTime map [string ]float64 `json:"exectime"` // map[json.dumps((task, node))] = time
44+ InitTime map [string ]float64 `json:"init_time"` // map[json.dumps((task, node))] = time
4445}
4546
4647type taskPlacement map [TaskId ]string
@@ -49,6 +50,7 @@ func initParams() ilpParams {
4950 return ilpParams {
5051 Adj : make (map [string ][]string ),
5152 ExecTime : make (map [string ]float64 ),
53+ InitTime : make (map [string ]float64 ),
5254 OutputSize : make (map [string ]float64 ),
5355 NodeMemory : make (map [string ]float64 ),
5456 Cost : make (map [string ]float64 ),
@@ -63,7 +65,6 @@ func initParams() ilpParams {
6365}
6466
6567const CLOUD = "CLOUD"
66- const LOCAL = "LOCAL"
6768
6869var httpClient = & http.Client {Timeout : 10 * time .Second }
6970
@@ -176,6 +177,8 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
176177
177178 completed := 0
178179
180+ var LOCAL = registration .SelfRegistration .Key
181+
179182 if p == nil || ! r .CanDoOffloading || len (p .ReadyToExecute ) == 0 {
180183 return OffloadingDecision {Offload : false }, nil
181184 }
@@ -295,6 +298,8 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
295298 params .DSBandwidth [CLOUD ] = config .GetFloat (config .OFFLOADING_POLICY_CLOUD_TO_DATA_STORE_BANDWIDTH , dsBandwidth * 10 )
296299 }
297300
301+ localWarmStatus := node .WarmStatus ()
302+
298303 // Execution Times
299304 retrievedMetrics := metrics .GetMetrics ()
300305 for tid , task := range r .W .Tasks {
@@ -305,34 +310,86 @@ func (policy *IlpOffloadingPolicy) Evaluate(r *Request, p *Progress) (Offloading
305310 if ok {
306311 f , _ := function .GetFunction (ft .Func )
307312 for _ , n := range params .EdgeNodes {
308- nodeTimes , found := retrievedMetrics .AvgEdgeExecutionTime [n ]
313+ nId := node.NodeID {Area : registration .SelfRegistration .Area , Key : n }
314+ // Execution Times
315+ nodeTimes , found := retrievedMetrics .AvgEdgeExecutionTime [nId .String ()]
316+ if ! found {
317+ log .Printf ("No data about exec times on %s" , n )
318+ params .ExecTime [tupleKey (string (tid ), n )] = 0.01 // no data: just guessing
319+ } else {
320+ t , found := nodeTimes [f .Name ]
321+ if found {
322+ params .ExecTime [tupleKey (string (tid ), n )] = t
323+ } else {
324+ log .Printf ("No data about exec times of %s on %s" , f .Name , n )
325+ params .ExecTime [tupleKey (string (tid ), n )] = 0.01 // no data: just guessing
326+ }
327+ }
328+
329+ // Init Times
330+ initTimes , found := retrievedMetrics .AvgEdgeInitTime [nId .String ()]
309331 if ! found {
310- params .ExecTime [tupleKey (string (tid ), n )] = 1 // no data: just guessing
332+ // Unknown node
333+ params .InitTime [tupleKey (string (tid ), n )] = 0.01 // no data: just guessing
311334 continue
312335 }
313- t , found := nodeTimes [f .Name ]
314- if found {
315- params .ExecTime [tupleKey (string (tid ), n )] = t
336+
337+ coldStart := false
338+ if n == LOCAL {
339+ warmCount , ok := localWarmStatus [f .Name ]
340+ if ! ok || warmCount < 1 {
341+ coldStart = true
342+ }
316343 } else {
317- params .ExecTime [tupleKey (string (tid ), n )] = 1 // no data: just guessing
344+ warmCount , ok := nearbyServers [n ].AvailableWarmContainers [f .Name ]
345+ if ! ok || warmCount < 1 {
346+ coldStart = true
347+ }
348+ }
349+
350+ if ! coldStart {
351+ params .InitTime [tupleKey (string (tid ), n )] = 0
352+ } else {
353+ t , found := initTimes [f .Name ]
354+ if found {
355+ params .InitTime [tupleKey (string (tid ), n )] = t
356+ } else {
357+ params .InitTime [tupleKey (string (tid ), n )] = 0.01 // no data: just guessing
358+ }
318359 }
319360 }
320361
321362 if len (params .CloudNodes ) > 0 {
322- // Cloud
363+ // Cloud Execution Time
323364 t , found := retrievedMetrics .AvgRemoteExecutionTime [f .Name ]
324365 if found {
325366 params .ExecTime [tupleKey (string (tid ), CLOUD )] = t
326367 } else {
327- params .ExecTime [tupleKey (string (tid ), CLOUD )] = 1 // no data: just guessing
368+ params .ExecTime [tupleKey (string (tid ), CLOUD )] = 0.01 // no data: just guessing
369+ }
370+
371+ // Init Time
372+ coldStart := true // TODO: assuming cold start
373+ if ! coldStart {
374+ params .InitTime [tupleKey (string (tid ), CLOUD )] = 0
375+ } else {
376+ t , found = retrievedMetrics .AvgRemoteInitTime [f .Name ]
377+ if found {
378+ params .InitTime [tupleKey (string (tid ), CLOUD )] = t
379+ } else {
380+ params .InitTime [tupleKey (string (tid ), CLOUD )] = 0.01 // no data: just guessing
381+ }
328382 }
329383 }
330384 } else {
385+ // The task is not a Functiontask
331386 for _ , n := range params .EdgeNodes {
332387 params .ExecTime [tupleKey (string (tid ), n )] = 0.0001
388+ params .InitTime [tupleKey (string (tid ), n )] = 0.0
333389 }
334390 if len (params .CloudNodes ) > 0 {
335391 params .ExecTime [tupleKey (string (tid ), CLOUD )] = 0.0001
392+ params .InitTime [tupleKey (string (tid ), CLOUD )] = 0.0
336393 }
337394 }
338395 }
@@ -438,7 +495,7 @@ func computeDecisionFromPlacement(placement taskPlacement, p *Progress, r *Reque
438495 var remoteNode string
439496 for _ , t := range p .ReadyToExecute {
440497 assignedNode := placement [t ]
441- if assignedNode == LOCAL {
498+ if assignedNode == registration . SelfRegistration . Key {
442499 localExecution = true
443500 break
444501 } else {
0 commit comments