## 4 An Architecture for Edge-Fog-Cloud Offloading
```
1:Input: Job pool \(\mathcal{J}=\{j_{1},j_{2},\ldots,j_{n}\}\) where \(n>0\), delegator \(d\), edge workers \(\mathcal{W}_{e}\), fog workers \(\mathcal{W}_{f}\), cloud workers \(\mathcal{W}_{c}\)
2:Output: Completed jobs \(\mathcal{J}c\), initially \(\mathcal{J}c=\emptyset\)
3: Initialise \(\mathcal{J}\) to ensure \(\mathcal{J}\
eq\emptyset\)
4: Start delegator's job consumer thread \(T_{d\_com}\)
5: Start \(T_{d\_comEdge}\) for edge workers
6: Start \(T_{d\_comFog}\) for fog workers
7: Start \(T_{d\_comCloud}\) for cloud workers
8:while\(\mathcal{J}\setminus\mathcal{J}c\
eq\emptyset\)do
9:\(T_{d\_com}\) consume \(\mathcal{J}\)
10: Update \(\mathcal{J}c\) with results from \(T_{d\_com}\)
11:endwhile
```  
**Algorithm 1** Delegator's main thread  
```
1:Input:\(\mathcal{J}=\{j_{1},j_{2},\ldots,j_{n}\}\), \(n>0\), \(d\), \(\mathcal{W}_{e}\), \(\mathcal{W}_{f}\), \(\mathcal{W}_{c}\)
2:Output:\(\mathcal{J}c\)
3: Let \(\mathcal{W}=\mathcal{W}_{e}\cup\mathcal{W}_{f}\cup\mathcal{W}_{c}\)
4:while\(\mathcal{J}\setminus\mathcal{J}c\
eq\emptyset\)do
5:if\(\mathcal{J}\
eq\emptyset\)then
6: Consume \(\mathcal{J}\)
7: Update \(\mathcal{J}c\)
8:else Steal from a worker in \(\mathcal{W}\)\(\triangleright\) Traverse workers in connection order
9:endif
10:endwhile
```  
**Algorithm 2** Delegator's job consumer thread  
```
1:Input: Worker type \(W\in\{\mathcal{W}_{e},\mathcal{W}_{f},\mathcal{W}_{c}\}\); Communication protocol \(Comm\)
2:Output: Established connections stored in a ConcurrentHashMap \(\mathcal{M}\)
3: Initialise \(\mathcal{M}\) as an empty ConcurrentHashMap
4:while resources are periodically discovered for \(W\)do
5:for each worker \(w\in W\)do
6: Open socket connection using protocol \(Comm\)
7: Create a ClientSocketThread instance for \(w\)
8:\(\mathcal{M}[w]\leftarrow\) ClientSocketThread instance
9: Start a communication thread for \(w\)\(\triangleright\) Algorithm 5
10:endfor
11:endwhile
```  
**Algorithm 3** Delegator's periodic resource discovery thread for worker type \(W\)  
```
1:Input: Worker job pool \(\mathcal{J}_{w}\), initially \(\mathcal{J}_{w}=\emptyset\), Stolen jobs \(\mathcal{J}s\), \(d\)
2:Output: Worker's completed jobs \(\mathcal{J}c_{w}\), initially \(\mathcal{J}c_{w}=\emptyset\)
3:Initialise: work_ongoing \(\leftarrow\) true
4:while work_ongoing do
5:if\(\mathcal{J}s\
eq\emptyset\)then
6:\(\mathcal{J}_{w}\leftarrow\mathcal{J}_{w}\cup\mathcal{J}s\)
7:while\(\mathcal{J}_{w}\
eq\emptyset\)do
8: Consume \(\mathcal{J}_{w}\)
9: Update \(\mathcal{J}c_{w}\) and send to \(d\)
10:endwhile
11:else Steal from \(d\)
12:endif
13:endwhile
```  
**Algorithm 4** Worker's main thread  
```
1:Input: Worker job pool \(\mathcal{J}_{w}\), initially \(\mathcal{J}_{w}=\emptyset\), Stolen jobs \(\mathcal{J}s\), \(d\)
2:Output: Worker's completed jobs \(\mathcal{J}c_{w}\), initially \(\mathcal{J}c_{w}=\emptyset\)
3:Initialise: work_ongoing \(\leftarrow\) true
4:while work_ongoing do
5:if\(\mathcal{J}s\
eq\emptyset\)then
6:\(\mathcal{J}_{w}\leftarrow\mathcal{J}_{w}\cup\mathcal{J}s\)
7:while\(\mathcal{J}_{w}\
eq\emptyset\)do
8: Consume \(\mathcal{J}_{w}\)
9: Update \(\mathcal{J}c_{w}\) and send to \(d\)
10:endwhile
11:else Steal from \(d\)
12:endif
13:endwhile
```  
**Algorithm 5** Delegator's main thread
```
1:Input: Worker \(w\), job pool \(\mathcal{J}\), connection map \(\mathcal{M}\)
2:Output: Updated \(\mathcal{J}\), completed results \(\mathcal{J}c\)
3: Retrieve \(w\)'s connection details from \(\mathcal{M}\)
4:Send init_signal to \(w\)
5:whileread \(\
eq\emptyset\)do\(m\gets\)read\(\triangleright\)\(m\): received message
6:if\(m=\) steal_request then
7: Send no_jobs_left if \(\mathcal{J}=\emptyset\), else start victim thread \(T\_{d\_vic}\)
8:else if \(m=\) results then
9:\(\mathcal{J}c\leftarrow\mathcal{J}c\cup\) new results \(\triangleright\) Store results
10:if\(\mathcal{J}\subseteq\mathcal{J}c\)then
11: Execute on_task_completed
12:endif
13:elseif\(m=\) stolen_jobs then
14:\(\mathcal{J}\leftarrow\mathcal{J}\cup\) stolen jobs; start job consumer thread \(T\_{d\_con}\)
15:elseif\(m=\) no_jobs then
16: Mark \(w\) as idle
17:if expired jobs \(\
eq\emptyset\)then
18:\(\mathcal{J}\leftarrow\mathcal{J}\cup\) expired jobs
19:endif
20:elseif\(m=\) worker_heartbeat then
21: Update \(w\)'s status in \(\mathcal{M}\)
22:endif
23:endwhile
```  
**Algorithm 5** Delegator's communication thread for each worker  
Algorithm 5 manages all communication between the worker node and the delegator node.