Java tutorial
/** * Copyright 2011 Amir Moulavi (amir.moulavi@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package instance.os; import cloud.api.RestartInstance; import cloud.common.Alive; import cloud.common.HeartbeatMessage; import cloud.common.NodeConfiguration; import cloud.common.RequestMessage; import cloud.elb.ActivateBlock; import cloud.elb.MyCPULoadAndBandwidth; import cloud.requestengine.DownloadStarted; import econtroller.sensor.Monitor; import instance.Node; import instance.common.*; import instance.cpu.CPU; import instance.cpu.OperationDuration; import instance.disk.StartDiskUnit; import instance.gui.DummyInstanceGUI; import instance.gui.GenericInstanceGUI; import instance.gui.HeadLessGUI; import instance.gui.InstanceGUI; import instance.mem.StartMemoryUnit; import logger.Logger; import logger.LoggerFactory; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import se.sics.kompics.ComponentDefinition; import se.sics.kompics.Handler; import se.sics.kompics.Negative; import se.sics.kompics.Positive; import se.sics.kompics.address.Address; import se.sics.kompics.network.Network; import se.sics.kompics.timer.CancelTimeout; import se.sics.kompics.timer.ScheduleTimeout; import se.sics.kompics.timer.Timer; import java.awt.*; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; /** * * @author Amir Moulavi * @date 2011-03-18 * */ public class OS extends ComponentDefinition { private Logger logger; // Ports Positive<CPUChannel> cpu = requires(CPUChannel.class); Positive<MemChannel> memory = requires(MemChannel.class); Positive<DiskChannel> disk = requires(DiskChannel.class); Positive<Timer> timer = requires(Timer.class); Positive<Network> network = requires(Network.class); Negative<OSPort> os = provides(OSPort.class); // Variables needed by OS private String uname_r = "2.2-2"; private Kernel kernel; protected final int numberOfDevices = 3; private int numberOfDevicesLoaded = 0; private long BANDWIDTH = 2 * Size.MB.getSize(); private static final long WAIT = 1000; private static final long REQUEST_QUEUE_PROCESSING_INTERVAL = 1000; private static final long CPU_LOAD_PROPAGATION_INTERVAL = 5000; public static final long RESTART_PERIOD = 60000; private static final long COST_CALCULATION_INTERVAL = 10000; private static int simultaneousDownloads = 70; protected Address cloudProvider; private ConcurrentMap<String, Process> pt = new ConcurrentHashMap<String, Process>(); private ConcurrentMap<UUID, String> currentTransfers = new ConcurrentHashMap<UUID, String>(); private final ConcurrentLinkedQueue<Request> requestQueue = new ConcurrentLinkedQueue<Request>(); private CostService costService = new CostService(); protected GenericInstanceGUI gui; protected Address self; protected Node node; protected NodeConfiguration nodeConfiguration; protected double currentCpuLoad; private XYSeriesCollection dataSet = new XYSeriesCollection(); private XYSeries xySeries = new XYSeries("Load"); private long startTime = System.currentTimeMillis(); private int lastSnapshotID = 1; private long currentBandwidth = BANDWIDTH; private List<Block> blocks = new ArrayList<Block>(); /* protected boolean acceptRequest = true; */ private boolean enabled = true; private int megaBytesDownloadedSoFar = 0; protected double totalCost = 0.0; private boolean headless; private OS selfReference; private Map<String, Address> dataBlocks; public OS() { this.selfReference = this; subscribe(initHandler, control); subscribe(cpuReadySignalHandler, cpu); subscribe(cpuLoadHandler, cpu); subscribe(snapshotRequestHandler, cpu); subscribe(memoryReadySignalHandler, memory); subscribe(ackBlockHandler, memory); subscribe(nackBlockHandler, memory); subscribe(diskReadySignalHandler, disk); subscribe(blockResponseHandler, disk); subscribe(processRequestQueueHandler, timer); subscribe(propagateCPULoadHandler, timer); subscribe(transferringFinishedHandler, timer); subscribe(readDiskFinishedHandler, timer); subscribe(waitTimeoutHandler, timer); subscribe(deathHandler, timer); subscribe(calculateCostHandler, timer); subscribe(requestMessageHandler, network); subscribe(heartbeatMessageHandler, network); subscribe(monitorHandler, network); subscribe(shutDownHandler, network); subscribe(restartInstanceHandler, network); subscribe(rebalanceRequestHandler, network); subscribe(rebalanceResponseHandler, network); subscribe(blockTransferredHandler, network); subscribe(closeMyStreamHandler, network); } Handler<OSInit> initHandler = new Handler<OSInit>() { @Override public void handle(OSInit event) { retrieveInitParameters(event); loadKernel(); loadBlocksToDisk(event); dataSet.addSeries(xySeries); waitForSystemStartUp(); costService.init(event.getNodeConfiguration()); gui.updateBandwidthInfoLabel(Size.getSizeString(BANDWIDTH)); } private void retrieveInitParameters(OSInit event) { nodeConfiguration = event.getNodeConfiguration(); BANDWIDTH = nodeConfiguration.getBandwidthConfiguration().getBandwidthMegaBytePerSecond(); simultaneousDownloads = nodeConfiguration.getSimultaneousDownloads(); self = event.getSelfAddress(); node = event.getNodeInfo(); cloudProvider = event.getCloudProviderAddress(); headless = nodeConfiguration.getHeadLess(); if (headless) { gui = new HeadLessGUI(); logger = LoggerFactory.getLogger(OS.class, new DummyInstanceGUI()); kernel = new Kernel(true); } else { gui = InstanceGUI.getInstance(); gui.setOSReference(selfReference); logger = LoggerFactory.getLogger(OS.class, InstanceGUI.getInstance()); kernel = new Kernel(false); } logger.info("NodeConfigurations:\n" + nodeConfiguration.toString()); gui.updateSimultaneousDownloads(String.valueOf(simultaneousDownloads)); } }; /** * This handler is in charge of handling the request that are sent by Elastic Load Balancer */ Handler<RequestMessage> requestMessageHandler = new Handler<RequestMessage>() { @Override public void handle(RequestMessage event) { if (instanceRunning()) { Request req = event.request(); logger.debug("Received request for block " + req); if (simultaneousDownloads > currentTransfers.size()) { logger.debug("Admitted Request for block '" + req.getBlockId() + "'"); requestQueue.add(req); } else { logger.warn( "Rejected Request for download block " + req.getBlockId() + ". No free slot. {simDown: " + simultaneousDownloads + ", currenTrans: " + currentTransfers.size() + "}"); Rejected rejected = new Rejected(self, cloudProvider, event.request()); trigger(rejected, network); } } } }; /** * This event handler is triggered periodically to process request queue */ Handler<ProcessRequestQueue> processRequestQueueHandler = new Handler<ProcessRequestQueue>() { @Override public void handle(ProcessRequestQueue event) { if (instanceRunning()) { int freeSlot = simultaneousDownloads - currentTransfers.size(); trigger(new MemoryCheckOperation(), cpu); for (int i = 0; i < freeSlot; i++) { if (!requestQueue.isEmpty()) { Request req = requestQueue.remove(); trigger(new MemoryCheckOperation(), cpu); trigger(new MemoryReadOperation(8), cpu); startProcessForRequest(req); } else break; } gui.updateRequestQueue(requestQueue.size()); synchronized (requestQueue) { for (int i = 0; i < requestQueue.size(); i++) { Request req = requestQueue.remove(); if (req != null) trigger(new Rejected(self, cloudProvider, req), network); } } } scheduleProcessingRequestQueue(); } }; Handler<Ready> cpuReadySignalHandler = new Handler<Ready>() { @Override public void handle(Ready event) { numberOfDevicesLoaded++; for (int i = 0; i < 10; i++) trigger(new BootOperation(), cpu); logger.debug("Received ready signal from " + event.getDevice()); if (instanceRunning()) osStarted(); } }; Handler<Ready> memoryReadySignalHandler = new Handler<Ready>() { @Override public void handle(Ready event) { numberOfDevicesLoaded++; logger.debug("Received ready signal from " + event.getDevice()); if (instanceRunning()) osStarted(); } }; Handler<Ready> diskReadySignalHandler = new Handler<Ready>() { @Override public void handle(Ready event) { numberOfDevicesLoaded++; logger.debug("Received ready signal from " + event.getDevice()); if (instanceRunning()) osStarted(); } }; /** * Memory hit: this means the next operation is to transfer the block * from memory into the network according to the bandwidth we have */ Handler<AckBlock> ackBlockHandler = new Handler<AckBlock>() { @Override public void handle(AckBlock event) { if (instanceRunning()) { logger.debug("Block " + event.getProcess().getRequest().getBlockId() + " exists in the memory"); scheduleTransferForBlock(event.getProcess()); trigger(new MemoryReadOperation(event.getProcess().getBlockSize()), cpu); } } }; /** * Memory miss: this means that the next operation is an I/O from the disk * that may take much more time than a memory read */ Handler<NAckBlock> nackBlockHandler = new Handler<NAckBlock>() { @Override public void handle(NAckBlock event) { if (instanceRunning()) { logger.debug( "Block " + event.getProcess().getRequest().getBlockId() + " does not exists in the memory"); ReadBlock read = new ReadBlock(event.getProcess().getRequest().getBlockId()); read.setProcess(event.getProcess()); trigger(read, disk); } } }; /** * This is the response from Disk containing the block requested earlier */ Handler<BlockResponse> blockResponseHandler = new Handler<BlockResponse>() { @Override public void handle(BlockResponse event) { if (instanceRunning()) { readFromDiskIntoMemory(event); WriteBlockIntoMemory write = new WriteBlockIntoMemory(event.getBlock()); trigger(new DiskReadOperation(event.getBlock().getSize()), cpu); trigger(new MemoryWriteOperation(event.getBlock().getSize()), cpu); trigger(write, memory); } } }; /** * Updates transfer table and compute bandwidth for remaining transfers */ Handler<TransferringFinished> transferringFinishedHandler = new Handler<TransferringFinished>() { @Override public void handle(TransferringFinished event) { if (instanceRunning()) { Process process = pt.get(event.getPid()); /* checkIfCanAcceptRequest(); */ if (process != null) { Request request = process.getRequest(); updateTransferredBandwidth(process); currentTransfers.remove(event.getTimeoutId()); gui.decreaseNrDownloadersFor(request.getBlockId()); gui.updateCurrentTransfers(currentTransfers.size()); informDownloader(event, process, request); removeFromProcessTable(event.getPid()); endProcessOnCPU(event.getPid()); if (currentTransfers.size() != 0) { cancelAllPreviousTimers(); rescheduleAllTimers(BANDWIDTH / currentTransfers.size(), System.currentTimeMillis()); } } } } private synchronized void updateTransferredBandwidth(Process process) { megaBytesDownloadedSoFar += (process.getBlockSize() / (1024 * 1024)); } private void informDownloader(TransferringFinished event, Process process, Request request) { if (request.getDestinationNode() != null) { logger.info("Rebalancing finished for " + event.getPid()); trigger(new BlockTransferred(self, request.getDestinationNode(), process.getBlockSize(), process.getRequest().getBlockId()), network); } else { logger.debug("Transferring finished for " + event.getPid()); } } }; /** * This means that the block is read from the disk into memory. Now we can transfer * it into the network */ Handler<ReadDiskFinished> readDiskFinishedHandler = new Handler<ReadDiskFinished>() { @Override public void handle(ReadDiskFinished event) { if (instanceRunning()) { scheduleTransferForBlock(pt.get(event.getPid())); trigger(new MemoryCheckOperation(), cpu); } } }; /** * This handler is executed if the system has not yet started until it starts successfully with all the hardware components */ Handler<WaitTimeout> waitTimeoutHandler = new Handler<WaitTimeout>() { @Override public void handle(WaitTimeout event) { if (!instanceRunning()) { waitForSystemStartUp(); } else { scheduleProcessingRequestQueue(); scheduleCPULoadPropagationToCloudProvider(); scheduleCostCalculation(); } } }; /** * This handler is triggered upon receiving a shutDown request from cloudProvider */ Handler<ShutDown> shutDownHandler = new Handler<ShutDown>() { @Override public void handle(ShutDown event) { if (event.getSource().equals(cloudProvider)) { logger.debug("Time to die forever :("); if (!headless) { ((InstanceGUI) gui).dispose(); } for (Map.Entry<String, Address> entry : dataBlocks.entrySet()) { trigger(new CloseMyStream(self, entry.getValue()), network); } trigger(new ShutDownAck(self, event.getSource(), node), network); scheduleDeath(); } else { logger.warn("Oh oh! Someone is trying to kill me!"); } } }; /** * This handler is triggered by dying instance to clean up open streams that can block accepting further requests */ Handler<CloseMyStream> closeMyStreamHandler = new Handler<CloseMyStream>() { @Override public void handle(CloseMyStream event) { removeProcessesBelongTo(event); /* checkIfCanAcceptRequest(); */ } }; private synchronized void removeProcessesBelongTo(CloseMyStream event) { for (String processId : pt.keySet()) { if (pt.get(processId).getRequest().getDestinationNode() != null && pt.get(processId).getRequest().getDestinationNode().equals(event.getSource())) pt.remove(processId); } } /** * This is for scheduling a complete shut down if the CloudProvider * was not able to shut down this instance completely (because of port binding) */ Handler<Death> deathHandler = new Handler<Death>() { @Override public void handle(Death event) { System.exit(0); } }; /** * This handler is triggered when receives a heatBeat message from HealthChecker */ Handler<HeartbeatMessage> heartbeatMessageHandler = new Handler<HeartbeatMessage>() { @Override public void handle(HeartbeatMessage event) { if (instanceRunning()) { trigger(new Alive(self, event.getSource()), network); } } }; /** * This handler is triggered by CPU */ Handler<CPULoad> cpuLoadHandler = new Handler<CPULoad>() { @Override public void handle(CPULoad event) { if (instanceRunning()) { currentCpuLoad = event.getCpuLoad(); } } }; /** * Upon every tick of CPU_LOAD_PROPAGATION_INTERVAL, this handler sends * the current cpu load to cloud provider */ Handler<PropagateCPULoad> propagateCPULoadHandler = new Handler<PropagateCPULoad>() { @Override public void handle(PropagateCPULoad event) { if (instanceRunning()) { trigger(new MyCPULoadAndBandwidth(self, cloudProvider, node, currentCpuLoad, currentBandwidth), network); trigger(new MemoryCheckOperation(), cpu); scheduleCPULoadPropagationToCloudProvider(); } } }; /** * This handler is for getting CPU Load chart from CPU */ Handler<SnapshotRequest> snapshotRequestHandler = new Handler<SnapshotRequest>() { @Override public void handle(SnapshotRequest event) { if (instanceRunning()) { InstanceSnapshot snapshot = new InstanceSnapshot(lastSnapshotID++); snapshot.addCPULoadChart(event.getCpuLoadChart()); snapshot.addBandwidthChart(getBandwidthChart()); gui.addSnapshot(snapshot); } } }; /** * This handler is triggered by Sensor component */ @Deprecated Handler<Monitor> monitorHandler = new Handler<Monitor>() { @Override public void handle(Monitor event) { if (instanceRunning()) { logger.info("Recieved Monitor from Sensor"); } } }; /** * This handler is triggered by Cloud Provider */ Handler<RestartInstance> restartInstanceHandler = new Handler<RestartInstance>() { @Override public void handle(RestartInstance event) { if (instanceRunning()) { restartInstance(); } } }; /** * This handler sends a request to another instance asking for the recommended blocks that it received * from cloud provider. */ Handler<RebalanceRequest> rebalanceRequestHandler = new Handler<RebalanceRequest>() { @Override public void handle(RebalanceRequest event) { Block block = findRequestedBlock(event.getBlockId()); trigger(new RebalanceResponse(self, event.getSource(), block), network); /* acceptRequest = false; */ Request req = new Request(UUID.randomUUID().toString(), block.getName(), event.getSource()); startProcessForRequest(req); } }; /** * This handler is a response from the other instance with the data blocks */ Handler<RebalanceResponse> rebalanceResponseHandler = new Handler<RebalanceResponse>() { @Override public void handle(RebalanceResponse event) { blocks.add(event.getBlock()); logger.debug("Rebalancing is started from " + event.getSource() + " for block " + event.getBlock().getName()); while (!instanceRunning()) { try { Thread.sleep(1000); } catch (InterruptedException e) { logger.error(e.getMessage()); } } Process p = Process.createAbstractProcess(); addToProcessTable(p); startTransferProcessOnCPU(p); currentBandwidth = BANDWIDTH / blocks.size(); addToBandwidthDiagram(currentBandwidth); } }; /** * This handler is triggered when the transfer from another instance node is finished */ Handler<BlockTransferred> blockTransferredHandler = new Handler<BlockTransferred>() { @Override public void handle(BlockTransferred event) { String process = pt.keySet().iterator().next(); pt.remove(process); Block block = new Block(event.getBlockName(), event.getBlockSize()); ActivateBlock activateBlock = new ActivateBlock(self, cloudProvider, node, block); trigger(activateBlock, network); endProcessOnCPU(process); trigger(new DiskWriteOperation(event.getBlockSize()), cpu); calculateNewBandwidth(); addToBandwidthDiagram(currentBandwidth); if (blocks.size() == dataBlocks.size()) { logger.info("Starting with " + blocks.size() + " block(s) in hand"); LoadBlock load = new LoadBlock(blocks); trigger(load, disk); gui.initializeDataBlocks(blocks); } } private void calculateNewBandwidth() { if (pt.size() == 0) { currentBandwidth = BANDWIDTH; } else { currentBandwidth = BANDWIDTH / pt.size(); } } }; /** * This handler is triggered to calculate the current cost for this instance from its start up time */ Handler<CalculateCost> calculateCostHandler = new Handler<CalculateCost>() { @Override public void handle(CalculateCost event) { totalCost = costService.computeCostSoFar(megaBytesDownloadedSoFar); double costToSend = costService.computeCostInThisPeriod(megaBytesDownloadedSoFar); DecimalFormat df = new DecimalFormat("##.####"); String totalCostString = df.format(totalCost); String periodicCostString = df.format(costToSend); gui.updateCurrentCost(totalCostString); trigger(new InstanceCost(self, cloudProvider, node, totalCostString, periodicCostString), network); scheduleCostCalculation(); } }; private void osStarted() { logger.debug("OS with kernel " + uname_r + " started"); gui.decorateSystemStarted(); } protected void scheduleCostCalculation() { ScheduleTimeout st = new ScheduleTimeout(COST_CALCULATION_INTERVAL); st.setTimeoutEvent(new CalculateCost(st)); trigger(st, timer); } protected Block findRequestedBlock(String blockId) { for (Block block : blocks) { if (block.getName().equals(blockId)) return block; } return null; } protected void scheduleCPULoadPropagationToCloudProvider() { ScheduleTimeout st = new ScheduleTimeout(CPU_LOAD_PROPAGATION_INTERVAL); st.setTimeoutEvent(new PropagateCPULoad(st)); trigger(st, timer); gui.createBandwidthDiagram(getBandwidthChart()); } protected void scheduleProcessingRequestQueue() { ScheduleTimeout st = new ScheduleTimeout(REQUEST_QUEUE_PROCESSING_INTERVAL); st.setTimeoutEvent(new ProcessRequestQueue(st)); trigger(st, timer); } protected void loadKernel() { gui.updateTitle(node.getNodeName() + "@" + node.getIP() + ":" + node.getPort()); gui.decorateWhileSystemStartUp(); enabled = false; kernel.init(nodeConfiguration.getCpuConfiguration().getCpuSpeedInstructionPerSecond()); enabled = true; } protected void scheduleDeath() { ScheduleTimeout st = new ScheduleTimeout(1000); st.setTimeoutEvent(new Death(st)); trigger(st, timer); } private void waitForSystemStartUp() { ScheduleTimeout st = new ScheduleTimeout(WAIT); st.setTimeoutEvent(new WaitTimeout(st)); trigger(st, timer); } private void readFromDiskIntoMemory(BlockResponse response) { Process process = response.getProcess(); Block block = response.getBlock(); process.setBlockSize(block.getSize()); ScheduleTimeout st = new ScheduleTimeout( OperationDuration.getDiskReadDuration(CPU.CPU_CLOCK, response.getBlock().getSize())); ReadDiskFinished rd = new ReadDiskFinished(st); rd.setPid(process.getPid()); st.setTimeoutEvent(rd); trigger(st, timer); } private synchronized void scheduleTransferForBlock(Process process) { if (currentTransfers.size() == 0) { logger.debug("Transfer started " + process); scheduleTimeoutFor(process, BANDWIDTH); addToBandwidthDiagram(BANDWIDTH); currentBandwidth = BANDWIDTH; } else { trigger(new MemoryCheckOperation(), cpu); long newBandwidth = BANDWIDTH / (currentTransfers.size() + 1); long now = System.currentTimeMillis(); cancelAllPreviousTimers(); rescheduleAllTimers(newBandwidth, now); logger.debug("Transfer started " + process); scheduleTimeoutFor(process, newBandwidth); } trigger(new DownloadStarted(self, cloudProvider, process.getRequest().getId()), network); } private void rescheduleAllTimers(long newBandwidth, long now) { logger.debug("Rescheduling all current downloads with bandwidth: " + newBandwidth + " B/s"); addToBandwidthDiagram(newBandwidth); currentBandwidth = newBandwidth; ConcurrentMap<UUID, String> ct = new ConcurrentHashMap<UUID, String>(); for (Entry<UUID, String> en : currentTransfers.entrySet()) { trigger(new MemoryCheckOperation(), cpu); Process p = pt.get(en.getValue()); if (p == null) continue; p.setRemainingBlockSize( p.getRemainingBlockSize() - (long) (now - p.getSnapshot()) * p.getCurrentBandwidth() / 1000); if (p.getRemainingBlockSize() < 0) p.setRemainingBlockSize(0); p.setCurrentBandwidth(newBandwidth); p.setTimeout(p.getRemainingBlockSize() / p.getCurrentBandwidth()); p.setSnapshot(now); pt.put(p.getPid(), p); ScheduleTimeout st = new ScheduleTimeout(1000 * p.getRemainingBlockSize() / p.getCurrentBandwidth()); TransferringFinished tt = new TransferringFinished(st); tt.setPid(p.getPid()); st.setTimeoutEvent(tt); ct.put(st.getTimeoutEvent().getTimeoutId(), p.getPid()); trigger(st, timer); } currentTransfers.clear(); currentTransfers.putAll(ct); } private void scheduleTimeoutFor(Process process, long bandwidth) { trigger(new MemoryCheckOperation(), cpu); long transferDelay = 1000 * process.getBlockSize() / bandwidth; ScheduleTimeout st = new ScheduleTimeout(1000 * process.getBlockSize() / bandwidth); TransferringFinished tt = new TransferringFinished(st); tt.setPid(process.getPid()); st.setTimeoutEvent(tt); UUID timeoutId = st.getTimeoutEvent().getTimeoutId(); currentTransfers.put(timeoutId, process.getPid()); process.setCurrentBandwidth(bandwidth).setRemainingBlockSize(process.getBlockSize()) .setSnapshot(System.currentTimeMillis()).setTimeout(transferDelay); pt.put(process.getPid(), process); trigger(st, timer); } private void cancelAllPreviousTimers() { for (Entry<UUID, String> en : currentTransfers.entrySet()) { trigger(new MemoryCheckOperation(), cpu); CancelTimeout cancel = new CancelTimeout(en.getKey()); trigger(cancel, timer); } } protected void startProcessForRequest(Request event) { Process p = new Process(event); startTransferProcessOnCPU(p); addToProcessTable(p); checkMemory(p); gui.increaseNrDownloadersFor(event.getBlockId()); gui.updateCurrentTransfers(currentTransfers.size()); } private void checkMemory(Process p) { RequestBlock rBlock = new RequestBlock(p); trigger(rBlock, memory); trigger(new MemoryCheckOperation(), cpu); } private void addToProcessTable(Process p) { pt.put(p.getPid(), p); } private void removeFromProcessTable(String pid) { pt.remove(pid); } private void startTransferProcessOnCPU(Process p) { StartProcess process = new StartProcess(p); trigger(process, cpu); } private void endProcessOnCPU(String pid) { EndProcess process = new EndProcess(pid); trigger(process, cpu); } protected void loadBlocksToDisk(OSInit event) { if (event.getBlocks() != null) { blocks = event.getBlocks(); logger.info("Starting with " + blocks.size() + " block(s) in hand"); LoadBlock load = new LoadBlock(blocks); trigger(load, disk); trigger(new BlocksAck(self, cloudProvider, node), network); gui.initializeDataBlocks(blocks); } else { logger.warn("I should get blocks from " + event.getNodeConfiguration().getDataBlocksMap().size() + " other instance(s)"); dataBlocks = event.getNodeConfiguration().getDataBlocksMap(); for (String blockId : dataBlocks.keySet()) { trigger(new RebalanceRequest(self, dataBlocks.get(blockId), blockId), network); } addToBandwidthDiagram(BANDWIDTH); } trigger(new InstanceStarted(self, cloudProvider, node), network); } private void addToBandwidthDiagram(long bandWidth) { xySeries.add(System.currentTimeMillis() - startTime, bandWidth); } private JFreeChart getBandwidthChart() { JFreeChart chart = ChartFactory.createXYLineChart("Bandwidth per download", "Time (ms)", "Bandwidth (B/s)", dataSet, PlotOrientation.VERTICAL, true, true, false); XYPlot plot = chart.getXYPlot(); XYItemRenderer renderer = plot.getRenderer(); renderer.setSeriesPaint(0, Color.blue); return chart; } public void takeSnapshot() { trigger(new SnapshotRequest(), cpu); } private boolean instanceRunning() { if (numberOfDevices != numberOfDevicesLoaded) return false; return enabled; } public void restartInstance() { trigger(new RestartSignal(), cpu); trigger(new RestartSignal(), memory); trigger(new RestartSignal(), disk); gui.systemRestart(); logger.warn("System restarting..."); numberOfDevicesLoaded = 0; pt.clear(); cancelAllPreviousTimers(); currentTransfers.clear(); requestQueue.clear(); xySeries.clear(); scheduleCPULoadPropagationToCloudProvider(); kernel.shutdown(); gui.decorateWhileSystemStartUp(); trigger(new StartMemoryUnit(), memory); trigger(new StartDiskUnit(), disk); loadKernel(); scheduleCPULoadPropagationToCloudProvider(); scheduleProcessingRequestQueue(); gui.decorateSystemStarted(); } /* private synchronized void checkIfCanAcceptRequest() { if (!acceptRequest) { boolean found = false; for (String pid : pt.keySet()) { if (pt.get(pid).getRequest().getDestinationNode() != null) { found = true; break; } } if (!found) acceptRequest = true; } trigger(new MemoryCheckOperation(), cpu); } */ }