finish about schedule

this.setFinished(true);
This commit is contained in:
coderfengyun 2014-09-01 17:32:26 +08:00
parent ddc57ba3ca
commit 3e73f4b4ed
8 changed files with 133 additions and 50 deletions

View File

@ -1,7 +1,6 @@
package org.bench4q.agent.api; package org.bench4q.agent.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -21,7 +20,6 @@ import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.RunScenarioResultModel; import org.bench4q.share.models.agent.RunScenarioResultModel;
import org.bench4q.share.models.agent.StopTestModel; import org.bench4q.share.models.agent.StopTestModel;
import org.bench4q.share.models.agent.TestBriefStatusModel; import org.bench4q.share.models.agent.TestBriefStatusModel;
import org.bench4q.share.models.agent.UpdatePopulationModel;
import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel; import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel;
import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel; import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel;
import org.bench4q.share.models.agent.statistics.AgentPageBriefModel; import org.bench4q.share.models.agent.statistics.AgentPageBriefModel;
@ -247,32 +245,20 @@ public class TestController {
if (scenarioContext == null) { if (scenarioContext == null) {
return null; return null;
} }
scenarioContext.setEndDate(new Date(System.currentTimeMillis()));
System.out.println("when before stop, classId:" System.out.println("when before stop, classId:"
+ scenarioContext.getExecutor().toString()); + scenarioContext.getExecutor().toString());
scenarioContext.getExecutor().shutdown();
scenarioContext.getExecutor().shutdownNow();
System.out.println("when after stop, classId:" System.out.println("when after stop, classId:"
+ scenarioContext.getExecutor().toString()); + scenarioContext.getExecutor().toString());
scenarioContext.setFinished(true); scenarioContext.stop();
clean(runId); clean();
return new StopTestModel(true); return new StopTestModel(true);
} }
@RequestMapping(value = "/clean/{runId}", method = RequestMethod.GET) @RequestMapping(value = "/clean", method = RequestMethod.GET)
@ResponseBody @ResponseBody
public CleanTestResultModel clean(@PathVariable UUID runId) { public CleanTestResultModel clean() {
this.getScenarioEngine().getRunningTests().remove(runId);
System.gc(); System.gc();
return new CleanTestResultModel(true); return new CleanTestResultModel(true);
} }
@RequestMapping(value = "/updatePopulation/{runId}/{requiredLoad}", method = {
RequestMethod.POST, RequestMethod.GET })
@ResponseBody
public UpdatePopulationModel updatePopulation(@PathVariable UUID runId,
@PathVariable int requiredLoad) {
this.getScenarioEngine().updatePopulation(runId, requiredLoad);
return new UpdatePopulationModel(true);
}
} }

View File

@ -11,24 +11,41 @@ import java.util.TimerTask;
import org.bench4q.share.exception.Bench4QRunTimeException; import org.bench4q.share.exception.Bench4QRunTimeException;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel; import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel; import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
/*
* Segments in Schedule is sorted asc by Segment.start.time
*/
public class Schedule extends Observable { public class Schedule extends Observable {
private static final int SCHEDULE_CYCLE = 3000; private static final int SCHEDULE_CYCLE = 3000;
private final List<Segment> segments; private final List<Segment> segments;
private final long beginTime; private final long beginTime;
private volatile boolean reachEnd;
public List<Segment> getSegments() { public List<Segment> getSegments() {
return segments; return segments;
} }
public boolean hasReachEnd() {
return this.reachEnd;
}
private void reachEnd() {
this.reachEnd = true;
}
public Schedule(List<Segment> segments) { public Schedule(List<Segment> segments) {
if (segments == null || segments.size() == 0) { if (segments == null || segments.size() == 0) {
throw new Bench4QRunTimeException("Can't init a schedul with zero segment"); throw new Bench4QRunTimeException(
"Can't init a schedul with zero segment");
} }
this.segments = segments; this.segments = segments;
this.beginTime = System.currentTimeMillis(); this.beginTime = System.currentTimeMillis();
this.reachEnd = false;
beginSchedul(); beginSchedul();
}
public long getScheduleRange() {
return this.getSegments().get(this.getSegments().size()).end.getTime()
- this.getSegments().get(0).start.getTime();
} }
private void beginSchedul() { private void beginSchedul() {
@ -39,19 +56,42 @@ public class Schedule extends Observable {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
Segment segment = getSegment(time); Segment segment = getSegment(time);
if (segment == null) { if (segment == null) {
//exceed the range of execute, should let the context stop the test // exceed the range of execute, should let the context stop
// the test
notifyObservers(0);
return; return;
} }
segment.loadFor(time - beginTime); notifyObservers(segment.loadFor(time - beginTime));
} }
}, 0, SCHEDULE_CYCLE); }, 0, SCHEDULE_CYCLE);
} }
// get the segment by binary search // get the segment by binary search
protected Segment getSegment(long time) { public Segment getSegment(long time) {
if (this.getSegments() == null || this.getSegments().size() < 1
|| time < this.getSegments().get(0).start.getTime()) {
throw new Bench4QRunTimeException(
"can't getSegment when segments' size is LT 2");
}
if (time >= this.getSegments().get(this.getSegments().size() - 1).end
.getTime()) {
this.reachEnd();
return null; return null;
} }
int begin = 0, end = this.getSegments().size(), mid = (begin + end) / 2;
while (begin <= end) {
Segment midSegment = this.getSegments().get(mid);
if (midSegment.end.getTime() < time) {
begin = mid + 1;
} else if (midSegment.start.getTime() > time) {
end = mid - 1;
} else {
return midSegment;
}
mid = (begin + end) / 2;
}
throw new Bench4QRunTimeException("Should not come to this place");
}
public static class Segment { public static class Segment {
private final Point start; private final Point start;
@ -62,16 +102,21 @@ public class Schedule extends Observable {
public Segment(Point startPoint, Point endPoint) { public Segment(Point startPoint, Point endPoint) {
this.start = startPoint.copy(); this.start = startPoint.copy();
this.end = endPoint.copy(); this.end = endPoint.copy();
long timeDifference = this.end.getTime() / 1000 - this.start.getTime() / 1000; long timeDifference = this.end.getTime() / 1000
if (timeDifference < 0 || this.start.getTime() < 0l || this.end.getTime() < 0l) { - this.start.getTime() / 1000;
throw new Bench4QRunTimeException("The end time in TestScehdul cannot be less than start time"); if (timeDifference < 0 || this.start.getTime() < 0l
|| this.end.getTime() < 0l) {
throw new Bench4QRunTimeException(
"The end time in TestScehdul cannot be less than start time");
} }
this.growthUnit = (float) (timeDifference == 0 ? 0 : (double)(this.end.getLoad() - this.start.getLoad()) this.growthUnit = (float) (timeDifference == 0 ? 0
: (double) (this.end.getLoad() - this.start.getLoad())
/ (double) (timeDifference)); / (double) (timeDifference));
} }
public int loadFor(long timeFromBegin) { public int loadFor(long timeFromBegin) {
if (timeFromBegin < this.start.getTime() || timeFromBegin > this.end.getTime()) { if (timeFromBegin < this.start.getTime()
|| timeFromBegin > this.end.getTime()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
long diffFromStart = timeFromBegin - this.start.getTime(); long diffFromStart = timeFromBegin - this.start.getTime();
@ -93,6 +138,10 @@ public class Schedule extends Observable {
} }
public Point(long time, int load) { public Point(long time, int load) {
if (load < 0) {
throw new IllegalArgumentException(
"Load can't be negtive number!");
}
this.time = time; this.time = time;
this.load = load; this.load = load;
} }
@ -103,8 +152,8 @@ public class Schedule extends Observable {
} }
public static Schedule build(ScheduleModel scheduleModel) { public static Schedule build(ScheduleModel scheduleModel) {
Schedule schedule = new Schedule(extractSegments(scheduleModel.getPoints())); Schedule schedule = new Schedule(
extractSegments(scheduleModel.getPoints()));
return schedule; return schedule;
} }

View File

@ -1,6 +1,8 @@
package org.bench4q.agent.scenario.engine; package org.bench4q.agent.scenario.engine;
import java.util.Date; import java.util.Date;
import java.util.Observable;
import java.util.Observer;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@ -12,8 +14,9 @@ import org.bench4q.agent.datacollector.DataCollector;
import org.bench4q.agent.datacollector.impl.ScenarioResultCollector; import org.bench4q.agent.datacollector.impl.ScenarioResultCollector;
import org.bench4q.agent.plugin.PluginManager; import org.bench4q.agent.plugin.PluginManager;
import org.bench4q.agent.scenario.Scenario; import org.bench4q.agent.scenario.Scenario;
import org.bench4q.agent.scenario.Schedule;
public class ScenarioContext { public class ScenarioContext extends Observable implements Observer {
private static final long keepAliveTime = 10; private static final long keepAliveTime = 10;
private UUID testId; private UUID testId;
private Date startDate; private Date startDate;
@ -96,6 +99,7 @@ public class ScenarioContext {
ScenarioContext scenarioContext = buildScenarioContextWithoutScenario( ScenarioContext scenarioContext = buildScenarioContextWithoutScenario(
testId, poolSize, pluginManager); testId, poolSize, pluginManager);
scenarioContext.setScenario(scenario); scenarioContext.setScenario(scenario);
scenario.getSchedule().addObserver(scenarioContext);
return scenarioContext; return scenarioContext;
} }
@ -127,7 +131,7 @@ public class ScenarioContext {
* *
* @param requiredLoad * @param requiredLoad
*/ */
void updatePopulation(int requiredLoad) { public void updatePopulation(int requiredLoad) {
this.getExecutor().setCorePoolSize(requiredLoad); this.getExecutor().setCorePoolSize(requiredLoad);
this.getExecutor().setMaximumPoolSize(requiredLoad); this.getExecutor().setMaximumPoolSize(requiredLoad);
} }
@ -146,4 +150,20 @@ public class ScenarioContext {
addTask(); addTask();
} }
} }
@Override
public void update(Observable o, Object arg) {
Schedule schedule = (Schedule) o;
if (schedule.hasReachEnd()) {
stop();
}else {
this.updatePopulation((Integer) arg);
}
}
public void stop(){
this.setFinished(true);
this.setEndDate(new Date());
this.getExecutor().shutdownNow();
}
} }

View File

@ -3,6 +3,7 @@ package org.bench4q.agent.scenario.engine;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.bench4q.agent.plugin.PluginManager; import org.bench4q.agent.plugin.PluginManager;
import org.bench4q.agent.scenario.Scenario; import org.bench4q.agent.scenario.Scenario;
@ -71,9 +72,4 @@ public class ScenarioEngine {
scenarioContext.initTasks(); scenarioContext.initTasks();
return true; return true;
} }
public void updatePopulation(UUID testId, int requiredLoad) {
ScenarioContext context = this.getRunningTests().get(testId);
context.updatePopulation(requiredLoad);
}
} }

View File

@ -0,0 +1,11 @@
package org.bench4q.agent.scenario.engine;
import java.util.Timer;
public class Supervisor {
private Timer timer;
public Supervisor(ScenarioContext context){
timer = new Timer();
}
}

View File

@ -3,6 +3,7 @@ package org.bench4q.agent.test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -18,7 +19,9 @@ import org.bench4q.share.models.agent.RunScenarioModel;
import org.bench4q.share.models.agent.scriptrecord.BatchModel; import org.bench4q.share.models.agent.scriptrecord.BatchModel;
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel; import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
import org.bench4q.share.models.agent.scriptrecord.PageModel; import org.bench4q.share.models.agent.scriptrecord.PageModel;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel; import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
public abstract class TestBase { public abstract class TestBase {
@ -105,6 +108,12 @@ public abstract class TestBase {
batch.getBehaviors().add(behavior); batch.getBehaviors().add(behavior);
} }
page.getBatches().add(batch); page.getBatches().add(batch);
ScheduleModel scheduleModel = new ScheduleModel();
List<PointModel> points = new LinkedList<ScheduleModel.PointModel>();
points.add(new PointModel(0, 0));
points.add(new PointModel(10000, 10));
scheduleModel.setPoints(points);
runScenarioModel.setScheduleModel(scheduleModel);
runScenarioModel.getPages().add(page); runScenarioModel.getPages().add(page);
return runScenarioModel; return runScenarioModel;
} }

View File

@ -49,7 +49,7 @@ public class Test_ScenarioEngine extends TestBase {
new ArrayList<ParameterModel>()))), new ArrayList<ParameterModel>()))),
100, this.pluginManager); 100, this.pluginManager);
this.getScenarioEngine().getRunningTests().put(testId, scenarioContext); this.getScenarioEngine().getRunningTests().put(testId, scenarioContext);
this.getScenarioEngine().updatePopulation(testId, 20); scenarioContext.updatePopulation(20);
assertEquals(20, scenarioContext.getExecutor().getMaximumPoolSize()); assertEquals(20, scenarioContext.getExecutor().getMaximumPoolSize());
System.out.println(scenarioContext.getExecutor().getActiveCount()); System.out.println(scenarioContext.getExecutor().getActiveCount());
} }

View File

@ -3,7 +3,9 @@ package org.bench4q.agent.test.scenario.engine;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.util.Date; import java.util.Date;
import org.bench4q.agent.scenario.Schedule; import org.bench4q.agent.scenario.Schedule;
import org.bench4q.agent.scenario.Schedule.Segment;
import org.bench4q.share.exception.Bench4QRunTimeException; import org.bench4q.share.exception.Bench4QRunTimeException;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel; import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel; import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
@ -72,4 +74,14 @@ public class Test_Shedule {
int load = schedule.getSegments().get(0).loadFor(500 * 1000); int load = schedule.getSegments().get(0).loadFor(500 * 1000);
assertEquals(75, load); assertEquals(75, load);
} }
@Test
public void test_getSegment(){
ScheduleModel model = new ScheduleModel();
model.getPoints().add(new PointModel(1000000, 100));
model.getPoints().add(new PointModel(0, 50));
Schedule schedule = Schedule.build(model);
Segment segment = schedule.getSegment(500 * 1000);
assertNotNull(segment);
}
} }