Important Notes: * EdgeTask class name is updated as TaskProperty. You may need to modify your existing application's source code if you use EdgeTask class in your application.
388 lines
14 KiB
Java
388 lines
14 KiB
Java
/*
|
|
* Title: EdgeCloudSim - Mobile Device Manager
|
|
*
|
|
* Description:
|
|
* DefaultMobileDeviceManager is responsible for submitting the tasks to the related
|
|
* device by using the Edge Orchestrator. It also takes proper actions
|
|
* when the execution of the tasks are finished.
|
|
* By default, DefaultMobileDeviceManager sends tasks to the edge servers or
|
|
* cloud servers. If you want to use different topology, for example
|
|
* MAN edge server, you should modify the flow defined in this class.
|
|
*
|
|
* Licence: GPL - http://www.gnu.org/copyleft/gpl.html
|
|
* Copyright (c) 2017, Bogazici University, Istanbul, Turkey
|
|
*/
|
|
|
|
package edu.boun.edgecloudsim.applications.sample_app4;
|
|
|
|
import org.cloudbus.cloudsim.UtilizationModel;
|
|
import org.cloudbus.cloudsim.UtilizationModelFull;
|
|
import org.cloudbus.cloudsim.Vm;
|
|
import org.cloudbus.cloudsim.core.CloudSim;
|
|
import org.cloudbus.cloudsim.core.CloudSimTags;
|
|
import org.cloudbus.cloudsim.core.SimEvent;
|
|
|
|
import edu.boun.edgecloudsim.core.SimManager;
|
|
import edu.boun.edgecloudsim.core.SimSettings;
|
|
import edu.boun.edgecloudsim.core.SimSettings.NETWORK_DELAY_TYPES;
|
|
import edu.boun.edgecloudsim.edge_client.CpuUtilizationModel_Custom;
|
|
import edu.boun.edgecloudsim.edge_client.MobileDeviceManager;
|
|
import edu.boun.edgecloudsim.edge_client.Task;
|
|
import edu.boun.edgecloudsim.edge_server.EdgeHost;
|
|
import edu.boun.edgecloudsim.edge_server.EdgeVM;
|
|
import edu.boun.edgecloudsim.network.NetworkModel;
|
|
import edu.boun.edgecloudsim.utils.TaskProperty;
|
|
import edu.boun.edgecloudsim.utils.Location;
|
|
import edu.boun.edgecloudsim.utils.SimLogger;
|
|
|
|
public class FuzzyMobileDeviceManager extends MobileDeviceManager {
|
|
private static final int BASE = 100000; //start from base in order not to conflict cloudsim tag!
|
|
|
|
private static final int UPDATE_MM1_QUEUE_MODEL = BASE + 1;
|
|
private static final int REQUEST_RECEIVED_BY_CLOUD = BASE + 2;
|
|
private static final int REQUEST_RECEIVED_BY_EDGE_DEVICE = BASE + 3;
|
|
private static final int REQUEST_RECEIVED_BY_REMOTE_EDGE_DEVICE = BASE + 4;
|
|
private static final int REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR = BASE + 5;
|
|
private static final int RESPONSE_RECEIVED_BY_MOBILE_DEVICE = BASE + 6;
|
|
private static final int RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE = BASE + 7;
|
|
|
|
private static final double MM1_QUEUE_MODEL_UPDATE_INTEVAL = 5; //seconds
|
|
|
|
private int taskIdCounter=0;
|
|
|
|
public FuzzyMobileDeviceManager() throws Exception{
|
|
}
|
|
|
|
@Override
|
|
public void initialize() {
|
|
}
|
|
|
|
@Override
|
|
public UtilizationModel getCpuUtilizationModel() {
|
|
return new CpuUtilizationModel_Custom();
|
|
}
|
|
|
|
@Override
|
|
public void startEntity() {
|
|
super.startEntity();
|
|
schedule(getId(), SimSettings.CLIENT_ACTIVITY_START_TIME +
|
|
MM1_QUEUE_MODEL_UPDATE_INTEVAL, UPDATE_MM1_QUEUE_MODEL);
|
|
}
|
|
|
|
/**
|
|
* Submit cloudlets to the created VMs.
|
|
*
|
|
* @pre $none
|
|
* @post $none
|
|
*/
|
|
protected void submitCloudlets() {
|
|
//do nothing!
|
|
}
|
|
|
|
/**
|
|
* Process a cloudlet return event.
|
|
*
|
|
* @param ev a SimEvent object
|
|
* @pre ev != $null
|
|
* @post $none
|
|
*/
|
|
protected void processCloudletReturn(SimEvent ev) {
|
|
NetworkModel networkModel = SimManager.getInstance().getNetworkModel();
|
|
Task task = (Task) ev.getData();
|
|
|
|
SimLogger.getInstance().taskExecuted(task.getCloudletId());
|
|
|
|
if(task.getAssociatedDatacenterId() == SimSettings.CLOUD_DATACENTER_ID){
|
|
//SimLogger.printLine(CloudSim.clock() + ": " + getName() + ": task #" + task.getCloudletId() + " received from cloud");
|
|
double WanDelay = networkModel.getDownloadDelay(SimSettings.CLOUD_DATACENTER_ID, task.getMobileDeviceId(), task);
|
|
if(WanDelay > 0)
|
|
{
|
|
Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()+WanDelay);
|
|
if(task.getSubmittedLocation().getServingWlanId() == currentLocation.getServingWlanId())
|
|
{
|
|
networkModel.downloadStarted(task.getSubmittedLocation(), SimSettings.CLOUD_DATACENTER_ID);
|
|
SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), WanDelay, NETWORK_DELAY_TYPES.WAN_DELAY);
|
|
schedule(getId(), WanDelay, RESPONSE_RECEIVED_BY_MOBILE_DEVICE, task);
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToMobility(task.getCloudletId(), CloudSim.clock());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), NETWORK_DELAY_TYPES.WAN_DELAY);
|
|
}
|
|
}
|
|
else{
|
|
int nextEvent = RESPONSE_RECEIVED_BY_MOBILE_DEVICE;
|
|
int nextDeviceForNetworkModel = SimSettings.GENERIC_EDGE_DEVICE_ID;
|
|
NETWORK_DELAY_TYPES delayType = NETWORK_DELAY_TYPES.WLAN_DELAY;
|
|
double delay = networkModel.getDownloadDelay(task.getAssociatedHostId(), task.getMobileDeviceId(), task);
|
|
|
|
EdgeHost host = (EdgeHost)(SimManager.
|
|
getInstance().
|
|
getEdgeServerManager().
|
|
getDatacenterList().get(task.getAssociatedHostId()).
|
|
getHostList().get(0));
|
|
|
|
//if neighbor edge device is selected
|
|
if(host.getLocation().getServingWlanId() != task.getSubmittedLocation().getServingWlanId())
|
|
{
|
|
delay = networkModel.getDownloadDelay(SimSettings.GENERIC_EDGE_DEVICE_ID, SimSettings.GENERIC_EDGE_DEVICE_ID, task);
|
|
nextEvent = RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE;
|
|
nextDeviceForNetworkModel = SimSettings.GENERIC_EDGE_DEVICE_ID + 1;
|
|
delayType = NETWORK_DELAY_TYPES.MAN_DELAY;
|
|
}
|
|
|
|
if(delay > 0)
|
|
{
|
|
Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()+delay);
|
|
if(task.getSubmittedLocation().getServingWlanId() == currentLocation.getServingWlanId())
|
|
{
|
|
networkModel.downloadStarted(currentLocation, nextDeviceForNetworkModel);
|
|
SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), delay, delayType);
|
|
|
|
schedule(getId(), delay, nextEvent, task);
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToMobility(task.getCloudletId(), CloudSim.clock());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), delayType);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void processOtherEvent(SimEvent ev) {
|
|
if (ev == null) {
|
|
SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null! Terminating simulation...");
|
|
System.exit(0);
|
|
return;
|
|
}
|
|
|
|
NetworkModel networkModel = SimManager.getInstance().getNetworkModel();
|
|
|
|
switch (ev.getTag()) {
|
|
case UPDATE_MM1_QUEUE_MODEL:
|
|
{
|
|
((FuzzyExperimentalNetworkModel)networkModel).updateMM1QueeuModel();
|
|
schedule(getId(), MM1_QUEUE_MODEL_UPDATE_INTEVAL, UPDATE_MM1_QUEUE_MODEL);
|
|
|
|
break;
|
|
}
|
|
case REQUEST_RECEIVED_BY_CLOUD:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
networkModel.uploadFinished(task.getSubmittedLocation(), SimSettings.CLOUD_DATACENTER_ID);
|
|
submitTaskToVm(task, SimSettings.VM_TYPES.CLOUD_VM);
|
|
break;
|
|
}
|
|
case REQUEST_RECEIVED_BY_EDGE_DEVICE:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
networkModel.uploadFinished(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID);
|
|
submitTaskToVm(task, SimSettings.VM_TYPES.EDGE_VM);
|
|
break;
|
|
}
|
|
case REQUEST_RECEIVED_BY_REMOTE_EDGE_DEVICE:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
networkModel.uploadFinished(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID+1);
|
|
submitTaskToVm(task, SimSettings.VM_TYPES.EDGE_VM);
|
|
|
|
break;
|
|
}
|
|
case REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
networkModel.uploadFinished(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID);
|
|
|
|
double manDelay = networkModel.getUploadDelay(SimSettings.GENERIC_EDGE_DEVICE_ID, SimSettings.GENERIC_EDGE_DEVICE_ID, task);
|
|
if(manDelay>0){
|
|
networkModel.uploadStarted(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID+1);
|
|
SimLogger.getInstance().setUploadDelay(task.getCloudletId(), manDelay, NETWORK_DELAY_TYPES.MAN_DELAY);
|
|
schedule(getId(), manDelay, REQUEST_RECEIVED_BY_REMOTE_EDGE_DEVICE, task);
|
|
}
|
|
else
|
|
{
|
|
//SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM");
|
|
SimLogger.getInstance().rejectedDueToBandwidth(
|
|
task.getCloudletId(),
|
|
CloudSim.clock(),
|
|
SimSettings.VM_TYPES.EDGE_VM.ordinal(),
|
|
NETWORK_DELAY_TYPES.MAN_DELAY);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RESPONSE_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_MOBILE_DEVICE:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
networkModel.downloadFinished(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID+1);
|
|
|
|
//SimLogger.printLine(CloudSim.clock() + ": " + getName() + ": task #" + task.getCloudletId() + " received from edge");
|
|
double delay = networkModel.getDownloadDelay(task.getAssociatedHostId(), task.getMobileDeviceId(), task);
|
|
|
|
if(delay > 0)
|
|
{
|
|
Location currentLocation = SimManager.getInstance().getMobilityModel().getLocation(task.getMobileDeviceId(),CloudSim.clock()+delay);
|
|
if(task.getSubmittedLocation().getServingWlanId() == currentLocation.getServingWlanId())
|
|
{
|
|
networkModel.downloadStarted(currentLocation, SimSettings.GENERIC_EDGE_DEVICE_ID);
|
|
SimLogger.getInstance().setDownloadDelay(task.getCloudletId(), delay, NETWORK_DELAY_TYPES.WLAN_DELAY);
|
|
schedule(getId(), delay, RESPONSE_RECEIVED_BY_MOBILE_DEVICE, task);
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToMobility(task.getCloudletId(), CloudSim.clock());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SimLogger.getInstance().failedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), NETWORK_DELAY_TYPES.WLAN_DELAY);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case RESPONSE_RECEIVED_BY_MOBILE_DEVICE:
|
|
{
|
|
Task task = (Task) ev.getData();
|
|
|
|
if(task.getAssociatedDatacenterId() == SimSettings.CLOUD_DATACENTER_ID)
|
|
networkModel.downloadFinished(task.getSubmittedLocation(), SimSettings.CLOUD_DATACENTER_ID);
|
|
else if(task.getAssociatedDatacenterId() != SimSettings.MOBILE_DATACENTER_ID)
|
|
networkModel.downloadFinished(task.getSubmittedLocation(), SimSettings.GENERIC_EDGE_DEVICE_ID);
|
|
|
|
SimLogger.getInstance().taskEnded(task.getCloudletId(), CloudSim.clock());
|
|
break;
|
|
}
|
|
default:
|
|
SimLogger.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker. Terminating simulation...");
|
|
System.exit(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void submitTask(TaskProperty edgeTask) {
|
|
int vmType=0;
|
|
int nextEvent=0;
|
|
int nextDeviceForNetworkModel;
|
|
NETWORK_DELAY_TYPES delayType;
|
|
double delay=0;
|
|
|
|
NetworkModel networkModel = SimManager.getInstance().getNetworkModel();
|
|
|
|
//create a task
|
|
Task task = createTask(edgeTask);
|
|
|
|
Location currentLocation = SimManager.getInstance().getMobilityModel().
|
|
getLocation(task.getMobileDeviceId(), CloudSim.clock());
|
|
|
|
//set location of the mobile device which generates this task
|
|
task.setSubmittedLocation(currentLocation);
|
|
|
|
//add related task to log list
|
|
SimLogger.getInstance().addLog(task.getCloudletId(),
|
|
task.getTaskType(),
|
|
(int)task.getCloudletLength(),
|
|
(int)task.getCloudletFileSize(),
|
|
(int)task.getCloudletOutputSize());
|
|
|
|
int nextHopId = SimManager.getInstance().getEdgeOrchestrator().getDeviceToOffload(task);
|
|
|
|
if(nextHopId == SimSettings.CLOUD_DATACENTER_ID){
|
|
delay = networkModel.getUploadDelay(task.getMobileDeviceId(), SimSettings.CLOUD_DATACENTER_ID, task);
|
|
vmType = SimSettings.VM_TYPES.CLOUD_VM.ordinal();
|
|
nextEvent = REQUEST_RECEIVED_BY_CLOUD;
|
|
delayType = NETWORK_DELAY_TYPES.WAN_DELAY;
|
|
nextDeviceForNetworkModel = SimSettings.CLOUD_DATACENTER_ID;
|
|
}
|
|
else {
|
|
delay = networkModel.getUploadDelay(task.getMobileDeviceId(), SimSettings.GENERIC_EDGE_DEVICE_ID, task);
|
|
vmType = SimSettings.VM_TYPES.EDGE_VM.ordinal();
|
|
nextEvent = REQUEST_RECEIVED_BY_EDGE_DEVICE;
|
|
delayType = NETWORK_DELAY_TYPES.WLAN_DELAY;
|
|
nextDeviceForNetworkModel = SimSettings.GENERIC_EDGE_DEVICE_ID;
|
|
}
|
|
|
|
if(delay>0){
|
|
|
|
Vm selectedVM = SimManager.getInstance().getEdgeOrchestrator().getVmToOffload(task, nextHopId);
|
|
|
|
if(selectedVM != null){
|
|
//set related host id
|
|
task.setAssociatedDatacenterId(nextHopId);
|
|
|
|
//set related host id
|
|
task.setAssociatedHostId(selectedVM.getHost().getId());
|
|
|
|
//set related vm id
|
|
task.setAssociatedVmId(selectedVM.getId());
|
|
|
|
//bind task to related VM
|
|
getCloudletList().add(task);
|
|
bindCloudletToVm(task.getCloudletId(), selectedVM.getId());
|
|
|
|
if(selectedVM instanceof EdgeVM){
|
|
EdgeHost host = (EdgeHost)(selectedVM.getHost());
|
|
|
|
//if neighbor edge device is selected
|
|
if(host.getLocation().getServingWlanId() != task.getSubmittedLocation().getServingWlanId()){
|
|
nextEvent = REQUEST_RECEIVED_BY_EDGE_DEVICE_TO_RELAY_NEIGHBOR;
|
|
}
|
|
}
|
|
networkModel.uploadStarted(currentLocation, nextDeviceForNetworkModel);
|
|
|
|
SimLogger.getInstance().taskStarted(task.getCloudletId(), CloudSim.clock());
|
|
SimLogger.getInstance().setUploadDelay(task.getCloudletId(), delay, delayType);
|
|
|
|
schedule(getId(), delay, nextEvent, task);
|
|
}
|
|
else{
|
|
//SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM");
|
|
SimLogger.getInstance().rejectedDueToVMCapacity(task.getCloudletId(), CloudSim.clock(), vmType);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//SimLogger.printLine("Task #" + task.getCloudletId() + " cannot assign to any VM");
|
|
SimLogger.getInstance().rejectedDueToBandwidth(task.getCloudletId(), CloudSim.clock(), vmType, delayType);
|
|
}
|
|
}
|
|
|
|
private void submitTaskToVm(Task task, SimSettings.VM_TYPES vmType) {
|
|
//SimLogger.printLine(CloudSim.clock() + ": Cloudlet#" + task.getCloudletId() + " is submitted to VM#" + task.getVmId());
|
|
schedule(getVmsToDatacentersMap().get(task.getVmId()), 0, CloudSimTags.CLOUDLET_SUBMIT, task);
|
|
|
|
SimLogger.getInstance().taskAssigned(task.getCloudletId(),
|
|
task.getAssociatedDatacenterId(),
|
|
task.getAssociatedHostId(),
|
|
task.getAssociatedVmId(),
|
|
vmType.ordinal());
|
|
}
|
|
|
|
private Task createTask(TaskProperty edgeTask){
|
|
UtilizationModel utilizationModel = new UtilizationModelFull(); /*UtilizationModelStochastic*/
|
|
UtilizationModel utilizationModelCPU = getCpuUtilizationModel();
|
|
|
|
Task task = new Task(edgeTask.getMobileDeviceId(), ++taskIdCounter,
|
|
edgeTask.getLength(), edgeTask.getPesNumber(),
|
|
edgeTask.getInputFileSize(), edgeTask.getOutputFileSize(),
|
|
utilizationModelCPU, utilizationModel, utilizationModel);
|
|
|
|
//set the owner of this task
|
|
task.setUserId(this.getId());
|
|
task.setTaskType(edgeTask.getTaskType());
|
|
|
|
if (utilizationModelCPU instanceof CpuUtilizationModel_Custom) {
|
|
((CpuUtilizationModel_Custom)utilizationModelCPU).setTask(task);
|
|
}
|
|
|
|
return task;
|
|
}
|
|
}
|