diff --git a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample1.java b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample1.java index 4c1a8ba..84aeb3c 100755 --- a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample1.java +++ b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample1.java @@ -30,18 +30,16 @@ import java.util.ArrayList; import java.util.List; -/** - * A simple example showing how to create a Datacenter with 1 host and a network - * topology, running 1 cloudlet on it. - * There is just one VM with a single PE of 250 MIPS. - * The Cloudlet requires 1 PE and has a length of 40000 MI. - * This way, the Cloudlet will take 160 seconds to finish (40000/250). - * - *
The Cloudlet is not requiring any files from a {@link SanStorage}, - * but since a network topology is defined from the file topology.brite, - * communication delay between network elements is simulated, - * causing the Cloudlet to start executing just after a few seconds.
- */ +/// A simple example showing how to create a Datacenter with 1 host and a network +/// topology, running 1 cloudlet on it. +/// There is just one VM with a single PE of 250 MIPS. +/// The Cloudlet requires 1 PE and has a length of 40000 MI. +/// This way, the Cloudlet will take 160 seconds to finish (40000/250). +/// +/// The Cloudlet is not requiring any files from a [SanStorage], +/// but since a network topology is defined from the file topology.brite, +/// communication delay between network elements is simulated, +/// causing the Cloudlet to start executing just after a few seconds. public class NetworkExample1 { private static final String NETWORK_TOPOLOGY_FILE = "topology.brite"; private static final int VM_PES = 1; diff --git a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample2.java b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample2.java index 261d235..6d9721d 100755 --- a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample2.java +++ b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample2.java @@ -28,10 +28,8 @@ import java.util.ArrayList; import java.util.List; -/** - * A simple example showing how to create 2 datacenters with 1 host. - * It sets a network topology and then run 2 cloudlets. - */ +/// A simple example showing how to create 2 datacenters with 1 host. +/// It sets a network topology and then run 2 cloudlets. public class NetworkExample2 { private static final String NETWORK_TOPOLOGY_FILE = "topology.brite"; private static final int VM_PES = 1; diff --git a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample3.java b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample3.java index 7a99292..31f9cb8 100755 --- a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample3.java +++ b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample3.java @@ -28,10 +28,8 @@ import java.util.ArrayList; import java.util.List; -/** - * A simple example showing how to create 2 datacenters with 1 host each and run - * cloudlets of 2 users. It also sets a network topology. - */ +/// A simple example showing how to create 2 datacenters with 1 host each and run +/// cloudlets of 2 users. It also sets a network topology. public class NetworkExample3 { private static final int VM_PES = 1; @@ -135,9 +133,7 @@ private void createAndSubmitVms() { brokerList.get(1).submitVmList(vmList2); } - /** - * Creates the network topology from a brite file. - */ + /// Creates the network topology from a brite file. private void createNetwork() { //load the network topology file final var networkTopology = BriteNetworkTopology.getInstance("topology.brite"); diff --git a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample4.java b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample4.java index ba3b33f..192728b 100755 --- a/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample4.java +++ b/src/main/java/org/cloudbus/cloudsim/examples/network/NetworkExample4.java @@ -31,24 +31,22 @@ import java.util.ArrayList; import java.util.List; -/** - * A simple example showing how to create a Datacenter with 1 host and a network - * topology, running 1 cloudlet on it. Here, instead of using a BRITE file - * describing the links, they are just inserted in the code. - * - *The example defines a given latency for communication with the created broker. - * Since the broker receives multiple messages (such as for VM and Cloudlet creation), - * cloudlets start running just after such multiple messages are received. - * If 3 messages are sent to the broker for starting a Cloudlet, - * the total delay is the network latency multiplied by 3.
- */ +/// A simple example showing how to create a Datacenter with 1 host and a network +/// topology, running 1 cloudlet on it. Here, instead of using a BRITE file +/// describing the links, they are just inserted in the code. +/// +/// The example defines a given latency for communication with the created broker. +/// Since the broker receives multiple messages (such as for VM and Cloudlet creation), +/// cloudlets start running just after such multiple messages are received. +/// If 3 messages are sent to the broker for starting a Cloudlet, +/// the total delay is the network latency multiplied by 3. public class NetworkExample4 { private static final int VM_PES = 1; - /** In Megabits/s. */ + /// In Megabits/s. private static final double NETWORK_BW = 10.0; - /** In seconds. */ + /// In seconds. private static final double NETWORK_LATENCY = 10.0; private final DatacenterBroker broker; diff --git a/src/main/java/org/cloudbus/cloudsim/examples/network/applications/NetworkVmExampleAbstract.java b/src/main/java/org/cloudbus/cloudsim/examples/network/applications/NetworkVmExampleAbstract.java index c539008..c1c72e2 100755 --- a/src/main/java/org/cloudbus/cloudsim/examples/network/applications/NetworkVmExampleAbstract.java +++ b/src/main/java/org/cloudbus/cloudsim/examples/network/applications/NetworkVmExampleAbstract.java @@ -25,18 +25,16 @@ import java.util.List; import java.util.Map; -/** - * A base class for network simulation examples - * using objects such as{@link NetworkDatacenter}, - * {@link NetworkHost}, {@link NetworkVm} and {@link NetworkCloudlet}. - * - *The class simulate applications that are compounded by a list of - * {@link NetworkCloudlet}.
- * - * @author Saurabh Kumar Garg - * @author Rajkumar Buyya - * @author Manoel Campos da Silva Filho - */ +/// A base class for network simulation examples +/// using objects such as[NetworkDatacenter], +/// [NetworkHost], [NetworkVm] and [NetworkCloudlet]. +/// +/// The class simulate applications that are compounded by a list of +/// [NetworkCloudlet]. +/// +/// @author Saurabh Kumar Garg +/// @author Rajkumar Buyya +/// @author Manoel Campos da Silva Filho abstract class NetworkVmExampleAbstract { public static final int MAX_VMS_PER_HOST = 2; @@ -57,11 +55,9 @@ abstract class NetworkVmExampleAbstract { public static final long VM_BW = 1000; public static final int VM_PES_NUMBER = HOST_PES / MAX_VMS_PER_HOST; - /** - * Number of fictitious applications to create. - * Each application is just a list of {@link NetworkCloudlet}. - * @see #appMap - */ + /// Number of fictitious applications to create. + /// Each application is just a list of [NetworkCloudlet]. + /// @see #appMap public static final int APPS_NUMBER = 1; public static final int CLOUDLET_PES = VM_PES_NUMBER; @@ -79,16 +75,12 @@ abstract class NetworkVmExampleAbstract { private final NetworkDatacenter datacenter; private final ListIt defines a set of constants that enables a developer - * to change the number of Hosts, VMs and Cloudlets to create - * and the number of {@link Pe}s for Hosts, VMs and Cloudlets.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - */ +/// A minimal but organized, structured and re-usable CloudSim Plus example +/// which shows good coding practices for creating simulation scenarios. +/// +/// It defines a set of constants that enables a developer +/// to change the number of Hosts, VMs and Cloudlets to create +/// and the number of [Pe]s for Hosts, VMs and Cloudlets. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 public class BasicFirstExample { private static final int HOSTS = 1; private static final int HOST_PES = 8; @@ -100,9 +98,7 @@ private BasicFirstExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayList- * If the VM has a lifeTime set, it's Cloudlets follow the same lifetime. - * If both Cloudlet and Vm have a lifetime, the shorter defines the maximum - * amount of time the Cloudlet will execute. - *
- * - *The example creates all Cloudlets and some VMs with a given lifetime. - * Since VM lifetime is shorter than their Cloudlets' lifetime, - * such Cloudlets finish sooner than their own lifetime.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 8.2.0 - * @see CloudletLifeTimeExample - */ +/// An example showing how to use the new [Lifetimed#setLifeTime(double)] to +/// define the maximum time [Cloudlet] or [Vm] entity is allowed to execute. +/// After this time is reached, the entity is finished as soon as possible. +/// +/// If the VM has a lifeTime set, it's Cloudlets follow the same lifetime. +/// If both Cloudlet and Vm have a lifetime, the shorter defines the maximum +/// amount of time the Cloudlet will execute. +/// +/// The example creates all Cloudlets and some VMs with a given lifetime. +/// Since VM lifetime is shorter than their Cloudlets' lifetime, +/// such Cloudlets finish sooner than their own lifetime. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 8.2.0 +/// @see CloudletLifeTimeExample public class CloudletAndVmLifeTimeExample { private static final int HOSTS = 3; private static final int HOST_PES = 10; @@ -81,23 +77,17 @@ public class CloudletAndVmLifeTimeExample { private static final int CLOUDLET_PES = 2; private static final int CLOUDLET_LENGTH = 10_000; - /** - * If the scheduling interval is not multiple of the VM/Cloudlet lifetime, - * Cloudlets may execute more than you desire. - * @see Datacenter#getSchedulingInterval() - */ + /// If the scheduling interval is not multiple of the VM/Cloudlet lifetime, + /// Cloudlets may execute more than you desire. + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 3; - /** - * Maximum time (in seconds) Cloudlets are allowed to execute. - * Set -1 to disable lifeTime and execute the Cloudlet entirely. - */ + /// Maximum time (in seconds) Cloudlets are allowed to execute. + /// Set -1 to disable lifeTime and execute the Cloudlet entirely. private static final double CLOUDLET_LIFE_TIME = 5; - /** - * Maximum time (in seconds) some VMs are allowed to execute. - * @see Lifetimed#setLifeTime(double) - */ + /// Maximum time (in seconds) some VMs are allowed to execute. + /// @see Lifetimed#setLifeTime(double) private static final double VM_LIFE_TIME = 3; private final CloudSimPlus simulation; @@ -141,21 +131,17 @@ private CloudletAndVmLifeTimeExample() { System.out.printf("Simulation finished at %s. Execution time: %.2f seconds%n", LocalTime.now(), TimeUtil.elapsedSeconds(startSecs)); } - /** - * Gets the lifetime as a String. - * If the lifetime is {@link Double#MAX_VALUE} (the default value), - * returns an empty string to indicate the attribute was not set. - * - * @param entity a Cloudlet of VM entity - * @return a String lifetime - */ + /// Gets the lifetime as a String. + /// If the lifetime is [Double#MAX_VALUE] (the default value), + /// returns an empty string to indicate the attribute was not set. + /// + /// @param entity a Cloudlet of VM entity + /// @return a String lifetime private String getLifeTimeStr(final Lifetimed entity) { return entity.getLifeTime() == Double.MAX_VALUE ? "" : "%.2f".formatted(entity.getLifeTime()); } - /** - * Sets a lifetime for half of the VMs. - */ + /// Sets a lifetime for half of the VMs. private void setVmsLifeTime() { vmList.stream() .filter(vm -> vm.getId() < VMS/2) diff --git a/src/main/java/org/cloudsimplus/examples/CloudletCancellationExample.java b/src/main/java/org/cloudsimplus/examples/CloudletCancellationExample.java index 8682f60..67124ed 100755 --- a/src/main/java/org/cloudsimplus/examples/CloudletCancellationExample.java +++ b/src/main/java/org/cloudsimplus/examples/CloudletCancellationExample.java @@ -48,25 +48,21 @@ import java.util.ArrayList; import java.util.List; -/** - * Shows how to cancel the execution of a Cloudlet - * after executing a given amount of MIPS from its total - * MIPS length. - * - *Realize you can't use the {@link Cloudlet#setStatus(Cloudlet.Status)} - * to directly change the status of a Cloudlet, such as to cancel it. - * That is an issue inherited from CloudSim that needs to be fixed yet. - * To change the Cloudlet status you have to use the {@link CloudletScheduler} - * that controls the execution of the Cloudlet.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.6 - */ +/// Shows how to cancel the execution of a Cloudlet +/// after executing a given amount of MIPS from its total +/// MIPS length. +/// +/// Realize you can't use the [Cloudlet#setStatus(Cloudlet.Status)] +/// to directly change the status of a Cloudlet, such as to cancel it. +/// That is an issue inherited from CloudSim that needs to be fixed yet. +/// To change the Cloudlet status you have to use the [CloudletScheduler] +/// that controls the execution of the Cloudlet. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.2.6 public class CloudletCancellationExample { - /** - * Defines, between other things, the time intervals - * to update the processing of Cloudlets (in seconds). - */ + /// Defines, between other things, the time intervals + /// to update the processing of Cloudlets (in seconds). private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 1; @@ -103,13 +99,11 @@ private CloudletCancellationExample() { vmList = createVms(); cloudletList = createCloudlets(); - /** - * Monitor the execution of the first Cloudlet to cancel it after it has executed 50% - * of its total length. - * In order to make this work, the {@link Datacenter#getSchedulingInterval()} - * most be set. - * See {@link #SCHEDULING_INTERVAL} for more details. - */ + /// Monitor the execution of the first Cloudlet to cancel it after it has executed 50% + /// of its total length. + /// In order to make this work, the [Datacenter#getSchedulingInterval()] + /// most be set. + /// See [#SCHEDULING_INTERVAL] for more details. cloudletList.get(0).addOnUpdateProcessingListener(this::cancelCloudletIfHalfExecuted); broker0.submitVmList(vmList); @@ -121,10 +115,8 @@ private CloudletCancellationExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Cancel a Cloudlet if it has already executed 50% of its total MIPS length. - * @param e the event information about Cloudlet processing - */ + /// Cancel a Cloudlet if it has already executed 50% of its total MIPS length. + /// @param e the event information about Cloudlet processing private void cancelCloudletIfHalfExecuted(final CloudletVmEventInfo e) { final var cloudlet = e.getCloudlet(); if(cloudlet.getFinishedLengthSoFar() >= CLOUDLET_LENGTH / 2){ @@ -135,9 +127,7 @@ private void cancelCloudletIfHalfExecuted(final CloudletVmEventInfo e) { } } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListIt's considered that we have multiple VMs from a given customer (broker), - * where all VMs are running the same services for load balancing and fault tolerance. - * If a VM fails, since they are providing the same service and there are other equal VMs running, - * there is no need for recovery. - * If the failures don't demand recovery, no new VMs need to be started up, since no service was stopped. - *
- * - *If you run this example multiple times, it will give the same results. - * Check {@link #createFaultInjectionForHosts(Datacenter)} to set - * a different seed for the fault injection random number generator - * to get different results at each run.
- * - * @author raysaoliveira - * @since CloudSim Plus 1.2.0 - */ +/// Example showing how to inject random [Pe] faults into Hosts using +/// [HostFaultInjection] objects. +/// +/// It's considered that we have multiple VMs from a given customer (broker), +/// where all VMs are running the same services for load balancing and fault tolerance. +/// If a VM fails, since they are providing the same service and there are other equal VMs running, +/// there is no need for recovery. +/// If the failures don't demand recovery, no new VMs need to be started up, since no service was stopped. +/// +/// If you run this example multiple times, it will give the same results. +/// Check [#createFaultInjectionForHosts(Datacenter)] to set +/// a different seed for the fault injection random number generator +/// to get different results at each run. +/// +/// @author raysaoliveira +/// @since CloudSim Plus 1.2.0 public final class HostFaultInjectionExample1 { private static final int SCHEDULE_TIME_TO_PROCESS_DATACENTER_EVENTS = 0; private static final int BROKERS = 1; - /** - * Number of Hosts to create for each Datacenter. The number of elements in - * this array defines the number of Datacenters to be created. - */ + /// Number of Hosts to create for each Datacenter. The number of elements in + /// this array defines the number of Datacenters to be created. private static final int HOSTS = 8; private static final int HOST_PES = 5; private static final int HOST_MIPS_BY_PE = 1000; @@ -86,13 +81,12 @@ public final class HostFaultInjectionExample1 { private static final long HOST_STORAGE = 1000000; //host storage private static final long HOST_BW = 100000000L; - /** - * The average number of failures expected to happen each hour - * in a Poisson arrival process, which is also called event rate or rate parameter. - * @see PoissonDistr */ + /// The average number of failures expected to happen each hour + /// in a Poisson arrival process, which is also called event rate or rate parameter. + /// @see PoissonDistr private static final double MEAN_FAILURE_NUMBER_PER_HOUR = 0.01; - /** @see HostFaultInjection#setMaxTimeToFailInHours(double) */ + /// @see HostFaultInjection#setMaxTimeToFailInHours(double) private static final double MAX_TIME_TO_FAIL_IN_HOURS = TimeUtil.daysToHours(30); private final ListThe example may run out of memory. - * Try to increase heap memory space passing, for instance, - * -Xmx6g to the java command line, where 6g means 6GB of maximum heap size.
- * - *Your computer may not even have enough memory capacity to run this example - * and it may just crashes with OutOfMemoryException.
- * - *Some factors that drastically impact simulation performance and memory consumption - * is the {@link #CLOUDLETS} number and {@link #SCHEDULING_INTERVAL}.
- * - * @author Manoel Campos da Silva Filho - * @since ClodSimPlus 7.3.1 - */ +/// An example creating a huge number of Hosts, VMs and Cloudlets +/// to simulate a large-scale cloud infrastructure. +/// +/// The example may run out of memory. +/// Try to increase heap memory space passing, for instance, +/// -Xmx6g to the java command line, where 6g means 6GB of maximum heap size. +/// +/// Your computer may not even have enough memory capacity to run this example +/// and it may just crashes with OutOfMemoryException. +/// +/// Some factors that drastically impact simulation performance and memory consumption +/// is the [#CLOUDLETS] number and [#SCHEDULING_INTERVAL]. +/// +/// @author Manoel Campos da Silva Filho +/// @since ClodSimPlus 7.3.1 public class LargeScaleExample { private static final int HOSTS = 200_000; private static final int HOST_PES = 16; @@ -80,14 +78,12 @@ public class LargeScaleExample { private static final int CLOUDLET_PES = VM_PES/2; private static final int CLOUDLET_LENGTH = HOST_MIPS * 10; - /** - * Defines a time interval to process cloudlets execution - * and possibly collect data. Setting a value greater than 0 - * enables that interval, which cause huge performance penaults for - * lage scale simulations. - * - * @see Datacenter#setSchedulingInterval(double) - */ + /// Defines a time interval to process cloudlets execution + /// and possibly collect data. Setting a value greater than 0 + /// enables that interval, which cause huge performance penaults for + /// lage scale simulations. + /// + /// @see Datacenter#setSchedulingInterval(double) private static final double SCHEDULING_INTERVAL = -1; private final CloudSimPlus simulation; @@ -146,9 +142,7 @@ private void brokerSubmit() { broker0.submitCloudletList(cloudletList); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListThese issues happen when the time between some events is smaller than the - * {@link Simulation#getMinTimeBetweenEvents()} (for instance, some Cloudlets are finishing - * in a time interval smaller than the mentioned simulation attribute). - * Therefore, you may need to fine tune such attribute according to your simulation.
- * - *This example reproduces the configuration - * Issue #163. - * The documentation of the {@link #MIN_TIME_BETWEEN_EVENTS} constant below shows how - * to configure the attribute to make CloudSim Plus process all events - * accurately in this scenario and then all submitted Cloudlets be finished. - *
- * - * @author Natthasak Vechprasit - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.0.7 - */ +/// An example showing how the [Simulation#getMinTimeBetweenEvents()] may affect the processing +/// of events in your simulation. +/// This way, it may affect simulation accuracy, regarding the execution time of Cloudlets. +/// +/// These issues happen when the time between some events is smaller than the +/// [Simulation#getMinTimeBetweenEvents()] (for instance, some Cloudlets are finishing +/// in a time interval smaller than the mentioned simulation attribute). +/// Therefore, you may need to fine tune such attribute according to your simulation. +/// +/// This example reproduces the configuration +/// [Issue #163](https://github.com/cloudsimplus/cloudsimplus/issues/163). +/// The documentation of the [#MIN_TIME_BETWEEN_EVENTS] constant below shows how +/// to configure the attribute to make CloudSim Plus process all events +/// accurately in this scenario and then all submitted Cloudlets be finished. +/// +/// @author Natthasak Vechprasit +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.0.7 public class MinTimeBetweenEventsExample { - /** - * The minimum time between an event and the previous one to get the current event to be processed. - * - *If events happen in a time interval smaller than this value, that will - * impact results accuracy. The created Cloudlets take about 0.1 second to finish, - * but with the current MIN_TIME_BETWEEN_EVENTS, you'll see the ExecTime is greater than - * that.
- * - *You can fix that by changing this constant to 0.01, for instance.
- * - * @see CloudSimPlus#getMinTimeBetweenEvents() - */ + /// The minimum time between an event and the previous one to get the current event to be processed. + /// + /// If events happen in a time interval smaller than this value, that will + /// impact results accuracy. The created Cloudlets take about 0.1 second to finish, + /// but with the current MIN_TIME_BETWEEN_EVENTS, you'll see the ExecTime is greater than + /// that. + /// + /// You can fix that by changing this constant to 0.01, for instance. + /// + /// @see CloudSimPlus#getMinTimeBetweenEvents() private static final double MIN_TIME_BETWEEN_EVENTS = 0.5; private static final int HOST_PES_NUMBER = 4; @@ -174,10 +169,8 @@ private Vm createVm(final int id) { return vm; } - /** - * Creates a list of Cloudlets to be run inside a given VM - * @param vm the VM to run the Cloudlets - */ + /// Creates a list of Cloudlets to be run inside a given VM + /// @param vm the VM to run the Cloudlets private void createAndSubmitCloudlets(final Vm vm) { final var list = new ArrayListThis is just a minimal example that runs 2 simulations with different number - * of Hosts, VMs and Cloudlets. However, all these objects will have the same configurations - * in the different simulations. There will be just a difference in the number of created - * objects.
- * - *To enable such a parallel simulations execution, the logging must be - * disable (as shown in the first line of the main method) and any console - * output should be avoided during simulation execution. - * Further, usage of static mutable attributes must be avoided. - * All simulation attributes must be instance attributes and one - * simulation run (a simulation instance) should not share data with other ones.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - */ +/// An example showing how to run two simulation scenarios with different configurations +/// in parallel, using the CloudSim Plus exclusive features and +/// [Java 8 Lambda Expressions and Parallel Streams](https://www.oracle.com/technical-resources/articles/java/ma14-java-se-8-streams.html). +/// The parallel execution of simulations doesn't ensure that the overall execution time will be reduced. +/// It depends on diverse factors such as the number of simulations, the tasks that each simulation +/// executes, the number of available physical CPUs at your machine, etc. +/// +/// This is just a minimal example that runs 2 simulations with different number +/// of Hosts, VMs and Cloudlets. However, all these objects will have the same configurations +/// in the different simulations. There will be just a difference in the number of created +/// objects. +/// +/// To enable such a parallel simulations execution, the logging must be +/// disable (as shown in the first line of the main method) and any console +/// output should be avoided during simulation execution. +/// Further, usage of static mutable attributes must be avoided. +/// All simulation attributes must be instance attributes and one +/// simulation run (a simulation instance) should not share data with other ones. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 public class ParallelSimulationsExample implements Runnable { private final String title; private final CloudSimPlus simulation; - /** Created when the simulation is started inside {@link #run()}. */ + /// Created when the simulation is started inside [#run()]. @SuppressWarnings("NullAway.Init") private DatacenterBroker broker; private ListSince CloudSim Plus provides functional - * VmAllocationPolicy implementations, you don't - * even need to create a new class to implement your own policy, - * unless you really want to (to make reuse easy).
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.0.5 - */ +/// An example showing how to implement a custom +/// [VmAllocationPolicy] that randomly +/// selects suitable Hosts to place submitted VMs. +/// Check the [#createDatacenter()] method for details. +/// +/// Since CloudSim Plus provides functional +/// VmAllocationPolicy implementations, you don't +/// even need to create a new class to implement your own policy, +/// unless you really want to (to make reuse easy). +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.0.5 public class RandomVmAllocationPolicyExample { private static final int HOSTS = 10; private static final int HOST_PES = 8; @@ -85,10 +83,9 @@ public class RandomVmAllocationPolicyExample { private ListNOTICE: This example is not intended to be reused and we strongly advise - * against doing that. Since all the code is inside a single method, - * that is completely inappropriate.
- * - *This code is only intended to show how it's simpler - * and easier to create cloud computing simulations using CloudSim Plus.
- * - *If you want a basic, but organized and reusable first example, - * see the {@link BasicFirstExample}.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - * @see BasicFirstExample - */ +/// An example showing the very minimal code required to create +/// a simulation scenario in CloudSim Plus. +/// +/// **NOTICE: This example is not intended to be reused and we strongly advise +/// against doing that. Since all the code is inside a single method, +/// that is completely inappropriate.** +/// +/// This code is only intended to show how it's simpler +/// and easier to create cloud computing simulations using CloudSim Plus. +/// +/// If you want a basic, but organized and reusable first example, +/// see the [BasicFirstExample]. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 +/// @see BasicFirstExample void main() { //tag::cloudsimplus-reduced-example[] //Enables just some level of log messages diff --git a/src/main/java/org/cloudsimplus/examples/StorageAreaNetworkExample1.java b/src/main/java/org/cloudsimplus/examples/StorageAreaNetworkExample1.java index 66a0e66..bf9ac4c 100755 --- a/src/main/java/org/cloudsimplus/examples/StorageAreaNetworkExample1.java +++ b/src/main/java/org/cloudsimplus/examples/StorageAreaNetworkExample1.java @@ -47,19 +47,17 @@ import java.util.ArrayList; import java.util.List; - /** - * An example of how to define a {@link SanStorage Storage Area Network (SAN)} - * for a Datacenter, add files to this SAN and make Cloudlets - * require files from that SAN. - * - *Cloudlets' finish time is delayed due to transfer of required files - * from the SAN to the VM. - * The transfer time is computed based on the SAN's bandwidth and - * size of the required files.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.6 - */ + /// An example of how to define a [Storage Area Network (SAN)][SanStorage] + /// for a Datacenter, add files to this SAN and make Cloudlets + /// require files from that SAN. + /// + /// Cloudlets' finish time is delayed due to transfer of required files + /// from the SAN to the VM. + /// The transfer time is computed based on the SAN's bandwidth and + /// size of the required files. + /// + /// @author Manoel Campos da Silva Filho + /// @since CloudSim Plus 1.2.6 public class StorageAreaNetworkExample1 { private static final int HOSTS = 2; private static final int HOST_PES = 8; @@ -75,12 +73,9 @@ public class StorageAreaNetworkExample1 { private static long SAN_BANDWIDTH_Mbps = 1; private static long SAN_CAPACITY_MB = 1024 * 1024 * 10; - /** - * A matrix of two rows each one containing an array of sizes - * for different files to be added to a SAN storage. - * Each row contains the sizes of the files for a SAN. - * - */ + /// A matrix of two rows each one containing an array of sizes + /// for different files to be added to a SAN storage. + /// Each row contains the sizes of the files for a SAN. private static int FILE_SIZES_MATRIX_MB[][] = {{1000, 10000, 5000, 25000}, {250000, 35000, 12000, 10000}}; private static int SAN_COUNT = FILE_SIZES_MATRIX_MB.length; @@ -129,11 +124,9 @@ private StorageAreaNetworkExample1() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a {@link SanStorage Storage Area Network (SAN)} array for a Datacenter. - * @return the List of storage devices (the SAN array) - * @see Disk Array - */ + /// Creates a [Storage Area Network (SAN)][SanStorage] array for a Datacenter. + /// @return the List of storage devices (the SAN array) + /// @see Disk Array private ListKeep in mind that such a policy is very naive and increases the number of active Hosts, - * leading to higher power consumption.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.4.2 - */ +/// An example that show the usage of the [VmAllocationPolicyRoundRobin], +/// that cyclically places VMs into Hosts. This way, it places a VM into a Host +/// and moves to the next Host. +/// All hosts are not powered-on when created. As VMs need to be placed, +/// Hosts are activated on demand, as can be checked in the logs. +/// +/// Keep in mind that such a policy is very naive and increases the number of active Hosts, +/// leading to higher power consumption. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.4.2 public class VmAllocationPolicyRoundRobinExample { private static final int HOSTS = 4; private static final int HOST_PES = 8; @@ -101,9 +99,7 @@ private VmAllocationPolicyRoundRobinExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListThe example uses the {@link UtilizationModelDynamic} to - * increase VM CPU usage over time (in seconds). - * This {@link UtilizationModelDynamic} relies on a {@link Function} - * to increase resource usage. Such a Function is defined using a Lambda Expression.
- * - *It shows Host CPU utilization every second, so that when the overloaded VM - * is destroyed, we can check the Host CPU utilization reduces.
- * - *Lambda Expressions and Functional Interfaces are Java 8+ features. - * If you don't know what these features are, I suggest checking out this - * tutorial
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.3.0 - */ +/// Shows how to destroy an overloaded VM during simulation runtime, +/// after its CPU usage reaches a defined threshold. +/// +/// The example uses the [UtilizationModelDynamic] to +/// increase VM CPU usage over time (in seconds). +/// This [UtilizationModelDynamic] relies on a [Function] +/// to increase resource usage. Such a Function is defined using a Lambda Expression. +/// +/// It shows Host CPU utilization every second, so that when the overloaded VM +/// is destroyed, we can check the Host CPU utilization reduces. +/// +/// **Lambda Expressions and Functional Interfaces are Java 8+ features.** +/// If you don't know what these features are, I suggest checking out this +/// [tutorial](http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html) +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.3.0 public class VmDestructionExample { - /** - * Defines, between other things, the time intervals - * to update the processing of simulation events. - * This way, simulation clock increases according to this time. - * Since a {@link UtilizationModelDynamic} is being used to define CPU usage of VMs, - * the utilization is updated at this time interval. - * - * Setting the Datacenter scheduling interval is required to allow - * the CPU utilization to increase along the simulation execution. - * - * @see Datacenter#setSchedulingInterval(double) - */ + /// Defines, between other things, the time intervals + /// to update the processing of simulation events. + /// This way, simulation clock increases according to this time. + /// Since a [UtilizationModelDynamic] is being used to define CPU usage of VMs, + /// the utilization is updated at this time interval. + /// + /// Setting the Datacenter scheduling interval is required to allow + /// the CPU utilization to increase along the simulation execution. + /// + /// @see Datacenter#setSchedulingInterval(double) private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 1; @@ -133,15 +129,13 @@ private VmDestructionExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Tracks the update of execution for a VM. - * If that VM is overloaded then destroys it. - * In this example, this {@link EventListener} is just - * attached for VM 1, therefore, just such a VM will be destroyed - * if overloaded. - * - * @param info event information, including the VM that was updated - */ + /// Tracks the update of execution for a VM. + /// If that VM is overloaded then destroys it. + /// In this example, this [EventListener] is just + /// attached for VM 1, therefore, just such a VM will be destroyed + /// if overloaded. + /// + /// @param info event information, including the VM that was updated private void vmProcessingUpdateListener(VmHostEventInfo info) { final Vm vm = info.getVm(); //Destroys VM 1 when its CPU usage reaches 90% @@ -155,9 +149,7 @@ private void vmProcessingUpdateListener(VmHostEventInfo info) { datacenter0.getHostList().forEach(h -> System.out.printf("# %.2f: %s CPU Utilization %.2f%%%n", info.getTime(), h, h.getCpuPercentUtilization()*100)); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListA {@link HorizontalVmScalingSimple} - * is set to each {@link #createListOfScalableVms(int) initially created VM}, - * that will check at {@link #SCHEDULING_INTERVAL specific time intervals} - * if the VM {@link #isVmOverloaded(Vm) is overloaded or not} to then - * request the creation of a new VM to attend arriving Cloudlets.
- * - *The example uses CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically creating objects such as Cloudlets and VMs. - * It relies on - * Java 8 Lambda Expressions - * to set a Listener for the {@link Simulation#addOnClockTickListener(EventListener) onClockTick event}. - * That Listener gets notified every time the simulation clock advances and then creates and submits new Cloudlets. - *
- * - *The {@link DatacenterBroker} is accountable to perform horizontal down scaling. - * The down scaling is enabled by setting a {@link Function} using the {@link DatacenterBroker#setVmDestructionDelayFunction(Function)}. - * This Function defines the time the broker has to wait to destroy a VM after it becomes idle. - * If no Function is set, the broker just destroys VMs after all running Cloudlets are finished - * and there is no Cloudlet waiting to be created. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - */ +/// An example that balances load by dynamically creating VMs, +/// according to the arrival of Cloudlets. +/// Cloudlets are [dynamically created and submitted to the broker at specific time intervals][#createNewCloudlets(EventInfo)]. +/// +/// A [HorizontalVmScalingSimple] +/// is set to each [initially created VM][#createListOfScalableVms(int)], +/// that will check at [specific time intervals][#SCHEDULING_INTERVAL] +/// if the VM [is overloaded or not][#isVmOverloaded(Vm)] to then +/// request the creation of a new VM to attend arriving Cloudlets. +/// +/// The example uses CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically creating objects such as Cloudlets and VMs. +/// It relies on +/// [Java 8 Lambda Expressions](http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html) +/// to set a Listener for the [onClockTick event][Simulation#addOnClockTickListener(EventListener)]. +/// That Listener gets notified every time the simulation clock advances and then creates and submits new Cloudlets. +/// +/// The [DatacenterBroker] is accountable to perform horizontal down scaling. +/// The down scaling is enabled by setting a [Function] using the [DatacenterBroker#setVmDestructionDelayFunction(Function)]. +/// This Function defines the time the broker has to wait to destroy a VM after it becomes idle. +/// If no Function is set, the broker just destroys VMs after all running Cloudlets are finished +/// and there is no Cloudlet waiting to be created. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 public class LoadBalancerByHorizontalVmScalingExample { - /** - * The interval in which the Datacenter will schedule events. - * As lower is this interval, sooner the processing of VMs and Cloudlets - * is updated and you will get more notifications about the simulation execution. - * However, that also affect the simulation performance. - * - *A large schedule interval, such as 15, will make that just - * at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just - * after this time the creation of a new one will be requested - * by the VM's {@link HorizontalVmScaling Horizontal Scaling} mechanism.
- * - *If this interval is defined using a small value, you may get - * more dynamically created VMs than expected. - * Accordingly, this value has to be trade-off. - * For more details, see {@link Datacenter#getSchedulingInterval()}.
- */ + /// The interval in which the Datacenter will schedule events. + /// As lower is this interval, sooner the processing of VMs and Cloudlets + /// is updated and you will get more notifications about the simulation execution. + /// However, that also affect the simulation performance. + /// + /// A large schedule interval, such as 15, will make that just + /// at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just + /// after this time the creation of a new one will be requested + /// by the VM's [Horizontal Scaling][HorizontalVmScaling] mechanism. + /// + /// If this interval is defined using a small value, you may get + /// more dynamically created VMs than expected. + /// Accordingly, this value has to be trade-off. + /// For more details, see [Datacenter#getSchedulingInterval()]. private static final int SCHEDULING_INTERVAL = 5; - /** - * The interval to request the creation of new Cloudlets. - */ + /// The interval to request the creation of new Cloudlets. private static final int CLOUDLETS_CREATION_INTERVAL = SCHEDULING_INTERVAL * 2; private static final int HOSTS = 50; @@ -123,9 +114,7 @@ public class LoadBalancerByHorizontalVmScalingExample { private final ListThe example uses the CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically create objects such as Cloudlets and VMs at runtime. - * It relies on - * Java 8 Method References - * to set a method to be called for {@link Simulation#addOnClockTickListener(EventListener) onClockTick events}. - * It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 2.2.1 - * @see VerticalVmCpuScalingExample - */ +/// An example that scales VM PEs up or down, according to the arrival of Cloudlets. +/// A [VerticalVmScaling] +/// is set to each [initially created VM][#createListOfScalableVms(int)]. +/// Every VM will check at [specific time intervals][#SCHEDULING_INTERVAL] +/// if its PEs [are over or underloaded][#upperCpuUtilizationThreshold(Vm)], +/// according to a **dynamic computed utilization threshold**. +/// Then it requests such PEs to be up or down scaled. +/// +/// The example uses the CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically create objects such as Cloudlets and VMs at runtime. +/// It relies on +/// [Java 8 Method References](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) +/// to set a method to be called for [onClockTick events][Simulation#addOnClockTickListener(EventListener)]. +/// It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 2.2.1 +/// @see VerticalVmCpuScalingExample public class VerticalVmCpuScalingDynamicThreshold { - /** - * The interval in which the Datacenter will schedule events. - * As lower is this interval, sooner the processing of VMs and Cloudlets - * is updated and you will get more notifications about the simulation execution. - * However, it can affect the simulation performance. - * - *For this example, a large schedule interval such as 15 will make that just - * at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just - * after this time the creation of a new one will be requested - * by the VM's {@link HorizontalVmScaling Horizontal Scaling} mechanism.
- * - *If this interval is defined using a small value, you may get - * more dynamically created VMs than expected. Accordingly, this value - * has to be trade-off. - * For more details, see {@link Datacenter#getSchedulingInterval()}.
- */ + /// The interval in which the Datacenter will schedule events. + /// As lower is this interval, sooner the processing of VMs and Cloudlets + /// is updated and you will get more notifications about the simulation execution. + /// However, it can affect the simulation performance. + /// + /// For this example, a large schedule interval such as 15 will make that just + /// at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just + /// after this time the creation of a new one will be requested + /// by the VM's [Horizontal Scaling][HorizontalVmScaling] mechanism. + /// + /// If this interval is defined using a small value, you may get + /// more dynamically created VMs than expected. Accordingly, this value + /// has to be trade-off. + /// For more details, see [Datacenter#getSchedulingInterval()]. private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 1; @@ -121,9 +116,7 @@ public static void main(String[] args) { new VerticalVmCpuScalingDynamicThreshold(); } - /** - * Default constructor that builds the simulation scenario and starts the simulation. - */ + /// Default constructor that builds the simulation scenario and starts the simulation. private VerticalVmCpuScalingDynamicThreshold() { /*Enables just some level of log messages. Make sure to import org.cloudsimplus.util.Log;*/ @@ -150,10 +143,8 @@ private VerticalVmCpuScalingDynamicThreshold() { printSimulationResults(); } - /** - * Shows updates every time the simulation clock advances. - * @param evt information about the event happened (that for this Listener is just the simulation time) - */ + /// Shows updates every time the simulation clock advances. + /// @param evt information about the event happened (that for this Listener is just the simulation time) private void onClockTickListener(EventInfo evt) { vmList.forEach(vm -> { System.out.printf( @@ -174,9 +165,7 @@ private void printSimulationResults() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private void createDatacenter() { for (int i = 0; i < HOSTS; i++) { hostList.add(createHost()); @@ -202,14 +191,12 @@ private Host createHost() { .setVmScheduler(new VmSchedulerTimeShared()); } - /** - * Creates a list of initial VMs in which each VM is able to scale vertically - * when it is over or underloaded. - * - * @param numberOfVms number of VMs to create - * @return the list of scalable VMs - * @see #createVerticalPeScaling() - */ + /// Creates a list of initial VMs in which each VM is able to scale vertically + /// when it is over or underloaded. + /// + /// @param numberOfVms number of VMs to create + /// @return the list of scalable VMs + /// @see #createVerticalPeScaling() private ListRealize the lower and upper thresholds are defined inside this method by using - * references to the methods {@link #lowerCpuUtilizationThreshold(Vm)} - * and {@link #upperCpuUtilizationThreshold(Vm)}. - * These methods enable defining thresholds in a dynamic way - * and even different thresholds for distinct VMs. - * Therefore, it's a powerful mechanism. - *
- * - *
- * However, if you are defining thresholds in a static way,
- * and they are the same for all VMs, you can use a Lambda Expression
- * like below, for instance, instead of creating a new method that just returns a constant value:
- * {@code verticalCpuScaling.setLowerThresholdFunction(vm -> 0.4);}
- *
The dynamic upper threshold is defined as 20% above the mean (mean * 1.2), - * if there are at least 10 CPU utilization history entries. - * That means if the CPU utilization of a VM is 20% above its mean - * CPU utilization, it indicates the VM is overloaded. - * If there aren't enough history entries, - * it defines a static threshold as 70% of CPU utilization.
- * - * @param vm the VM to check if its CPU is overloaded. - * The parameter is not being used internally, that means the same - * threshold is used for any Vm. - * @return the upper dynamic CPU utilization threshold - * @see #createVerticalPeScaling() - */ + /// Defines a dynamic CPU utilization threshold that indicates a Vm is overloaded. + /// Such a threshold is the maximum CPU a VM can use before requesting vertical CPU scaling. + /// A reference to this method is assigned to each Vertical VM Scaling created. + /// + /// The dynamic upper threshold is defined as 20% above the mean (mean * 1.2), + /// if there are at least 10 CPU utilization history entries. + /// That means if the CPU utilization of a VM is 20% above its mean + /// CPU utilization, it indicates the VM is overloaded. + /// If there aren't enough history entries, + /// it defines a static threshold as 70% of CPU utilization. + /// + /// @param vm the VM to check if its CPU is overloaded. + /// The parameter is not being used internally, that means the same + /// threshold is used for any Vm. + /// @return the upper dynamic CPU utilization threshold + /// @see #createVerticalPeScaling() private double upperCpuUtilizationThreshold(final Vm vm) { return vm.getCpuUtilizationStats().count() > 10 ? vm.getCpuUtilizationStats().getMean() * 1.2 : 0.7; } - /** - * Creates lists of Cloudlets to be submitted to the broker with different delays, - * simulating their arrivals at different times. - * Adds all created Cloudlets to the {@link #cloudletList}. - */ + /// Creates lists of Cloudlets to be submitted to the broker with different delays, + /// simulating their arrivals at different times. + /// Adds all created Cloudlets to the [#cloudletList]. private void createCloudletListsWithDifferentDelays() { final int initialCloudletsNumber = (int)(CLOUDLETS/2.5); final int remainingCloudletsNumber = CLOUDLETS-initialCloudletsNumber; @@ -357,26 +330,22 @@ private void createCloudletListsWithDifferentDelays() { } } - /** - * Creates a single Cloudlet with no delay, which means the Cloudlet arrival time will - * be zero (exactly when the simulation starts). - * - * @param length the Cloudlet length - * @param pesNumber the number of PEs the Cloudlets requires - * @return the created Cloudlet - */ + /// Creates a single Cloudlet with no delay, which means the Cloudlet arrival time will + /// be zero (exactly when the simulation starts). + /// + /// @param length the Cloudlet length + /// @param pesNumber the number of PEs the Cloudlets requires + /// @return the created Cloudlet private Cloudlet createCloudlet(final long length, final int pesNumber) { return createCloudlet(length, pesNumber, 0); } - /** - * Creates a single Cloudlet. - * - * @param length the length of the cloudlet to create. - * @param pesNumber the number of PEs the Cloudlets requires. - * @param delay the delay that defines the arrival time of the Cloudlet at the Cloud infrastructure. - * @return the created Cloudlet - */ + /// Creates a single Cloudlet. + /// + /// @param length the length of the cloudlet to create. + /// @param pesNumber the number of PEs the Cloudlets requires. + /// @param delay the delay that defines the arrival time of the Cloudlet at the Cloud infrastructure. + /// @return the created Cloudlet private Cloudlet createCloudlet(final long length, final int pesNumber, final double delay) { /* Since a VM PE isn't used by two Cloudlets at the same time, @@ -388,18 +357,16 @@ private Cloudlet createCloudlet(final long length, final int pesNumber, final do */ final var utilizationCpu = new UtilizationModelFull(); - /** - * Since BW e RAM are shared resources that don't enable preemption, - * two Cloudlets can't use the same portion of such resources at the same time - * (unless virtual memory is enabled, but such a feature is not available in simulation). - * This way, the total capacity of such resources is being evenly split among created Cloudlets. - * If there are 10 Cloudlets, each one will use just 10% of such resources. - * This value can be defined in different ways, as you want. For instance, some Cloudlets - * can require more resources than other ones. - * To enable that, you would need to instantiate specific {@link UtilizationModelDynamic} for each Cloudlet, - * use a {@link UtilizationModelStochastic} to define resource usage randomly, - * or use any other {@link UtilizationModel} implementation. - */ + /// Since BW e RAM are shared resources that don't enable preemption, + /// two Cloudlets can't use the same portion of such resources at the same time + /// (unless virtual memory is enabled, but such a feature is not available in simulation). + /// This way, the total capacity of such resources is being evenly split among created Cloudlets. + /// If there are 10 Cloudlets, each one will use just 10% of such resources. + /// This value can be defined in different ways, as you want. For instance, some Cloudlets + /// can require more resources than other ones. + /// To enable that, you would need to instantiate specific [UtilizationModelDynamic] for each Cloudlet, + /// use a [UtilizationModelStochastic] to define resource usage randomly, + /// or use any other [UtilizationModel] implementation. final var utilizationModelDynamic = new UtilizationModelDynamic(1.0/CLOUDLETS); final var cl = new CloudletSimple(length, pesNumber); cl.setFileSize(1024) diff --git a/src/main/java/org/cloudsimplus/examples/autoscaling/VerticalVmCpuScalingExample.java b/src/main/java/org/cloudsimplus/examples/autoscaling/VerticalVmCpuScalingExample.java index ce820ed..d268bf5 100755 --- a/src/main/java/org/cloudsimplus/examples/autoscaling/VerticalVmCpuScalingExample.java +++ b/src/main/java/org/cloudsimplus/examples/autoscaling/VerticalVmCpuScalingExample.java @@ -57,42 +57,37 @@ import static java.util.Comparator.comparingDouble; -/** - * An example that scales VM PEs up or down, according to the arrival of Cloudlets. - * A {@link VerticalVmScaling} - * is set to each {@link #createListOfScalableVms(int) initially created VM}. - * Every VM will check at {@link #SCHEDULING_INTERVAL specific time intervals} - * if its PEs {@link #upperCpuUtilizationThreshold(Vm) are over or underloaded}, - * according to a static computed utilization threshold. - * Then it requests such PEs to be up or down scaled, increasing or decreasing - * the number of PEs. - * - *The example uses the CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically create objects such as Cloudlets and VMs at runtime. - * The {@link Simulation#addOnClockTickListener(EventListener) onClockTick listener}. - * enables getting notifications when the simulation clock changes, then creating and submitting new cloudlets. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.0 - * @see VerticalVmRamScalingExample - * @see VerticalVmCpuScalingDynamicThreshold - */ +/// An example that scales VM PEs up or down, according to the arrival of Cloudlets. +/// A [VerticalVmScaling] +/// is set to each [initially created VM][#createListOfScalableVms(int)]. +/// Every VM will check at [specific time intervals][#SCHEDULING_INTERVAL] +/// if its PEs [are over or underloaded][#upperCpuUtilizationThreshold(Vm)], +/// according to a **static computed utilization threshold**. +/// Then it requests such PEs to be up or down scaled, increasing or decreasing +/// the number of PEs. +/// +/// The example uses the CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically create objects such as Cloudlets and VMs at runtime. +/// The [onClockTick listener][Simulation#addOnClockTickListener(EventListener)]. +/// enables getting notifications when the simulation clock changes, then creating and submitting new cloudlets. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.2.0 +/// @see VerticalVmRamScalingExample +/// @see VerticalVmCpuScalingDynamicThreshold public class VerticalVmCpuScalingExample { - /** - * The interval in which the Datacenter will schedule events (in seconds). - * As lower is this interval, sooner the processing of VMs and Cloudlets is updated, - * resulting in more notifications about the simulation execution. - * However, it can affect the simulation performance. - * - *A larger schedule interval makes processing of VMs to be updated less frequently. - * If a VM is overloaded, just after that interval the creation of a new one will be requested - * by the VM's {@link HorizontalVmScaling Horizontal Scaling} mechanism.
- * - *If this interval is defined using a small value, you may get - * more dynamically created VMs than expected. Accordingly, this value has to be trade-off. - * For more details, see {@link Datacenter#getSchedulingInterval()}.
- */ + /// The interval in which the Datacenter will schedule events (in seconds). + /// As lower is this interval, sooner the processing of VMs and Cloudlets is updated, + /// resulting in more notifications about the simulation execution. + /// However, it can affect the simulation performance. + /// + /// A larger schedule interval makes processing of VMs to be updated less frequently. + /// If a VM is overloaded, just after that interval the creation of a new one will be requested + /// by the VM's [Horizontal Scaling][HorizontalVmScaling] mechanism. + /// + /// If this interval is defined using a small value, you may get + /// more dynamically created VMs than expected. Accordingly, this value has to be trade-off. + /// For more details, see [Datacenter#getSchedulingInterval()]. private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 1; @@ -109,7 +104,7 @@ public class VerticalVmCpuScalingExample { private static final int CLOUDLETS = 10; - /** A base length (in MI) for initially created Cloudlets. */ + /// A base length (in MI) for initially created Cloudlets. private static final int CLOUDLET_LEN_BASE = 80_000; private int createsVms; @@ -118,9 +113,7 @@ public static void main(String[] args) { new VerticalVmCpuScalingExample(); } - /** - * Default constructor that builds the simulation scenario and starts the simulation. - */ + /// Default constructor that builds the simulation scenario and starts the simulation. private VerticalVmCpuScalingExample() { /*Enables just some level of log messages. Make sure to import org.cloudsimplus.util.Log;*/ @@ -147,10 +140,8 @@ private VerticalVmCpuScalingExample() { printSimulationResults(); } - /** - * Shows updates every time the simulation clock changes. - * @param evt information about the event happened (that for this Listener is just the simulation time) - */ + /// Shows updates every time the simulation clock changes. + /// @param evt information about the event happened (that for this Listener is just the simulation time) private void onClockTickListener(EventInfo evt) { vmList.forEach(vm -> System.out.printf( @@ -191,14 +182,12 @@ private Host createHost() { return new HostSimple(ram, bw, storage, peList).setVmScheduler(new VmSchedulerTimeShared()); } - /** - * Creates a list of initial VMs in which each VM is able to scale vertically - * when it is over or underloaded. - * - * @param vmsNumber number of VMs to create - * @return the list of scalable VMs - * @see #createVerticalPeScaling() - */ + /// Creates a list of initial VMs in which each VM is able to scale vertically + /// when it is over or underloaded. + /// + /// @param vmsNumber number of VMs to create + /// @return the list of scalable VMs + /// @see #createVerticalPeScaling() private ListRealize the lower and upper thresholds are defined inside this method by using - * references to the methods {@link #lowerCpuUtilizationThreshold(Vm)} - * and {@link #upperCpuUtilizationThreshold(Vm)}. - * These methods enable defining thresholds in a dynamic way, - * setting different thresholds for distinct VMs. - *
- * - *
- * However, if you are defining thresholds in a static way,
- * and they are the same for all VMs, you can use a Lambda Expression
- * like below, instead of creating a new method that just returns a constant value:
- *
- * {@code verticalCpuScaling.setLowerThresholdFunction(vm -> 0.4);}
- *
A {@link VerticalVmScaling} - * is set to each initially created VM (check {@link #createListOfScalableVms(int)}), - * which will check at {@link #SCHEDULING_INTERVAL specific time intervals} - * if a VM's RAM {@link #upperRamUtilizationThreshold(Vm) is overloaded or not}, - * according to a statically computed utilization threshold. - * Then it requests the RAM to be scaled up.
- * - *The example uses the CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically creating objects such as Cloudlets and VMs. - * It creates a Listener for the {@link Simulation#addOnClockTickListener(EventListener) onClockTick event} - * to get notifications when the simulation clock advances, then creating and submitting new cloudlets. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.0 - * @see VerticalVmCpuScalingExample - */ +/// An example that scales VM RAM up or down, according to resource requests from running Cloudlets. +/// It relies on [UtilizationModelDynamic] to +/// set Vm RAM usage increasingly along the time. +/// Cloudlets are created with different lengths, so that they will finish gradually. +/// This way, it's possible to check that RAM usage decreases along the time. +/// +/// A [VerticalVmScaling] +/// is set to each initially created VM (check [#createListOfScalableVms(int)]), +/// which will check at [specific time intervals][#SCHEDULING_INTERVAL] +/// if a VM's RAM [is overloaded or not][#upperRamUtilizationThreshold(Vm)], +/// according to a **statically computed utilization threshold**. +/// Then it requests the RAM to be scaled up. +/// +/// The example uses the CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically creating objects such as Cloudlets and VMs. +/// It creates a Listener for the [onClockTick event][Simulation#addOnClockTickListener(EventListener)] +/// to get notifications when the simulation clock advances, then creating and submitting new cloudlets. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.2.0 +/// @see VerticalVmCpuScalingExample public class VerticalVmRamScalingExample { - /** - * The interval in which the Datacenter will schedule events. - * As lower this interval is, sooner the processing of VMs and Cloudlets - * is updated, and you get more notifications about the simulation execution. - * However, it can affect the simulation performance. - * - *For this example, a larger schedule interval such as 15 will make that just - * at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just - * after this time the creation of a new one will be requested - * by the VM's {@link HorizontalVmScaling Horizontal Scaling} mechanism.
- * - *If this interval is defined using a small value, you may get - * more dynamically created VMs than expected. Accordingly, this value - * has to be trade-off. - * For more details, see {@link Datacenter#getSchedulingInterval()}.
- */ + /// The interval in which the Datacenter will schedule events. + /// As lower this interval is, sooner the processing of VMs and Cloudlets + /// is updated, and you get more notifications about the simulation execution. + /// However, it can affect the simulation performance. + /// + /// For this example, a larger schedule interval such as 15 will make that just + /// at every 15 seconds the processing of VMs is updated. If a VM is overloaded, just + /// after this time the creation of a new one will be requested + /// by the VM's [Horizontal Scaling][HorizontalVmScaling] mechanism. + /// + /// If this interval is defined using a small value, you may get + /// more dynamically created VMs than expected. Accordingly, this value + /// has to be trade-off. + /// For more details, see [Datacenter#getSchedulingInterval()]. private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 1; private static final int HOST_PES = 8; - /** Host RAM capacity in Megabytes. */ + /// Host RAM capacity in Megabytes. private static final long HOST_RAM = 20000; private static final int HOST_MIPS = 1000; private static final int VMS = 1; - /** - * Vm RAM capacity in Megabytes. - */ + /// Vm RAM capacity in Megabytes. private static final int VM_RAM = 1000; private static final int VM_PES = 5; private static final int VM_MIPS = 1000; - /** - * The percentage (in scale from 0 to 1) to scale VM RAM capacity up/down - * when it becomes under/overloaded. - * @see #createVerticalRamScalingForVm(Vm) - */ + /// The percentage (in scale from 0 to 1) to scale VM RAM capacity up/down + /// when it becomes under/overloaded. + /// @see #createVerticalRamScalingForVm(Vm) private static final double VM_RAM_SCALING_FACTOR = 0.1; private final CloudSimPlus simulation; @@ -128,12 +119,10 @@ public class VerticalVmRamScalingExample { private final ListYou can see that VM 11 submitted to Broker 6 targeting Datacenter 3 - * could not be placed into that DC due to lack of suitable Hosts. - * Then, the next Datacenter was selected, in a round-robin (circular) way. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 7.3.2 - * @see #createBrokersVmsAndCloudlets() - */ +/// An example showing how to make the [DatacenterBrokerSimple] +/// to set a specific target [Datacenter] to place VMs, +/// before trying the next Datacenter if VM placement fails +/// (due to lack of suitable Hosts). +/// +/// You can see that VM 11 submitted to Broker 6 targeting Datacenter 3 +/// could not be placed into that DC due to lack of suitable Hosts. +/// Then, the next Datacenter was selected, in a round-robin (circular) way. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 7.3.2 +/// @see #createBrokersVmsAndCloudlets() public class BrokerTargetDatacenterExample { private static final int DATACENTERS = 3; private static final int HOSTS_BY_DC = 5; @@ -96,10 +93,8 @@ private BrokerTargetDatacenterExample() { brokerList.forEach(BrokerTargetDatacenterExample::createCloudletsResultTable); } - /** - * Creates a broker for each available Datacenter - * and submit VMs and Cloudlets. - */ + /// Creates a broker for each available Datacenter + /// and submit VMs and Cloudlets. private void createBrokersVmsAndCloudlets() { for (final var dc : datacenterList) { final var broker = createBroker(dc); @@ -116,11 +111,9 @@ private void createBrokersVmsAndCloudlets() { } } - /** - * Creates a broker that sets a target Datacenter to initially place arriving VMs. - * @param dc the target datacenter - * @return the new broker - */ + /// Creates a broker that sets a target Datacenter to initially place arriving VMs. + /// @param dc the target datacenter + /// @return the new broker private DatacenterBrokerSimple createBroker(final Datacenter dc) { final var broker = new DatacenterBrokerSimple(simulation); broker.setName("Broker %d for %s".formatted(broker.getId(), dc)); @@ -142,9 +135,7 @@ private ListThe example uses the CloudSim Plus - * Functional DatacenterBroker that enables - * changing the method used for that goal, - * without requiring to create a subclass to accomplish that.
- * - *The example uses the class {@link DatacenterBrokerBestFit} that performs - * an optimal mapping of Cloudlets to VMs based on the free Pes in VMs. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.3.0 - */ +/// An example showing how to change the policy +/// used by a [DatacenterBroker] to map Cloudlets to VMs. +/// +/// The example uses the CloudSim Plus +/// Functional DatacenterBroker that enables +/// changing the method used for that goal, +/// without requiring to create a subclass to accomplish that. +/// +/// The example uses the class [DatacenterBrokerBestFit] that performs +/// an optimal mapping of Cloudlets to VMs based on the free Pes in VMs. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.3.0 public class CloudletToVmMappingBestFit { private static final int HOSTS = 2; private static final int HOST_PES = 8; @@ -103,9 +100,7 @@ private CloudletToVmMappingBestFit() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListThe {@link DatacenterBrokerHeuristic} is used - * with the {@link CloudletToVmMappingSimulatedAnnealing} class - * in order to find an acceptable solution with a high - * {@link HeuristicSolution#getFitness() fitness value}.
- * - *Different {@link CloudletToVmMappingHeuristic} implementations can be used - * with the {@link DatacenterBrokerHeuristic} class.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - */ +/// An example that uses a +/// [Simulated Annealing](http://en.wikipedia.org/wiki/Simulated_annealing) +/// heuristic to find a suboptimal mapping between Cloudlets and Vm's submitted to a +/// DatacenterBroker. The number of [Pe]s of Vm's and Cloudlets are defined +/// randomly. +/// +/// The [DatacenterBrokerHeuristic] is used +/// with the [CloudletToVmMappingSimulatedAnnealing] class +/// in order to find an acceptable solution with a high +/// [fitness value][HeuristicSolution#getFitness()]. +/// +/// Different [CloudletToVmMappingHeuristic] implementations can be used +/// with the [DatacenterBrokerHeuristic] class. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 public class DatacenterBrokerHeuristicExample { private static final int HOSTS_TO_CREATE = 100; private static final int VMS_TO_CREATE = 50; private static final int CLOUDLETS_TO_CREATE = 100; - /** - * Simulated Annealing (SA) parameters. - */ + /// Simulated Annealing (SA) parameters. public static final double SA_INITIAL_TEMPERATURE = 1.0; public static final double SA_COLD_TEMPERATURE = 0.0001; public static final double SA_COOLING_RATE = 0.003; @@ -89,26 +85,18 @@ public class DatacenterBrokerHeuristicExample { private ListThe {@link DatacenterBrokerHeuristic} is used - * with the {@link CloudletToVmMappingSimulatedAnnealing} class - * in order to find an acceptable solution with a high - * {@link HeuristicSolution#getFitness() fitness value}.
- * - *Different {@link CloudletToVmMappingHeuristic} implementations can be used - * with the {@link DatacenterBrokerHeuristic} class.
- * - *A comparison of cloudlet-VM mapping is done among the best fit approach, - * heuristic approach and round robin mapping.
- * - * @author Humaira Abdul Salam - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.3.8 - */ +/// An example that uses a +/// [Simulated Annealing](http://en.wikipedia.org/wiki/Simulated_annealing) +/// heuristic to find a suboptimal mapping between Cloudlets and Vm's submitted to a +/// DatacenterBroker. The number of [Pe]s of Vm's and Cloudlets are defined +/// randomly. +/// +/// The [DatacenterBrokerHeuristic] is used +/// with the [CloudletToVmMappingSimulatedAnnealing] class +/// in order to find an acceptable solution with a high +/// [fitness value][HeuristicSolution#getFitness()]. +/// +/// Different [CloudletToVmMappingHeuristic] implementations can be used +/// with the [DatacenterBrokerHeuristic] class. +/// +/// A comparison of cloudlet-VM mapping is done among the best fit approach, +/// heuristic approach and round robin mapping. +/// +/// @author Humaira Abdul Salam +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.3.8 public class DatacenterBrokersMappingComparison { - /** - * Simulated Annealing (SA) parameters. - */ + /// Simulated Annealing (SA) parameters. public static final double SA_INITIAL_TEMPERATURE = 1.0; public static final double SA_COLD_TEMPERATURE = 0.0001; public static final double SA_COOLING_RATE = 0.003; @@ -130,9 +126,7 @@ public static void main(String[] args) { System.out.println("Comparison finished!"); } - /** - * Default constructor where the simulation is built. - */ + /// Default constructor where the simulation is built. private DatacenterBrokersMappingComparison(final DatacenterBroker broker, final ContinuousDistribution random, final boolean verbose) { this.broker = broker; this.simulation = broker.getSimulation(); @@ -196,12 +190,10 @@ private void print(final boolean verbose) { "The solution based on %s mapper costs %.2f.%n", broker.getClass().getSimpleName(), brokersMappingCost); } - /** - * Randomly gets a number of PEs (CPU cores). - * - * @param maxPesNumber the maximum value to get a random number of PEs - * @return the randomly generated PEs number - */ + /// Randomly gets a number of PEs (CPU cores). + /// + /// @param maxPesNumber the maximum value to get a random number of PEs + /// @return the randomly generated PEs number private int getRandomPesNumber(final int maxPesNumber, final ContinuousDistribution random) { final double uniform = random.sample(); diff --git a/src/main/java/org/cloudsimplus/examples/brokers/DatacenterSelectionByTimeZoneExample.java b/src/main/java/org/cloudsimplus/examples/brokers/DatacenterSelectionByTimeZoneExample.java index 003a3d7..37cc399 100755 --- a/src/main/java/org/cloudsimplus/examples/brokers/DatacenterSelectionByTimeZoneExample.java +++ b/src/main/java/org/cloudsimplus/examples/brokers/DatacenterSelectionByTimeZoneExample.java @@ -50,22 +50,18 @@ import static java.util.Map.Entry; -/** - * An example showing how to use the {@link DatacenterBrokerSimple} - * to select the {@link Datacenter} closest to every submitted {@link Vm}, - * according to their {@link TimeZoned#getTimeZone() TimeZone offset}. - * - *Realize that for this feature to work, the {@link DatacenterBroker#setSelectClosestDatacenter(boolean)} - * must be called to enable it.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.8.0 - */ +/// An example showing how to use the [DatacenterBrokerSimple] +/// to select the [Datacenter] closest to every submitted [Vm], +/// according to their [TimeZone offset][TimeZoned#getTimeZone()]. +/// +/// Realize that for this feature to work, the [DatacenterBroker#setSelectClosestDatacenter(boolean)] +/// must be called to enable it. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.8.0 public class DatacenterSelectionByTimeZoneExample { - /** - * Amazon Web Services Regions (just some of them). - * @see AWS Global Infrastructure - */ + /// Amazon Web Services Regions (just some of them). + /// @see AWS Global Infrastructure private static final MapIt creates Cloudlets with different lengths to enable - * them to finish in different times. - * It also uses the {@link DatacenterBroker#setVmDestructionDelayFunction(Function)} - * method to define a {@link Function} which will be used - * to get the time delay a VM will be destroyed after becoming idle. - * Setting a delay before destroying an idle VM - * gives dynamically arrived Cloudltes the opportunity to possibly - * run inside such a VM. In this case, the VM stays idle for a - * period of time to balance the load of arrived Cloudlets - * or even to enable fault tolerance.
- * - *See the {@link DatacenterBroker#DEF_VM_DESTRUCTION_DELAY} - * for details about the default behaviour.
- * - *For details about Fault Injection, check the {@link org.cloudsimplus.faultinjection} package.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.2 - */ +/// An example showing how to create VMs and Cloudlets +/// for multiple customers, each one represented +/// by a [DatacenterBroker] object. +/// +/// It creates Cloudlets with different lengths to enable +/// them to finish in different times. +/// It also uses the [DatacenterBroker#setVmDestructionDelayFunction(Function)] +/// method to define a [Function] which will be used +/// to get the time delay a VM will be destroyed after becoming idle. +/// Setting a delay before destroying an idle VM +/// gives dynamically arrived Cloudltes the opportunity to possibly +/// run inside such a VM. In this case, the VM stays idle for a +/// period of time to balance the load of arrived Cloudlets +/// or even to enable fault tolerance. +/// +/// See the [DatacenterBroker#DEF_VM_DESTRUCTION_DELAY] +/// for details about the default behaviour. +/// +/// For details about Fault Injection, check the [org.cloudsimplus.faultinjection] package. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.2.2 public class MultipleBrokers1 { - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 5; private static final int HOSTS = 2; private static final int HOST_PES = 8; @@ -114,9 +110,7 @@ private MultipleBrokers1() { printResults(); } - /** - * Creates VMs and Cloudlets for each DatacenterBroker. - */ + /// Creates VMs and Cloudlets for each DatacenterBroker. private void createVmsAndCloudlets() { int i = 0; for (var broker : brokers) { @@ -141,17 +135,15 @@ private void printResults() { System.out.println(); } - /** - * Creates the list of {@link DatacenterBroker}s. - * It enables you to define when a broker should destroy - * an idle VM, according to a given - * {@link DatacenterBroker#setVmDestructionDelayFunction(Function) VM Destruction Delay Function}. - * - *See Issue #99 for more details.
- * - * @see DatacenterBroker#setVmDestructionDelayFunction(Function) - * @return the List of created brokers - */ + /// Creates the list of [DatacenterBroker]s. + /// It enables you to define when a broker should destroy + /// an idle VM, according to a given + /// [VM Destruction Delay Function][DatacenterBroker#setVmDestructionDelayFunction(Function)]. + /// + /// See [Issue #99](https://github.com/cloudsimplus/cloudsimplus/issues/99) for more details. + /// + /// @see DatacenterBroker#setVmDestructionDelayFunction(Function) + /// @return the List of created brokers private ListIt creates Cloudlets with different lengths to enable - * them to finish in different times. - * It also uses the {@link DatacenterBroker#setVmDestructionDelayFunction(Function)} - * method to define a {@link Function} which will be used - * to get the time delay a VM will be destroyed after becoming idle. - * Setting a delay before destroying an idle VM - * gives dynamically arrived Cloudltes the opportunity to possibly - * run inside such a VM. In this case, the VM stay idle for a - * period of time to balance the load of arrived Cloudlets - * or even to enable fault tolerance.
- * - *See the {@link DatacenterBroker#DEF_VM_DESTRUCTION_DELAY} - * for details about the default behaviour.
- * - *For details about Fault Injection, check the {@link org.cloudsimplus.faultinjection} package.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.2.2 - * @see MultipleBrokers1 - */ +/// An example showing how to create VMs and Cloudlets +/// for multiple customers, each one represented +/// by a [DatacenterBroker] object. +/// +/// It creates Cloudlets with different lengths to enable +/// them to finish in different times. +/// It also uses the [DatacenterBroker#setVmDestructionDelayFunction(Function)] +/// method to define a [Function] which will be used +/// to get the time delay a VM will be destroyed after becoming idle. +/// Setting a delay before destroying an idle VM +/// gives dynamically arrived Cloudltes the opportunity to possibly +/// run inside such a VM. In this case, the VM stay idle for a +/// period of time to balance the load of arrived Cloudlets +/// or even to enable fault tolerance. +/// +/// See the [DatacenterBroker#DEF_VM_DESTRUCTION_DELAY] +/// for details about the default behaviour. +/// +/// For details about Fault Injection, check the [org.cloudsimplus.faultinjection] package. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.2.2 +/// @see MultipleBrokers1 public class MultipleBrokers2 { - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 5; private static final int HOSTS = 2; private static final int HOST_PES = 8; @@ -129,48 +125,43 @@ private MultipleBrokers2() { printResults(); } - /** - * Statically submits a Cloudlet with a specific delay, - * meaning it will start executing only after the defined time. - * The Cloudlet is submitted before the simulation starts. - */ + /// Statically submits a Cloudlet with a specific delay, + /// meaning it will start executing only after the defined time. + /// The Cloudlet is submitted before the simulation starts. private void submitCloudletWithDelay() { final var cloudlet = createCloudlet(cloudletList.size(), CLOUDLET_LENGTH); cloudlet.setSubmissionDelay(35); brokers.get(1).submitCloudlet(cloudlet); } - /** - * Dynamically submits a cloudlet during simulation execution. - * This method is called every time when the simulation clock - * increases. - * The created Cloudlet is submitted only at a specific simulation time. - * - *Realize the interval in which this method is called is defined - * according to the {@link #SCHEDULING_INTERVAL}.
- * - *Different from the {@link #submitCloudletWithDelay()} method, - * which creates all Cloudtets when the simulation starts and make them wait - * to start executing, this method is called dynamically during - * simulation. It defines internally, when - * we want the Cloudlet to be submitted. - * The method is called by the {@link CloudSimPlus} object - * because an {@link EventListener} was added to be - * notified when the simulation clock changes. - * This way it allows, between uncountable possibilities, - * to define specific conditions when a new Cloudlet should be submitted - * to a broker. - *
- * - *The dynamic way of submitting Cloudlets is more flexible because it allows you to define - * any condition you want inside a method such as this one. - * That condition may include any other variables besides the time.
- * - * @param e information about the generated event - * @return - * @see Datacenter#getSchedulingInterval() - * @see CloudSimPlus#addOnClockTickListener(EventListener) - */ + /// Dynamically submits a cloudlet during simulation execution. + /// This method is called every time when the simulation clock + /// increases. + /// The created Cloudlet is submitted only at a specific simulation time. + /// + /// Realize the interval in which this method is called is defined + /// according to the [#SCHEDULING_INTERVAL]. + /// + /// Different from the [#submitCloudletWithDelay()] method, + /// which creates all Cloudtets when the simulation starts and make them wait + /// to start executing, this method is called dynamically during + /// simulation. It defines internally, when + /// we want the Cloudlet to be submitted. + /// The method is called by the [CloudSimPlus] object + /// because an [EventListener] was added to be + /// notified when the simulation clock changes. + /// This way it allows, between uncountable possibilities, + /// to define specific conditions when a new Cloudlet should be submitted + /// to a broker. + /// + /// The dynamic way of submitting Cloudlets is more flexible because it allows you to define + /// any condition you want inside a method such as this one. + /// That condition may include any other variables besides the time. + /// + /// @param e information about the generated event + /// @return + /// @see Datacenter#getSchedulingInterval() + /// @see CloudSimPlus#addOnClockTickListener(EventListener) private void dynamicCloudletArrival(EventInfo e) { if((int)e.getTime() != 35) { return; @@ -182,16 +173,14 @@ private void dynamicCloudletArrival(EventInfo e) { broker.submitCloudlet(cloudlet); } - /** - * Creates VMs and Cloudlets for each DatacenterBroker. - * It enables you to define when a broker should destroy - * an idle VM, according to a given - * {@link DatacenterBroker#setVmDestructionDelayFunction(Function) VM Destruction Delay Function}. - * - *See Issue #99 for more details.
- * - * @see DatacenterBroker#setVmDestructionDelayFunction(Function) - */ + /// Creates VMs and Cloudlets for each DatacenterBroker. + /// It enables you to define when a broker should destroy + /// an idle VM, according to a given + /// [VM Destruction Delay Function][DatacenterBroker#setVmDestructionDelayFunction(Function)]. + /// + /// See [Issue #99](https://github.com/cloudsimplus/cloudsimplus/issues/99) for more details. + /// + /// @see DatacenterBroker#setVmDestructionDelayFunction(Function) private void createVmsAndCloudlets() { int i = 0; for (var broker : brokers) { @@ -226,9 +215,7 @@ private ListEach created Datacenter has hosts with more PEs than the previous Datacenter. - * This way, only the Datacenter 4 will have Hosts to place the - * created VMs.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.8.0 - */ +/// An example showing how the [DatacenterBrokerSimple] +/// selects the next [Datacenter] when the previous one +/// is not able to create all [Vm]s due to lack +/// of suitable Hosts. +/// +/// Each created Datacenter has hosts with more PEs than the previous Datacenter. +/// This way, only the Datacenter 4 will have Hosts to place the +/// created VMs. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.8.0 public class SelectNextDatacenterExample { private static final int DATACENTERS = 5; private static final int HOSTS = 5; @@ -99,11 +97,9 @@ private SelectNextDatacenterExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a List of Datacenters, each Datacenter having - * Hosts with a number of PEs higher than the previous Datacenter. - * @return - */ + /// Creates a List of Datacenters, each Datacenter having + /// Hosts with a number of PEs higher than the previous Datacenter. + /// @return private List- * Some examples include the utilization of multiple brokers - * to represent multiple cloud customers, the utilization - * of a {@link org.cloudsimplus.examples.brokers.DatacenterBrokerHeuristicExample} - * that maps Cloudlets to VMs based on the Simulated Annealing Heuristic, - * and other example showing how to dynamically change the policy used - * to map Cloudlets to VMs without requiring to subclass the - * {@link org.cloudsimplus.brokers.DatacenterBrokerSimple}. - *
+ * Copyright (C) 2015-2021 Universidade da Beira Interior (UBI, Portugal) and + * the Instituto Federal de Educação Ciência e Tecnologia do Tocantins (IFTO, Brazil). * - * @author Manoel Campos da Silva Filho + * This file is part of CloudSim Plus. + * + * CloudSim Plus is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CloudSim Plus is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CloudSim Plus. If not, seeThis example uses CloudSim Plus Listener features to intercept when - * the a Cloudlet finishes its execution to then request - * the creation of a new Cloudlet. It uses the Java 8+ Lambda Functions features - * to pass a listener to the mentioned Cloudlet, by means of the - * {@link Cloudlet#addOnFinishListener(EventListener)} method.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 2.2.0 - */ +/// An example showing how to dynamically create one Cloudlet after the previous one finishes. +/// It stops creating Cloudlets when the number reaches [#CLOUDLETS]. +/// +/// This example uses CloudSim Plus Listener features to intercept when +/// the a Cloudlet finishes its execution to then request +/// the creation of a new Cloudlet. It uses the Java 8+ Lambda Functions features +/// to pass a listener to the mentioned Cloudlet, by means of the +/// [Cloudlet#addOnFinishListener(EventListener)] method. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 2.2.0 public class CreateCloudletAfterLastFinishedOne { private static final int HOSTS = 2; private static final int VMS = 4; @@ -74,19 +72,15 @@ public class CreateCloudletAfterLastFinishedOne { private final Datacenter datacenter; private final CloudSimPlus simulation; - /** - * Starts the example execution, calling the class constructor\ - * to build and run the simulation. - * - * @param args command line parameters - */ + /// Starts the example execution, calling the class constructor\ + /// to build and run the simulation. + /// + /// @param args command line parameters public static void main(String[] args) { new CreateCloudletAfterLastFinishedOne(); } - /** - * Default constructor that builds and starts the simulation. - */ + /// Default constructor that builds and starts the simulation. private CreateCloudletAfterLastFinishedOne() { /*Enables just some level of log messages. Make sure to import org.cloudsimplus.util.Log;*/ @@ -124,12 +118,9 @@ private ListThis example uses CloudSim Plus Listener features to intercept when - * the first Cloudlet finishes its execution to then request - * the creation of new VMs and Cloudlets. It uses the Java 8+ Lambda Functions features - * to pass a listener to the mentioned Cloudlet, by means of the - * {@link Cloudlet#addOnFinishListener(EventListener)} method.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.0 - * - * @see Cloudlet#addOnFinishListener(EventListener) - * @see EventListener - */ +/// An example showing how to dynamically create VMs and Cloudlets during simulation +/// executing using the exclusive CloudSim Plus [DatacenterBroker] implementations +/// and Listener features. Using such features, **it is not required to create DatacenterBrokers in runtime +/// in order to allow dynamic submission of VMs and Cloudlets.** +/// +/// This example uses CloudSim Plus Listener features to intercept when +/// the first Cloudlet finishes its execution to then request +/// the creation of new VMs and Cloudlets. It uses the Java 8+ Lambda Functions features +/// to pass a listener to the mentioned Cloudlet, by means of the +/// [Cloudlet#addOnFinishListener(EventListener)] method. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.0 +/// +/// @see Cloudlet#addOnFinishListener(EventListener) +/// @see EventListener public class DynamicCreationOfVmsAndCloudletsExample { private final CloudSimPlus simulation; private final DatacenterBrokerSimple broker0; @@ -75,9 +73,7 @@ public static void main(String[] args) { new DynamicCreationOfVmsAndCloudletsExample(); } - /** - * Default constructor that builds the simulation. - */ + /// Default constructor that builds the simulation. private DynamicCreationOfVmsAndCloudletsExample() { /*Enables just some level of log messages. Make sure to import org.cloudsimplus.util.Log;*/ @@ -132,11 +128,9 @@ private void createAndSubmitVmsAndCloudlets(int vmsToCreate, int cloudletsToCrea broker0.submitCloudletList(newCloudletList); } - /** - * Dynamically creates and submits a set of VMs to the broker when - * the first cloudlet finishes. - * @param eventInfo information about the fired event - */ + /// Dynamically creates and submits a set of VMs to the broker when + /// the first cloudlet finishes. + /// @param eventInfo information about the fired event private void submitNewVmsAndCloudletsToBroker(CloudletVmEventInfo eventInfo) { final int numberOfNewVms = 2; final int numberOfCloudletsByVm = 4; diff --git a/src/main/java/org/cloudsimplus/examples/dynamic/DynamicHostCreation.java b/src/main/java/org/cloudsimplus/examples/dynamic/DynamicHostCreation.java index 37c656c..f773ad0 100755 --- a/src/main/java/org/cloudsimplus/examples/dynamic/DynamicHostCreation.java +++ b/src/main/java/org/cloudsimplus/examples/dynamic/DynamicHostCreation.java @@ -48,57 +48,50 @@ import java.util.ArrayList; import java.util.List; -/** - * An example showing how to create Hosts at simulation runtime, - * enabling to simulate the physical expansion of a Datacenter by - * the addition of new Hosts (PMs). - * The example starts by creating 2 hosts and 4 VMs (2 VMs for each Host). - * Then it creates 4 Cloudlets (1 for each VM). - * - *After the simulation starts and reaches 5 seconds (defined in {@link #SCHEDULING_INTERVAL}), - * it's created a new Host and VM. Two new Cloudlets are created for this new VM - * the Cloudlets and the VM is submitted by the broker to the Datacenter. - * Since the Hosts created before starting the simulation - * don't have enough PEs to place this new VM, the {@link VmAllocationPolicy} - * will chose the 5th Host (created dynamically) to place that VM - * and run the Cloudlets. - *
- * - *Since these two new Cloudlets are running in the same VM, - * which is using a {@link CloudletSchedulerTimeShared}, and there aren't - * enough VM PEs for all the 2 Cloudlets, they will spend the double of the time to finish, - * because they will share the VM PEs. - * Realize that the start time of these 2 dynamically created Cloudlets is 5, - * showing they were submitted to the broker just that time. - *
- * - *To allow track the simulation time and know when the clock is in 5 seconds, - * it is required to call {@link Datacenter#setSchedulingInterval(double)} - * to set the scheduling interval. Check the method documentation for more details. - * This example uses the CloudSim Plus Listener features to enable your simulation - * to be notified when some event happens. - * In this case, it's being used the {@link CloudSimPlus#addOnClockTickListener(EventListener)} - * to pass a {@link EventListener} object that will be notified - * when the simulation clock advances. - *
- * - *In fact, this {@link EventListener} is a Java 8+ {@link FunctionalInterface} - * that enables using Lambda Expression - * or method references in order to provide a {@link FunctionalInterface}. - * This example uses a reference to the {@link #clockTickListener(EventInfo)} method - * as being the {@link EventListener} required by the {@link CloudSimPlus#addOnClockTickListener(EventListener)}.
- * - *Lambda Expressions, method references and Functional Interfaces are Java 8+ features. - * If you don't know what these features are, I suggest checking out this - * tutorial
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 1.3.0 - */ +/// An example showing how to create Hosts at simulation runtime, +/// enabling to simulate the physical expansion of a Datacenter by +/// the addition of new Hosts (PMs). +/// The example starts by creating 2 hosts and 4 VMs (2 VMs for each Host). +/// Then it creates 4 Cloudlets (1 for each VM). +/// +/// After the simulation starts and reaches 5 seconds (defined in [#SCHEDULING_INTERVAL]), +/// it's created a new Host and VM. Two new Cloudlets are created for this new VM +/// the Cloudlets and the VM is submitted by the broker to the Datacenter. +/// Since the Hosts created before starting the simulation +/// don't have enough PEs to place this new VM, the [VmAllocationPolicy] +/// will chose the 5th Host (created dynamically) to place that VM +/// and run the Cloudlets. +/// +/// Since these two new Cloudlets are running in the same VM, +/// which is using a [CloudletSchedulerTimeShared], and there aren't +/// enough VM PEs for all the 2 Cloudlets, they will spend the double of the time to finish, +/// because they will share the VM PEs. +/// Realize that the start time of these 2 dynamically created Cloudlets is 5, +/// showing they were submitted to the broker just that time. +/// +/// To allow track the simulation time and know when the clock is in 5 seconds, +/// it is required to call [Datacenter#setSchedulingInterval(double)] +/// to set the scheduling interval. Check the method documentation for more details. +/// This example uses the CloudSim Plus Listener features to enable your simulation +/// to be notified when some event happens. +/// In this case, it's being used the [CloudSimPlus#addOnClockTickListener(EventListener)] +/// to pass a [EventListener] object that will be notified +/// when the simulation clock advances. +/// +/// In fact, this [EventListener] is a Java 8+ [FunctionalInterface] +/// that enables using Lambda Expression +/// or method references in order to provide a [FunctionalInterface]. +/// This example uses a reference to the [#clockTickListener(EventInfo)] method +/// as being the [EventListener] required by the [CloudSimPlus#addOnClockTickListener(EventListener)]. +/// +/// **Lambda Expressions, method references and Functional Interfaces are Java 8+ features.** +/// If you don't know what these features are, I suggest checking out this +/// [tutorial](http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html) +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 1.3.0 public class DynamicHostCreation { - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 5; private static final int HOSTS = 2; @@ -143,10 +136,8 @@ private DynamicHostCreation() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Event listener which is called every time the simulation clock advances. - * @param info information about the event happened. - */ + /// Event listener which is called every time the simulation clock advances. + /// @param info information about the event happened. private void clockTickListener(final EventInfo info) { final int time = (int)info.getTime(); @@ -173,9 +164,7 @@ private void clockTickListener(final EventInfo info) { } } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListVMs are allocated based on a Best Fit allocation policy, which - * selects the suitable Host with the lowest number of available PEs - * that is enough to run the VM. - * This policy is dynamically defined by changing the {@link Function} - * of the {@link VmAllocationPolicy}, without requiring to create - * a new class. The {@link VmAllocationPolicySimple} used in this example ignores power usage of - * Hosts. This way, it isn't required to set a PowerModel for Hosts. - *
- * - * It is used some constants to create simulation objects such as - * {@link DatacenterSimple}, {@link Host} and {@link Vm}. - * The values of these constants were careful and accordingly chosen to allow - * migration of VMs due to either under and overloaded hosts and - * to allow one developer to know exactly how the simulation will run - * and what will be the final results. - * Several values impact the simulation results, such as - * hosts CPU capacity and number of PEs, VMs and cloudlets requirements - * and even VM bandwidth (that defines the VM migration time). - * - *This way, if you want to change these values, you must - * define new appropriated ones to allow the simulation - * to run correctly.
- * - * @author Manoel Campos da Silva Filho - */ +/// An example showing how to create 1 Datacenter with 5 hosts, +/// 1 VM by host and 1 cloudlet by VM and perform VM allocation by +/// using Java 8+ Functional Programming to change, at runtime, the +/// policy used by a [VmAllocationPolicy]. +/// +/// VMs are allocated based on a **Best Fit allocation policy**, which +/// selects the suitable Host with the lowest number of available PEs +/// that is enough to run the VM. +/// This policy is dynamically defined by changing the [Function] +/// of the [VmAllocationPolicy], without requiring to create +/// a new class. The [VmAllocationPolicySimple] used in this example ignores power usage of +/// Hosts. This way, it isn't required to set a PowerModel for Hosts. +/// +/// It is used some constants to create simulation objects such as +/// [DatacenterSimple], [Host] and [Vm]. +/// The values of these constants were careful and accordingly chosen to allow +/// migration of VMs due to either under and overloaded hosts and +/// to allow one developer to know exactly how the simulation will run +/// and what will be the final results. +/// Several values impact the simulation results, such as +/// hosts CPU capacity and number of PEs, VMs and cloudlets requirements +/// and even VM bandwidth (that defines the VM migration time). +/// +/// This way, if you want to change these values, you must +/// define new appropriated ones to allow the simulation +/// to run correctly. +/// +/// @author Manoel Campos da Silva Filho public final class DynamicVmAllocationPolicyBestFitExample { private static final int SCHEDULE_INTERVAL = 5; @@ -127,9 +124,7 @@ public final class DynamicVmAllocationPolicyBestFitExample { private static final long CLOUDLET_FILESIZE = 300; private static final long CLOUDLET_OUTPUTSIZE = 300; - /** - * List of all created VMs. - */ + /// List of all created VMs. private final ListFinally, considering there aren't enough hosts for all VMs, this example shows - * how to make the broker to destroy idle VMs after a while to open room for new VMs. - * Check {@link #createBroker()} for details. - *
- * - * @author Fabian Mastenbroek - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 7.2.1 - */ +/// An example showing how to submit VMs to the broker with different delays. +/// This way, Cloudlets bound to such delayed VMs just start +/// executing after the respective VM is placed into some Host. +/// Since submitted cloudlets are not explicitly delayed, you can see in results +/// that, at the end, they are delayed due to VM delay. +/// +/// Finally, considering there aren't enough hosts for all VMs, this example shows +/// how to make the broker to destroy idle VMs after a while to open room for new VMs. +/// Check [#createBroker()] for details. +/// +/// @author Fabian Mastenbroek +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 7.2.1 public class DynamicVmsArrival2 { private static final int HOSTS = 1; - /** - * Number of Processor Elements (CPU Cores) of each Host. - */ + /// Number of Processor Elements (CPU Cores) of each Host. private static final int HOST_PES_NUMBER = 4; - /** - * Number of Processor Elements (CPU Cores) of each VM and cloudlet. - */ + /// Number of Processor Elements (CPU Cores) of each VM and cloudlet. private static final int VM_PES_NUMBER = 4; - /** - * Number of Cloudlets to create simultaneously. - * Other cloudlets will be enqueued. - */ + /// Number of Cloudlets to create simultaneously. + /// Other cloudlets will be enqueued. private static final int CLOUDLETS_NUMBER = VM_PES_NUMBER; private final ListThe example is useful when you want to run a simulation - * for a specific amount of time. - * For instance, if you want to run a simulation for 24 hours, - * you just need to call {@code simulation.terminateAt(60*60*24)} (realize the value is in seconds).
- * - *It creates 4 Cloudlets and 2 VMs statically. - * These Cloudlets will take 10 seconds to finish, but - * the simulation is set to terminate - * only after the time defined in {@link #TIME_TO_TERMINATE_SIMULATION}. - * - * This way, the simulation keeps waiting for dynamically - * arrived events. Then, at a {@link #TIME_TO_CREATE_NEW_CLOUDLET defined time}, - * new Cloudlets are created. - *
- * - *The example uses the CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically creating Cloudlets and VMs at runtime. - * It relies on - * Java 8 Method References - * to set a method to be called for {@link Simulation#addOnClockTickListener(EventListener) onClockTick events}. - * It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. - *
- * - *Since the simulation was set to keep waiting for new events - * until a defined time, the clock will be updated - * even if no event arrives, to simulate time passing. - * Check the {@link Simulation#terminateAt(double)} for details. - *
- * - *At the time defined in {@link #TIME_TO_CREATE_NEW_CLOUDLET}, - * 1 Cloudlet and 1 VM is created, so the results will show 5 Cloudlets. - * The simulation will just end at the specified time. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 2.3.0 - * @see RandomCloudletsArrivalExample - */ +/// Shows how to keep the simulation running, even +/// when there is no event to be processed anymore. +/// It calls the [Simulation#terminateAt(double)] to define +/// the time the simulation must be terminated. +/// +/// The example is useful when you want to run a simulation +/// for a specific amount of time. +/// For instance, if you want to run a simulation for 24 hours, +/// you just need to call `simulation.terminateAt(60*60*24)` (realize the value is in seconds). +/// +/// It creates 4 Cloudlets and 2 VMs statically. +/// These Cloudlets will take 10 seconds to finish, but +/// the simulation is set to terminate +/// only after the time defined in [#TIME_TO_TERMINATE_SIMULATION]. +/// +/// This way, the simulation keeps waiting for dynamically +/// arrived events. Then, at a [defined time][#TIME_TO_CREATE_NEW_CLOUDLET], +/// new Cloudlets are created. +/// +/// The example uses the CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically creating Cloudlets and VMs at runtime. +/// It relies on +/// [Java 8 Method References](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) +/// to set a method to be called for [onClockTick events][Simulation#addOnClockTickListener(EventListener)]. +/// It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. +/// +/// Since the simulation was set to keep waiting for new events +/// until a defined time, the clock will be updated +/// even if no event arrives, to simulate time passing. +/// Check the [Simulation#terminateAt(double)] for details. +/// +/// At the time defined in [#TIME_TO_CREATE_NEW_CLOUDLET], +/// 1 Cloudlet and 1 VM is created, so the results will show 5 Cloudlets. +/// The simulation will just end at the specified time. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 2.3.0 +/// @see RandomCloudletsArrivalExample public class KeepSimulationRunningExample { - /** - * @see #createDynamicCloudletAndVm(EventInfo) - */ + /// @see #createDynamicCloudletAndVm(EventInfo) private static final double TIME_TO_CREATE_NEW_CLOUDLET = 15; - /** - * @see Simulation#terminateAt(double) - */ + /// @see Simulation#terminateAt(double) private static final double TIME_TO_TERMINATE_SIMULATION = TIME_TO_CREATE_NEW_CLOUDLET*2; - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 3; @@ -158,9 +146,7 @@ private KeepSimulationRunningExample() { new CloudletsTableBuilder(cloudletFinishedList).build(); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListThe example is useful when you want to run a simulation - * for a specific amount of time, for instance, to wait random arrival - * or requests (such as Cloudlets and VMs). - * Lets say you want to run a simulation for 24 hours. - * This way, you just need to call {@code simulation.terminateAt(60*60*24)} (realize the value is in seconds).
- * - *It creates Cloudlets randomly, according to a pseudo random number generator (PRNG) following the - * {@link UniformDistr uniform distribution}. You can change the PRNG as you wish, - * for instance, to use a {@link PoissonDistr} arrival process.
- * - *The example uses the CloudSim Plus {@link EventListener} feature - * to enable monitoring the simulation and dynamically creating Cloudlets and VMs at runtime. - * It relies on - * Java 8 Method References - * to set a method to be called for {@link Simulation#addOnClockTickListener(EventListener) onClockTick events}. - * It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. - *
- * - *Since the simulation was set to keep waiting for new events - * until a defined time, the clock will be updated - * even if no event arrives, to simulate time passing. - * Check the {@link Simulation#terminateAt(double)} for details. - * The simulation will just end at the specified time. - *
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 4.0.4 - * @see KeepSimulationRunningExample - */ +/// Shows how to keep the simulation running, even +/// when there is no event to be processed anymore. +/// It calls the [Simulation#terminateAt(double)] to define +/// the time the simulation must be terminated. +/// +/// The example is useful when you want to run a simulation +/// for a specific amount of time, for instance, to wait random arrival +/// or requests (such as Cloudlets and VMs). +/// Lets say you want to run a simulation for 24 hours. +/// This way, you just need to call `simulation.terminateAt(60*60*24)` (realize the value is in seconds). +/// +/// It creates Cloudlets randomly, according to a pseudo random number generator (PRNG) following the +/// [uniform distribution][UniformDistr]. You can change the PRNG as you wish, +/// for instance, to use a [PoissonDistr] arrival process. +/// +/// The example uses the CloudSim Plus [EventListener] feature +/// to enable monitoring the simulation and dynamically creating Cloudlets and VMs at runtime. +/// It relies on +/// [Java 8 Method References](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html) +/// to set a method to be called for [onClockTick events][Simulation#addOnClockTickListener(EventListener)]. +/// It enables getting notifications when the simulation clock advances, then creating and submitting new cloudlets. +/// +/// Since the simulation was set to keep waiting for new events +/// until a defined time, the clock will be updated +/// even if no event arrives, to simulate time passing. +/// Check the [Simulation#terminateAt(double)] for details. +/// The simulation will just end at the specified time. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 4.0.4 +/// @see KeepSimulationRunningExample public class RandomCloudletsArrivalExample { - /** - * @see Simulation#terminateAt(double) - */ + /// @see Simulation#terminateAt(double) private static final double TIME_TO_TERMINATE_SIMULATION = 30; - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 8; @@ -105,9 +97,7 @@ public class RandomCloudletsArrivalExample { private static final int CLOUDLET_PES = 2; private static final int CLOUDLET_LENGTH = 10000; - /** - * Number of Cloudlets to be statically created when the simulation starts. - */ + /// Number of Cloudlets to be statically created when the simulation starts. private static final int INITIAL_CLOUDLETS_NUMBER = 5; private final CloudSimPlus simulation; @@ -152,9 +142,7 @@ private RandomCloudletsArrivalExample() { randomCloudlets+" randomly created during simulation runtime)"); } - /** - * Creates a Datacenter and its Hosts. - */ + /// Creates a Datacenter and its Hosts. private Datacenter createDatacenter() { final var hostList = new ArrayListThe example uses the new Cloudlet listeners to get these - * notifications while the simulation is running.
- * - * @see Cloudlet#addOnFinishListener(EventListener) - * @see EventListener - * - * @author Manoel Campos da Silva Filho - */ +/// A simple example showing how to create a data center with 1 host and run +/// cloudlets on it, and receive notifications when each cloudlet finishes executing. +/// +/// The example uses the new Cloudlet listeners to get these +/// notifications while the simulation is running. +/// +/// @see Cloudlet#addOnFinishListener(EventListener) +/// @see EventListener +/// +/// @author Manoel Campos da Silva Filho public class CloudletListenersExample1 { - /** - * Number of Processor Elements (CPU Cores) of each Host. - */ + /// Number of Processor Elements (CPU Cores) of each Host. private static final int HOST_PES_NUMBER = 4; - /** - * Number of Processor Elements (CPU Cores) of each VM and cloudlet. - */ + /// Number of Processor Elements (CPU Cores) of each VM and cloudlet. private static final int VM_PES_NUMBER = 2; - /** - * Number of Cloudlets to create. - */ + /// Number of Cloudlets to create. private static final int NUMBER_OF_CLOUDLETS = 4; private final List- * Despite there isn't the concept of multi-cloud environments on CloudSim Plus, - * this example can be used to simulate that. - * Lets say you have 2 or more datacenters where some of them belong to a cloud provider - * and other ones belong to another provider. - * Since the example is performing VM migration between those datacenters, - * we can consider in that case we are performing VM migration between - * cloud providers. - *
- * - *Realize the example is creating datacenters in private and public clouds. - * This way, when migrating VMs from/to a public cloud, non-live migration will be performed, - * where the VM is shutdown and restarted on the target datacenter. - * Check {@link DatacenterCharacteristics#getDistribution()} for details.
- * - *The example performs VM migration using - * a {@link VmAllocationPolicyMigrationFirstFitStaticThreshold}. - * Such a policy migrates VMs based on - * a static host CPU utilization threshold. - * The VmAllocationPolicy used in this example ignores power consumption of Hosts. - * This way, it isn't required to set a PowerModel for Hosts.
- * - *A Host from Datacenter 1 will become overloaded, - * however, there will be no other suitable Host from the same datacenter - * to migrate VMs to. - * Therefore, intra-datacenter migration is not possible - * and the next datacenter available will be tried next time.
- * - *The {@link VmAllocationPolicyMigrationFirstFitStaticThreshold} - * allows setting static under/over CPU utilization thresholds to - * enable VM migration. - * The example uses a {@link UtilizationModelDynamic} to define that CPU usage of cloudlets - * increases along simulation time. - *
- * - *Some constants are used to create simulation objects such as - * {@link DatacenterSimple}, {@link Host} and {@link Vm}. - * The values of these constants were careful and accordingly chosen to allow: - * (i) migration of VMs due to either under and overloaded hosts; and - * (ii) the researcher to know exactly how the simulation will run - * and what will be the final results. - *
- * - *- * Several values impact simulation results, such as - * (i) hosts CPU capacity and number of PEs, - * (ii) VMs and cloudlets requirements and - * (iii) even VM bandwidth (which defines the VM migration time). - * - * This way, if you want to change these values, you must - * define new appropriated ones to allow the simulation - * to run correctly.
- * - *Realize that Host State History is just collected - * if you enable that by calling {@link Host#setStateHistoryEnabled(boolean)}.
- * - * @author Manoel Campos da Silva Filho - * @since CloudSim Plus 7.2.0 - */ +/// An example showing how to create 2 Datacenters having different +/// number of Hosts and VMs with heterogeneous capacity/requirements. +/// +/// Despite there isn't the concept of multi-cloud environments on CloudSim Plus, +/// this example can be used to simulate that. +/// Lets say you have 2 or more datacenters where some of them belong to a cloud provider +/// and other ones belong to another provider. +/// Since the example is performing VM migration between those datacenters, +/// we can consider in that case we are performing VM migration between +/// cloud providers. +/// +/// Realize the example is creating datacenters in private and public clouds. +/// This way, when migrating VMs from/to a public cloud, non-live migration will be performed, +/// where the VM is shutdown and restarted on the target datacenter. +/// Check [DatacenterCharacteristics#getDistribution()] for details. +/// +/// The example performs VM migration using +/// a [VmAllocationPolicyMigrationFirstFitStaticThreshold]. +/// Such a policy migrates VMs based on +/// a static host CPU utilization threshold. +/// The VmAllocationPolicy used in this example ignores power consumption of Hosts. +/// This way, it isn't required to set a PowerModel for Hosts. +/// +/// A Host from Datacenter 1 will become overloaded, +/// however, there will be no other suitable Host from the same datacenter +/// to migrate VMs to. +/// Therefore, intra-datacenter migration is not possible +/// and the next datacenter available will be tried next time. +/// +/// The [VmAllocationPolicyMigrationFirstFitStaticThreshold] +/// allows setting static under/over CPU utilization thresholds to +/// enable VM migration. +/// The example uses a [UtilizationModelDynamic] to define that CPU usage of cloudlets +/// increases along simulation time. +/// +/// Some constants are used to create simulation objects such as +/// [DatacenterSimple], [Host] and [Vm]. +/// The values of these constants were careful and accordingly chosen to allow: +/// (i) migration of VMs due to either under and overloaded hosts; and +/// (ii) the researcher to know exactly how the simulation will run +/// and what will be the final results. +/// +/// Several values impact simulation results, such as +/// (i) hosts CPU capacity and number of PEs, +/// (ii) VMs and cloudlets requirements and +/// (iii) even VM bandwidth (which defines the VM migration time). +/// +/// This way, if you want to change these values, you must +/// define new appropriated ones to allow the simulation +/// to run correctly. +/// +/// Realize that Host State History is just collected +/// if you enable that by calling [Host#setStateHistoryEnabled(boolean)]. +/// +/// @author Manoel Campos da Silva Filho +/// @since CloudSim Plus 7.2.0 public final class InterDatacenterMigration1 { - /** @see Datacenter#getSchedulingInterval() */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 2; - /** - * A matrix where each row defines the PEs capacity for hosts in one Datacenter. - * Each item is the number of PEs for a Host. - * The number of rows (length of the matrix) define the number of Datacenters to create. - * The number of cols (length of each row) define the number of Hosts for each Datacenter. - * - *The total number of items define the number of Hosts to create.
- */ + /// A matrix where each row defines the PEs capacity for hosts in one Datacenter. + /// Each item is the number of PEs for a Host. + /// The number of rows (length of the matrix) define the number of Datacenters to create. + /// The number of cols (length of each row) define the number of Hosts for each Datacenter. + /// + /// The total number of items define the number of Hosts to create. private static final int[][] DC_HOST_PES = {{4, 5}, {8, 8, 8, 16}}; - /** - * The percentage of host CPU usage that trigger VM migration - * due to under utilization (in scale from 0 to 1, where 1 is 100%). - */ + /// The percentage of host CPU usage that trigger VM migration + /// due to under utilization (in scale from 0 to 1, where 1 is 100%). private static final double HOST_UNDER_UTILIZATION_THRESHOLD_FOR_VM_MIGRATION = 0.1; - /** - * The percentage of host CPU usage that trigger VM migration - * due to over utilization (in scale from 0 to 1, where 1 is 100%). - */ + /// The percentage of host CPU usage that trigger VM migration + /// due to over utilization (in scale from 0 to 1, where 1 is 100%). private static final double HOST_OVER_UTILIZATION_THRESHOLD_FOR_VM_MIGRATION = 0.78; - /** @see Datacenter#setHostSearchRetryDelay(double) */ + /// @see Datacenter#setHostSearchRetryDelay(double) private static final int HOST_SEARCH_RETRY_DELAY = 10; - /** - * The time spent during VM migration depend on the - * bandwidth of the target Host. - * By default, a {@link Datacenter} - * uses only 50% of the BW to migrate VMs, while the - * remaining capacity is used for VM communication. - * This can be changed by calling - * {@link DatacenterSimple#setBandwidthPercentForMigration(double)}. - * - *The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity - * is used for VM migration, only 1000 MB/s will be available for this process. - * The time that takes to migrate a Vm depend on the VM RAM capacity. - * Since VMs in this example are created with 2000 MB of RAM, any migration - * will take 2 seconds to finish, as can be seen in the logs. - */ + /// The time spent during VM migration depend on the + /// bandwidth of the target Host. + /// By default, a [Datacenter] + /// uses only 50% of the BW to migrate VMs, while the + /// remaining capacity is used for VM communication. + /// This can be changed by calling + /// [DatacenterSimple#setBandwidthPercentForMigration(double)]. + /// + /// The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity + /// is used for VM migration, only 1000 MB/s will be available for this process. + /// The time that takes to migrate a Vm depend on the VM RAM capacity. + /// Since VMs in this example are created with 2000 MB of RAM, any migration + /// will take 2 seconds to finish, as can be seen in the logs. private static final long HOST_BW = 16_000L; //Mbps private static final int HOST_MIPS = 1000; //for each PE - /** - * RAM capacity for created Hosts. - * The length of this array must be the length of the largest row on {@link #DC_HOST_PES} matrix. - */ + /// RAM capacity for created Hosts. + /// The length of this array must be the length of the largest row on [#DC_HOST_PES] matrix. private static final long[] HOST_RAM = {50_000, 50_000, 50_000, 50_000}; //host memory (MB) private static final long HOST_STORAGE = 1_000_000; //host storage (MB) - /** - * A matrix where each row defines the number of PEs required by each VM in one Datacenter. - * The total number of items define the number of VMs to create. - * - *
The length of this matrix (number of rows) must be equal to the number of datacenters, - * defined by the length of {@link #DC_HOST_PES}.
- */ + /// A matrix where each row defines the number of PEs required by each VM in one Datacenter. + /// The total number of items define the number of VMs to create. + /// + /// The length of this matrix (number of rows) must be equal to the number of datacenters, + /// defined by the length of [#DC_HOST_PES]. private static final int[][] VM_PES = {{3, 2, 2}, {4, 4, 4}}; private static final int VM_MIPS = 1000; //for each PE @@ -198,21 +179,17 @@ public final class InterDatacenterMigration1 { private static final long CLOUDLET_FILESIZE = 300; private static final long CLOUDLET_OUTPUT_SIZE = 300; - /** - * The percentage of CPU that a cloudlet will use when - * it starts executing (in scale from 0 to 1, where 1 is 100%). - * For each cloudlet create, this value is used - * as a base to define CPU usage. - * @see #createAndSubmitCloudlets(DatacenterBroker) - */ + /// The percentage of CPU that a cloudlet will use when + /// it starts executing (in scale from 0 to 1, where 1 is 100%). + /// For each cloudlet create, this value is used + /// as a base to define CPU usage. + /// @see #createAndSubmitCloudlets(DatacenterBroker) private static final double CLOUDLET_INITIAL_CPU_PERCENTAGE = 0.5; - /** - * Defines the speed (in percentage) that CPU usage of a cloudlet - * will increase during the simulation execution. - * (in scale from 0 to 1, where 1 is 100%). - * @see #createCpuUtilizationModel(double, double) - */ + /// Defines the speed (in percentage) that CPU usage of a cloudlet + /// will increase during the simulation execution. + /// (in scale from 0 to 1, where 1 is 100%). + /// @see #createCpuUtilizationModel(double, double) private static final double CLOUDLET_CPU_INCREMENT_PER_SECOND = 0.05; private final ListThe listener is removed after finishing, so that it's called just once, - * even if new VMs are submitted and created later on.
- */ + /// A listener that is called after all VMs from a broker are created, + /// setting the allocation policy to the default value + /// so that some Hosts will be overloaded with the placed VMs and migration will be fired. + /// + /// The listener is removed after finishing, so that it's called just once, + /// even if new VMs are submitted and created later on. private void onVmsCreatedListener(final DatacenterBrokerEventInfo info) { final var broker = info.getDatacenterBroker(); final String vmIds = broker.getVmCreatedList() @@ -363,13 +332,11 @@ public void createAndSubmitCloudlets(final DatacenterBroker broker) { broker.submitCloudletList(cloudletList); } - /** - * Creates a Cloudlet. - * - * @param vm the VM that will run the Cloudlets - * @param cpuUtilizationModel the CPU UtilizationModel for the Cloudlet - * @return the created Cloudlets - */ + /// Creates a Cloudlet. + /// + /// @param vm the VM that will run the Cloudlets + /// @param cpuUtilizationModel the CPU UtilizationModel for the Cloudlet + /// @return the created Cloudlets public Cloudlet createCloudlet(final Vm vm, final UtilizationModel cpuUtilizationModel) { final var broker = vm.getBroker(); final var cloudlet = @@ -390,12 +357,10 @@ public void createAndSubmitVms(final DatacenterBroker broker, final int[] vmPesA vmList.forEach(vm -> vm.addOnMigrationStartListener(this::startMigration)); } - /** - * A listener method that is called when a VM migration starts. - * @param info information about the happened event - * - * @see Vm#addOnMigrationFinishListener(EventListener) - */ + /// A listener method that is called when a VM migration starts. + /// @param info information about the happened event + /// + /// @see Vm#addOnMigrationFinishListener(EventListener) private void startMigration(final VmHostEventInfo info) { migrationsNumber++; } @@ -407,23 +372,21 @@ public Vm createVm(final int pes) { .setSize(VM_SIZE); } - /** - * Creates a CPU UtilizationModel for a Cloudlet. - * If the initial usage is lower than the max usage, the usage will - * be dynamically incremented along the time, according to the - * {@link #getCpuUsageIncrement(UtilizationModelDynamic)} - * function. Otherwise, the CPU usage will be static, according to the - * defined initial usage. - * - * @param initialCpuUsagePercent the percentage of CPU utilization - * that created Cloudlets will use when they start to execute. - * If this value is greater than 1 (100%), it will be changed to 1. - * @param maxCpuUsagePercentage the maximum percentage of - * CPU utilization that created Cloudlets are allowed to use. - * If this value is greater than 1 (100%), it will be changed to 1. - * It must be equal or greater than the initial CPU usage. - * @return - */ + /// Creates a CPU UtilizationModel for a Cloudlet. + /// If the initial usage is lower than the max usage, the usage will + /// be dynamically incremented along the time, according to the + /// [#getCpuUsageIncrement(UtilizationModelDynamic)] + /// function. Otherwise, the CPU usage will be static, according to the + /// defined initial usage. + /// + /// @param initialCpuUsagePercent the percentage of CPU utilization + /// that created Cloudlets will use when they start to execute. + /// If this value is greater than 1 (100%), it will be changed to 1. + /// @param maxCpuUsagePercentage the maximum percentage of + /// CPU utilization that created Cloudlets are allowed to use. + /// If this value is greater than 1 (100%), it will be changed to 1. + /// It must be equal or greater than the initial CPU usage. + /// @return private UtilizationModelDynamic createCpuUtilizationModel(double initialCpuUsagePercent, double maxCpuUsagePercentage) { if(maxCpuUsagePercentage < initialCpuUsagePercent){ throw new IllegalArgumentException("Max CPU usage must be equal or greater than the initial CPU usage."); @@ -442,10 +405,8 @@ private UtilizationModelDynamic createCpuUtilizationModel(double initialCpuUsage return um; } - /** - * Increments the CPU resource utilization, that is defined in percentage values. - * @return the new resource utilization after the increment - */ + /// Increments the CPU resource utilization, that is defined in percentage values. + /// @return the new resource utilization after the increment private double getCpuUsageIncrement(final UtilizationModelDynamic um){ return um.getUtilization() + um.getTimeSpan()*CLOUDLET_CPU_INCREMENT_PER_SECOND; } @@ -455,12 +416,10 @@ private ListThis is a manual migration, different when using some - * {@link VmAllocationPolicyMigration} implementation. - * Such a policy automatically migrates VMs based on - * a static host CPU utilization threshold. - * In this example, such an implementation is not used - * and therefore, automatic VM migration based on CPU utilization threshold is not triggered. - * If you want to implement a VM migration policy, you should - * create a subclass from some of the existing ones. - * Usually the starting point is the {@link VmAllocationPolicyMigrationAbstract} - * but concrete implementations such as the {@link VmAllocationPolicyMigrationBestFitStaticThreshold} - * can be used as an example. - *
- * - *VMs are initially placed into Hosts following the - * {@link VmAllocationPolicyFirstFit} policy, which doesn't implement automatic VM - * migration based on CPU utilization threshold. We call this VM as "manual migration" - * exactly because we are not using a {@link VmAllocationPolicyMigration} implementation - * and the migration is defined by the simulation class itself.
- * - *When the simulation clock reaches a specific time, - * an arbitrary VM is migrated to an arbitrary Host. - * The clock advance is tracked by the {@link #clockTickListener(EventInfo)}, - * that actually fires the manual migration request. - *
- * - * @author Manoel Campos da Silva Filho - * @see MigrationExample1 - * @since CloudSim Plus 5.0.4 - */ +/// An example showing how perform a manual VM migration +/// according to any desired condition, such as +/// when the simulation reaches specific times. +/// +/// This is a manual migration, different when using some +/// [VmAllocationPolicyMigration] implementation. +/// Such a policy automatically migrates VMs based on +/// a static host CPU utilization threshold. +/// In this example, such an implementation is not used +/// and therefore, automatic VM migration based on CPU utilization threshold is not triggered. +/// If you want to implement a VM migration policy, you should +/// create a subclass from some of the existing ones. +/// Usually the starting point is the [VmAllocationPolicyMigrationAbstract] +/// but concrete implementations such as the [VmAllocationPolicyMigrationBestFitStaticThreshold] +/// can be used as an example. +/// +/// VMs are initially placed into Hosts following the +/// [VmAllocationPolicyFirstFit] policy, which doesn't implement automatic VM +/// migration based on CPU utilization threshold. We call this VM as "manual migration" +/// exactly because we are not using a [VmAllocationPolicyMigration] implementation +/// and the migration is defined by the simulation class itself. +/// +/// When the simulation clock reaches a specific time, +/// an arbitrary VM is migrated to an arbitrary Host. +/// The clock advance is tracked by the [#clockTickListener(EventInfo)], +/// that actually fires the manual migration request. +/// +/// @author Manoel Campos da Silva Filho +/// @see MigrationExample1 +/// @since CloudSim Plus 5.0.4 public final class ManualMigrationExample1 { - /** - * @see Datacenter#getSchedulingInterval() - */ + /// @see Datacenter#getSchedulingInterval() private static final int SCHEDULING_INTERVAL = 1; private static final int HOSTS = 5; private static final int VMS = 3; @@ -100,21 +94,19 @@ public final class ManualMigrationExample1 { private static final long HOST_RAM = 500000; //host memory (MB) private static final long HOST_STORAGE = 1000000; //host storage - /** - * The time spent during VM migration depend on the - * bandwidth of the target Host. - * By default, a {@link Datacenter} - * uses only 50% of the BW to migrate VMs, while the - * remaining capacity is used for VM communication. - * This can be changed by calling - * {@link DatacenterSimple#setBandwidthPercentForMigration(double)}. - * - *The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity
- * is used for VM migration, only 1000 MB/s will be available for this process.
- * The time that takes to migrate a Vm depend on the VM RAM capacity.
- * Since VMs in this example are created with 2000 MB of RAM, any migration
- * will take 2 seconds to finish, as can be seen in the logs.
- */
+ /// The time spent during VM migration depend on the
+ /// bandwidth of the target Host.
+ /// By default, a [Datacenter]
+ /// uses only 50% of the BW to migrate VMs, while the
+ /// remaining capacity is used for VM communication.
+ /// This can be changed by calling
+ /// [DatacenterSimple#setBandwidthPercentForMigration(double)].
+ ///
+ /// The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity
+ /// is used for VM migration, only 1000 MB/s will be available for this process.
+ /// The time that takes to migrate a Vm depend on the VM RAM capacity.
+ /// Since VMs in this example are created with 2000 MB of RAM, any migration
+ /// will take 2 seconds to finish, as can be seen in the logs.
private static final long HOST_BW = 16000L; //Mb/s
private static final int VM_MIPS = 1000; //for each PE
@@ -127,9 +119,7 @@ public final class ManualMigrationExample1 {
private static final long CLOUDLET_FILESIZE = 300;
private static final long CLOUDLET_OUTPUTSIZE = 300;
- /**
- * List of all created VMs.
- */
+ /// List of all created VMs.
private final List Realize that the Host State History is just collected
- * if {@link Host#isStateHistoryEnabled() history is enabled}
- * by calling {@link Host#setStateHistoryEnabled(boolean)}. The example then performs VM migration using
- * a {@link VmAllocationPolicyMigrationBestFitStaticThreshold}.
- * Such a policy migrates VMs based on
- * a static host CPU utilization threshold.
- * The VmAllocationPolicy used in this example ignores power consumption of Hosts.
- * This way, it isn't required to set a PowerModel for Hosts. According to the allocation policy, VM 0 will be allocated to Host 0.
- * Since Host 0 has just 4 PEs, allocating a second VM into it
- * would cause overload.
- * Each cloudlet will start using 80% of its VM CPU.
- * As the VM 0 will run one Cloudlet and requires just 2 PEs from Host 0 (which has 4 PEs),
- * the initial Host CPU usage will be just 40% (1 VM using 80% of 2 PEs from a total of 4 Host PEs = 0.8*2 / 4).
- *
- * Allocating a second VM into Host 0 would double the Host CPU utilization,
- * overreaching its upper utilization threshold (defined as 70%).
- * This way, VMs 1 and 2 are allocated to Host 1 which has 5 PEs.
- * The {@link VmAllocationPolicyMigrationBestFitStaticThreshold}
- * allows setting static under/over CPU utilization thresholds to
- * enable VM migration.
- * The example uses a {@link UtilizationModelDynamic} to define that CPU usage of cloudlets
- * increases along simulation time.
- * The first 2 Cloudlets start with a usage of 80% of CPU,
- * which increases along the time (see {@link #CLOUDLET_CPU_INCREMENT_PER_SECOND}).
- * The third Cloudlet starts at a lower CPU usage and increases in the same way.
- * Some constants are used to create simulation objects such as
- * {@link DatacenterSimple}, {@link Host} and {@link Vm}.
- * The values of these constants were careful and accordingly chosen to allow:
- * (i) migration of VMs due to either under and overloaded hosts;
- * and (ii) the researcher to know exactly how the simulation will run
- * and what will be the final results.
- *
- * Several values impact simulation results, such as
- * (i) hosts CPU capacity and number of PEs,
- * (ii) VMs and cloudlets requirements and
- * (iii) even VM bandwidth (which defines the VM migration time).
- *
- * This way, if you want to change these values, you must
- * define new appropriated ones to allow the simulation
- * to run correctly. Realize that Host State History is just collected
- * if you enable that by calling {@link Host#setStateHistoryEnabled(boolean)}. The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity
- * is used for VM migration, only 1000 MB/s will be available for this process.
- * The time that takes to migrate a Vm depend on the VM RAM capacity.
- * Since VMs in this example are created with 2000 MB of RAM, any migration
- * will take 2 seconds to finish, as can be seen in the logs.
- */
+ /// The time spent during VM migration depend on the
+ /// bandwidth of the target Host.
+ /// By default, a [Datacenter]
+ /// uses only 50% of the BW to migrate VMs, while the
+ /// remaining capacity is used for VM communication.
+ /// This can be changed by calling
+ /// [DatacenterSimple#setBandwidthPercentForMigration(double)].
+ ///
+ /// The 16000 Mb/s is the same as 2000 MB/s. Since just half of this capacity
+ /// is used for VM migration, only 1000 MB/s will be available for this process.
+ /// The time that takes to migrate a Vm depend on the VM RAM capacity.
+ /// Since VMs in this example are created with 2000 MB of RAM, any migration
+ /// will take 2 seconds to finish, as can be seen in the logs.
private static final long HOST_BW = 16_000L; //Mb/s
private static final int HOST_MIPS = 1000; //for each PE
private static final long HOST_RAM[] = {15_000, 500_000, 25_000}; //host memory (MB)
private static final long HOST_STORAGE = 1_000_000; //host storage
- /**
- * An array where each item defines the number of PEs for each Host to be created.
- * The length of the array represents the number of Hosts.
- */
+ /// An array where each item defines the number of PEs for each Host to be created.
+ /// The length of the array represents the number of Hosts.
private static final int HOST_PES[] = {4, 5, 5};
private static final int VM_PES[] = {2, 2, 2, 1};
@@ -178,26 +158,20 @@ public final class MigrationExample1 {
private static final long CLOUDLET_FILESIZE = 300;
private static final long CLOUDLET_OUTPUTSIZE = 300;
- /**
- * The percentage of CPU that a cloudlet will use when
- * it starts executing (in scale from 0 to 1, where 1 is 100%).
- * For each cloudlet create, this value is used
- * as a base to define CPU usage.
- * @see #createAndSubmitCloudlets(DatacenterBroker)
- */
+ /// The percentage of CPU that a cloudlet will use when
+ /// it starts executing (in scale from 0 to 1, where 1 is 100%).
+ /// For each cloudlet create, this value is used
+ /// as a base to define CPU usage.
+ /// @see #createAndSubmitCloudlets(DatacenterBroker)
private static final double CLOUDLET_INITIAL_CPU_PERCENTAGE = 0.8;
- /**
- * Defines the speed (in percentage) that CPU usage of a cloudlet
- * will increase during the simulation execution.
- * (in scale from 0 to 1, where 1 is 100%).
- * @see #createCpuUtilizationModel(double, double)
- */
+ /// Defines the speed (in percentage) that CPU usage of a cloudlet
+ /// will increase during the simulation execution.
+ /// (in scale from 0 to 1, where 1 is 100%).
+ /// @see #createCpuUtilizationModel(double, double)
private static final double CLOUDLET_CPU_INCREMENT_PER_SECOND = 0.04;
- /**
- * List of all created VMs.
- */
+ /// List of all created VMs.
private final List The listener is removed after finishing, so that it's called just once,
- * even if new VMs are submitted and created latter on. There are a set of constants you can change to see how the simulation
- * is impacted. The most impacting ones are {@link #CLOUDLETS},
- * {@link #CLOUDLET_LENGTH} and {@link #SCHEDULING_INTERVAL}.
- * Just play with these values to see the results. There are a set of constants you can change to see how the simulation
- * is impacted. The most impacting ones are {@link #CLOUDLETS},
- * {@link #CLOUDLET_LENGTH}, {@link #SCHEDULING_INTERVAL},
- * {@link #MULTIPLE_UTILIZATION_MODELS}
- * and {@link #STORE_CLOUDLETS_CPU_UTILIZATION_HISTORY}.
- * Just play with these values to see the results. Since the utilization history Map stored by the {@link UtilizationModelStochastic}
- * is commonly not used after the simulation finishes,
- * maintaining such history is a time and memory expensive operation.
- * This way, if you don't need such a history, you can
- * disable it by setting {@link #STORE_CLOUDLETS_CPU_UTILIZATION_HISTORY} to false.
- * However, keep in mind it is a trade-off between performance and memory consumption,
- * as it's explained in {@link UtilizationModelStochastic#setHistoryEnabled(boolean)}
- * documentation.
- * Realize that if you use a single {@link UtilizationModel} for all
- * Cloudlets, the resource utilization will usually be the same
- * for all of them.
- * Using the {@link UtilizationModelStochastic}, if two Cloudlets
- * consecutively request the current resource utilization for the same time,
- * it will be returned the same value. If they send consecutive requests for different times,
- * probably it will be returned distinct randomly generated values. The dynamic demand for Hosts is simulated
- * by creating VMs during simulation runtime.
- * To enable this, it's required to define
- * a {@link Datacenter#setSchedulingInterval(double)} scheduling interval}.
- * It's also used a Event Listener to track the simulation clock.
- * This way, when the clock increases according to the scheduling interval,
- * a new VM is created, up to the total VMs defined in {@link #MAX_VMS}. It creates one Cloudlet for each VM and the Cloudlets are created with different lengths.
- * This enables VMs to become idle in different times.
- * To ensure idle VMs are destroyed as soon as they become idle
- * (so that we can quickly check that the number of VMs into a Host has reduced),
- * a {@link DatacenterBroker#setVmDestructionDelayFunction(Function)} is
- * set. Check the {@link #createBroker()} method for details.
- *
- * Since the total number of PEs requested by all VMs is equal to 24
- * and each Host has 8 PEs, it's only used 3 Hosts to meet the demand. It creates the number of cloudlets defined in
- * {@link #CLOUDLETS}. All cloudlets will require 100% of PEs they are using all the time.
- * Half of these cloudlets are created with the length defined by {@link #CLOUDLET_LENGTH}
- * and the other half will have the double of this length.
- * This way, it's possible to see that for the last half of the
- * simulation time, a Host doesn't use the entire CPU capacity,
- * and therefore doesn't consume the maximum power. However, you may notice in this case that the power usage isn't
- * half of the maximum consumption, because there is a static minimum
- * amount of power to use, even if the Host is idle,
- * which is defined by {@link #STATIC_POWER}.
- * Check {@link PowerModelHostSimple#PowerModelHostSimple(double, double)}.
- * Realize that the Host CPU Utilization History is only stored
- * if VMs utilization history is enabled by calling
- * {@code vm.getUtilizationHistory().enable()} Each line in the table with CPU utilization and power consumption shows
- * the data from the time specified in the line, up to the time before the value in the next line.
- * For instance, consider the scheduling interval is 10, the time in the first line is 1 and
- * it shows 100% CPU utilization and 100 W of power consumption.
- * Then, the next line contains data for time 10.
- * It means that for any point between time 1 to time 10,
- * the CPU utilization and power consumption is the one provided in that first line. A Host, even if idle, may consume a static amount of power.
- * Lets say it consumes 20 W in idle state and that for each 1% of CPU use it consumes 1 W more.
- * For the 2 VMs of the example above, each one using 50% of CPU will consume 50 W.
- * That is 100 W for the 2 VMs, plus the 20 W that is static.
- * Therefore we have a total Host power consumption of 120 W.
- *
- * If we computer the power consumption for a single VM by
- * calling {@code vm.getHost().getPowerModel().getPower(hostCpuUsage)},
- * we get the 50 W consumed by the VM, plus the 20 W of static power.
- * This adds up to 70 W. If the two VMs are equal and using the same amount of CPU,
- * their power consumption would be the half of the total Host's power consumption.
- * This would be 60 W, not 70.
- * This way, we have to compute VM power consumption by sharing a supposed Host static power
- * consumption with each VM, as it's being shown here.
- * Not all {@link PowerModel} have this static power consumption.
- * However, the way the VM power consumption
- * is computed here, that detail is abstracted.
- * CloudSim Plus has a very accurate and consistent power consumption computation.
- * This way, you can see in this example that results just change
- * when a scheduling interval is set with a value equals to the time the last
- * Cloudlet finishes.
- *
- * You are strongly encouraged to firstly check the {@link PowerExample} to understand the details. Cloudlets run in VMs with different MIPS requirements and will
- * take different times to complete the execution, depending on the requested VM
- * performance.
- *
- *
- *