/* * Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved * http://www.griddynamics.com * * This library is free software; you can redistribute it and/or modify it under the terms of * the Apache License; either * version 2.0 of the License, or any later version. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.griddynamics.jagger.engine.e1.scenario; import com.griddynamics.jagger.coordinator.NodeId; import com.griddynamics.jagger.user.ProcessingConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Maps; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** * User: dkotlyarov */ public class UserClock implements WorkloadClock { private static final Logger log = LoggerFactory.getLogger(UserClock.class); private final Random random; private final long startTime = System.currentTimeMillis(); private final UserWorkload workload; private final int totalUserCount; private final int tickInterval; private final AtomicBoolean shutdown; private boolean userStarted = false; public UserClock(List<ProcessingConfig.Test.Task.User> users, int delay, int tickInterval, AtomicBoolean shutdown) { this.random = new Random(0); this.workload = new UserWorkload(true, this, users, delay, startTime); this.totalUserCount = workload.getTotalUserCount(); this.tickInterval = tickInterval; this.shutdown = shutdown; } public Random getRandom() { return random; } public long getStartTime() { return startTime; } public UserWorkload getWorkload() { return workload; } public int getTotalUserCount() { return totalUserCount; } public AtomicBoolean getShutdown() { return shutdown; } public boolean isUserStarted() { return userStarted; } public void setUserStarted(boolean userStarted) { this.userStarted = userStarted; } @Override public Map<NodeId, Integer> getPoolSizes(Set<NodeId> nodes) { int max = totalUserCount / nodes.size() + 1; Map<NodeId, Integer> result = Maps.newHashMap(); for (NodeId node : nodes) { result.put(node, max); } return result; } @Override public void tick(WorkloadExecutionStatus status, WorkloadAdjuster adjuster) { log.debug("Going to perform tick with status {}", status); Set<NodeId> nodes = status.getNodes(); LinkedHashMap<NodeId, WorkloadConfiguration> workloadConfigurations = new LinkedHashMap<NodeId, WorkloadConfiguration>(nodes.size()); for (NodeId node : nodes) { WorkloadConfiguration workloadConfiguration = WorkloadConfiguration.with(status.getThreads(node), status.getDelay(node)); workloadConfigurations.put(node, workloadConfiguration); } long time = System.currentTimeMillis(); workload.tick(time, workloadConfigurations); for (Map.Entry<NodeId, WorkloadConfiguration> workloadConfigurationEntry : workloadConfigurations.entrySet()) { NodeId nodeId = workloadConfigurationEntry.getKey(); WorkloadConfiguration workloadConfiguration = workloadConfigurationEntry.getValue(); if ((workloadConfiguration.getThreads() != status.getThreads(nodeId)) || (workloadConfiguration.getDelay() != status.getDelay(nodeId))) { adjuster.adjustConfiguration(nodeId, workloadConfiguration); log.debug("Adjust configuration {} for node {}", workloadConfiguration, nodeId); } } if (userStarted && (workload.getStartedUserCount()==workload.getTotalUserCount()) && (workload.getActiveUserCount() == 0)) { shutdown.set(true); } } @Override public int getTickInterval() { return tickInterval; } @Override public int getValue() { return totalUserCount; } @Override public String toString() { return totalUserCount + " virtual user with " + workload.getDelay() + " delay"; } }