001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: //package org.cougaar.lib.quo.performance;
027: package org.cougaar.lib.quo.performance;
028:
029: import java.io.FileWriter;
030: import java.util.Collections;
031: import java.util.Date;
032: import java.util.Enumeration;
033: import java.util.Vector;
034:
035: import org.cougaar.core.blackboard.ChangeReport;
036: import org.cougaar.core.blackboard.IncrementalSubscription;
037: import org.cougaar.lib.quo.performance.assets.ProgrammerAsset;
038: import org.cougaar.planning.ldm.plan.AllocationResult;
039: import org.cougaar.planning.ldm.plan.AspectType;
040: import org.cougaar.planning.ldm.plan.AspectValue;
041: import org.cougaar.planning.ldm.plan.PlanElement;
042: import org.cougaar.planning.ldm.plan.Role;
043: import org.cougaar.planning.ldm.plan.Task;
044: import org.cougaar.planning.ldm.plan.Verb;
045: import org.cougaar.util.UnaryPredicate;
046:
047: /**
048: * This COUGAAR Plugin subscribes to tasks in a workflow and allocates
049: * the workflow sub-tasks to programmer assets.
050: **/
051: public class DevelopmentAllocatorPlugin extends CommonUtilPlugin {
052: private IncrementalSubscription allCodeTasks; // Tasks that I'm interested in
053: private IncrementalSubscription allProgrammers; // Programmer assets that I allocate to
054:
055: protected int CPUCONSUME, MESSAGESIZE, MAXCOUNT;
056: protected int THINK_TIME, OUTSTANDING_MESSAGES;
057: protected String FILENAME, VERB;
058: protected Task task;
059: protected boolean DEBUG = false, LOG = false;
060: protected Date startTime;
061: protected long minDelta = 0;
062: protected FileWriter fw;
063: protected int wakeUpCount, taskAllocationCount, count = 1;
064: protected AspectValue allocAspectVal;
065: protected double allocNum = 0;
066: protected int expectedSeqNum = 1;
067:
068: /**
069: * parsing the plugIn arguments and setting the values
070: */
071: protected void parseParameter() {
072: Vector p = getParameters();
073: CPUCONSUME = getParameterIntValue(p, "CPUCONSUME");
074: MESSAGESIZE = getParameterIntValue(p, "MESSAGESIZE");
075: FILENAME = getParameterValue(p, "FILENAME");
076: MAXCOUNT = getParameterIntValue(p, "MAXCOUNT");
077: OUTSTANDING_MESSAGES = getParameterIntValue(p,
078: "OUTSTANDING_MESSAGES");
079: DEBUG = getParameterBooleanValue(p, "DEBUG");
080: LOG = getParameterBooleanValue(p, "LOG");
081: VERB = getParameterValue(p, "VERB");
082: THINK_TIME = getParameterIntValue(p, "THINK_TIME");
083: }
084:
085: static class MyChangeReport implements ChangeReport {
086: private byte[] bytes;
087:
088: MyChangeReport(byte[] bytes) {
089: this .bytes = bytes;
090: }
091: }
092:
093: /**
094: * Predicate matching all ProgrammerAssets
095: */
096: private UnaryPredicate allProgrammersPredicate = new UnaryPredicate() {
097: public boolean execute(Object o) {
098: return o instanceof ProgrammerAsset;
099: }
100: };
101:
102: /**
103: * Predicate that matches all Test tasks
104: */
105: private UnaryPredicate codeTaskPredicate = new UnaryPredicate() {
106: public boolean execute(Object o) {
107: if (o instanceof Task) {
108: Task task = (Task) o;
109: return task.getVerb().equals(Verb.get(VERB));
110: }
111: return false;
112: }
113: };
114:
115: /**
116: * Establish subscription for tasks and assets
117: **/
118: public void setupSubscriptions() {
119: parseParameter();
120: allProgrammers = (IncrementalSubscription) subscribe(allProgrammersPredicate);
121: allCodeTasks = (IncrementalSubscription) subscribe(codeTaskPredicate);
122: }
123:
124: /**
125: * Top level plugin execute loop. Handle changes to my subscriptions.
126: **/
127: public void execute() {
128: wakeUpCount++;
129: debug(DEBUG, "" + System.currentTimeMillis() + " wakeUpcount "
130: + wakeUpCount + "------------------");
131: allocateTasks(allCodeTasks.getAddedList());
132: allocateTasks(allCodeTasks.getChangedList());
133: }
134:
135: private void allocateTasks(Enumeration task_enum) {
136: while (task_enum.hasMoreElements()) {
137: taskAllocationCount++;
138: task = (Task) task_enum.nextElement();
139: startTime = new Date();
140: waitFor(THINK_TIME);
141: allocateTask(task, startMonth(task));
142: }
143: }
144:
145: /**
146: * Extract the start month from a task
147: */
148: private int startMonth(Task t) {
149: return 0;
150: }
151:
152: /**
153: * Find an available ProgrammerAsset for this task. Task must be scheduled
154: * after the month "after"
155: */
156: private int allocateTask(Task task, int after) {
157: if (CPUCONSUME != -1) //i.e. cpuconsume passed to plugin as a arg
158: consumeCPU(CPUCONSUME);
159:
160: int end = after;
161: int duration = 3;
162: int earliest = 0;
163: end = earliest + duration;
164: int desired_delivery = 10; //bogus
165: boolean onTime = (end <= desired_delivery);
166:
167: // select an available programmer at random
168: Vector programmers = new Vector(allProgrammers.getCollection());
169: boolean allocated = false;
170:
171: while ((!allocated) && (programmers.size() > 0)) {
172: int stuckee = (int) Math.floor(Math.random()
173: * programmers.size());
174: ProgrammerAsset asset = (ProgrammerAsset) programmers
175: .elementAt(stuckee);
176: allocNum = task.getPreferredValue(AspectType._ASPECT_COUNT);
177: String msg = "expectedSeqNum::receivedSeNum::"
178: + expectedSeqNum + ":" + allocNum;
179: if (expectedSeqNum > allocNum) {
180: debug(DEBUG, "Warning out of sequence task: " + msg);
181: } else {
182: if (expectedSeqNum < allocNum) {
183: debug(DEBUG, "Skipped a task: " + msg);
184: }
185: if (expectedSeqNum == allocNum) {
186: debug(DEBUG, "expectedSeqNum == receivedSeNum::"
187: + msg);
188: }
189: int[] aspect_types = { AspectType._ASPECT_COUNT };
190: double[] results = { allocNum };
191: AllocationResult estAR = theLDMF.newAllocationResult(
192: 1.0, onTime, aspect_types, results);
193:
194: ChangeReport cr = null;
195: if (MESSAGESIZE != -1)
196: cr = new MyChangeReport(
197: alterMessageSize(MESSAGESIZE));
198: else
199: cr = new MyChangeReport(alterMessageSize(0));
200:
201: //Allocation planElement
202: PlanElement pe = task.getPlanElement();
203: if (pe == null) {
204: pe = theLDMF.createAllocation(task.getPlan(), task,
205: asset, estAR, Role.ASSIGNED);
206: publishAdd(pe);
207: } else {
208: pe.setEstimatedResult(estAR);
209: publishChange(pe, Collections.singleton(cr));
210: }
211: publishRemove(task);
212: printTheChange(task);
213: expectedSeqNum = (int) allocNum + 1; //updating seq num
214: breakFromLoop(count, MAXCOUNT);
215: }
216: allocated = true;
217: }
218:
219: return end;
220: }
221:
222: protected void printTheChange(Task task) {
223: Date endTime = new Date();
224: long delta = endTime.getTime() - startTime.getTime();
225: if (count == 1)
226: minDelta = delta;
227: else
228: minDelta = Math.min(minDelta, delta);
229: int taskCount = (int) task
230: .getPreferredValue(AspectType._ASPECT_COUNT);
231: String msg = task.getVerb() + "=>" + taskCount + "," + delta
232: + "," + minDelta;
233: debug(DEBUG, " TaskAllocationCount:" + taskAllocationCount);
234: log(LOG, FILENAME, fw, msg);
235: count++;
236: }
237: }
|