package jadex.micro.benchmarks; import jadex.bridge.Argument; import jadex.bridge.ComponentResultListener; import jadex.bridge.CreationInfo; import jadex.bridge.IArgument; import jadex.bridge.IComponentIdentifier; import jadex.bridge.IComponentManagementService; import jadex.bridge.IComponentStep; import jadex.bridge.IInternalAccess; import jadex.commons.IFuture; import jadex.commons.concurrent.DefaultResultListener; import jadex.commons.concurrent.IResultListener; import jadex.commons.service.SServiceProvider; import jadex.commons.service.clock.IClockService; import jadex.micro.IMicroExternalAccess; import jadex.micro.MicroAgent; import jadex.micro.MicroAgentMetaInfo; import java.util.HashMap; import java.util.Map; /** * Agent creation benchmark. */ public class AgentCreationAgent extends MicroAgent { //-------- methods -------- /** * Execute an agent step. */ public void executeBody() { Map arguments = getArguments(); if(arguments==null) arguments = new HashMap(); final Map args = arguments; if(args.get("num")==null) { SServiceProvider.getService(getServiceProvider(), IClockService.class).addResultListener(new ComponentResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { args.put("num", new Integer(1)); Long startmem = new Long(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()); Long starttime = new Long(((IClockService)result).getTime()); args.put("startmem", startmem); args.put("starttime", starttime); step1(args); } }, getAgentAdapter())); } else { step1(args); } } /** * Execute the first step. */ protected void step1(final Map args) { final int num = ((Integer)args.get("num")).intValue(); final int max = ((Integer)args.get("max")).intValue(); final boolean nested = ((Boolean)args.get("nested")).booleanValue(); System.out.println("Created peer: "+num); if(num<max) { args.put("num", new Integer(num+1)); // System.out.println("Args: "+num+" "+args); SServiceProvider.getServiceUpwards(getServiceProvider(), IComponentManagementService.class).addResultListener(createResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { ((IComponentManagementService)result).createComponent(createPeerName(num+1, getComponentIdentifier()), AgentCreationAgent.this.getClass().getName()+".class", new CreationInfo(args, nested ? getComponentIdentifier() : null), null); } })); } else { Long startmem = (Long)args.get("startmem"); final Long starttime = (Long)args.get("starttime"); final long used = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); final long omem = (used-startmem.longValue())/1024; final double upera = ((long)(1000*(used-startmem.longValue())/max/1024))/1000.0; System.out.println("Overall memory usage: "+omem+"kB. Per agent: "+upera+" kB."); getTime().addResultListener(createResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { final long end = ((Long)result).longValue(); System.out.println("Last peer created. "+max+" agents started."); final double dur = ((double)end-starttime.longValue())/1000.0; final double pera = dur/max; System.out.println("Needed: "+dur+" secs. Per agent: "+pera+" sec. Corresponds to "+(1/pera)+" agents per sec."); // Delete prior agents. if(!nested) { deletePeers(max-1, end, dur, pera, omem, upera, max, (IMicroExternalAccess)getExternalAccess(), nested); } // If nested, use initial component to kill others else { SServiceProvider.getServiceUpwards(getServiceProvider(), IComponentManagementService.class).addResultListener(createResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { IComponentManagementService cms = (IComponentManagementService)result; String initial = createPeerName(1, getComponentIdentifier()); IComponentIdentifier cid = cms.createComponentIdentifier(initial, true); cms.getExternalAccess(cid).addResultListener(createResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { IMicroExternalAccess exta = (IMicroExternalAccess)result; deletePeers(max, end, dur, pera, omem, upera, max, exta, nested); } })); } })); } } })); } } /** * Create a name for a peer with a given number. */ protected String createPeerName(int num, IComponentIdentifier cid) { String name = cid.getLocalName(); int index = name.indexOf("Peer_#"); if(index!=-1) { name = name.substring(0, index); } if(num!=1) { name += "Peer_#"+num; } return name; } /** * Delete all peers from last-1 to first. * @param cnt The highest number of the agent to kill. */ protected void deletePeers(final int cnt, final long killstarttime, final double dur, final double pera, final long omem, final double upera, final int max, final IMicroExternalAccess exta, final boolean nested) { final String name = createPeerName(cnt, exta.getComponentIdentifier()); // System.out.println("Destroying peer: "+name); SServiceProvider.getService(exta.getServiceProvider(), IComponentManagementService.class) .addResultListener(new DefaultResultListener() { public void resultAvailable(Object source, final Object result) { exta.scheduleStep(new IComponentStep() { public Object execute(IInternalAccess ia) { IComponentManagementService cms = (IComponentManagementService)result; IComponentIdentifier aid = cms.createComponentIdentifier(name, true, null); IResultListener lis = new IResultListener() { public void resultAvailable(Object source, Object result) { exta.scheduleStep(new IComponentStep() { public Object execute(IInternalAccess ia) { System.out.println("Successfully destroyed peer: "+name); if(cnt-1>(nested?1:0)) { deletePeers(cnt-1, killstarttime, dur, pera, omem, upera, max, exta, nested); } else { killLastPeer(max, killstarttime, dur, pera, omem, upera, exta); } return null; } }); } public void exceptionOccurred(Object source, Exception exception) { exception.printStackTrace(); } }; IFuture ret = cms.destroyComponent(aid); ret.addResultListener(lis); return null; } }); } }); } /** * Kill the last peer and print out the results. */ protected void killLastPeer(final int max, final long killstarttime, final double dur, final double pera, final long omem, final double upera, final IMicroExternalAccess exta) { SServiceProvider.getService(exta.getServiceProvider(), IClockService.class) .addResultListener(new DefaultResultListener() { public void resultAvailable(Object source, final Object result) { exta.scheduleStep(new IComponentStep() { public Object execute(IInternalAccess ia) { IClockService cs = (IClockService)result; long killend = cs.getTime(); System.out.println("Last peer destroyed. "+(max-1)+" agents killed."); double killdur = ((double)killend-killstarttime)/1000.0; double killpera = killdur/(max-1); Runtime.getRuntime().gc(); long stillused = (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/1024; System.out.println("\nCumulated results:"); System.out.println("Creation needed: "+dur+" secs. Per agent: "+pera+" sec. Corresponds to "+(1/pera)+" agents per sec."); System.out.println("Killing needed: "+killdur+" secs. Per agent: "+killpera+" sec. Corresponds to "+(1/killpera)+" agents per sec."); System.out.println("Overall memory usage: "+omem+"kB. Per agent: "+upera+" kB."); System.out.println("Still used memory: "+stillused+"kB."); SServiceProvider.getService(exta.getServiceProvider(), IComponentManagementService.class) .addResultListener(new DefaultResultListener() { public void resultAvailable(Object source, final Object result) { exta.scheduleStep(new IComponentStep() { public Object execute(IInternalAccess ia) { IComponentManagementService cms = (IComponentManagementService)result; cms.destroyComponent(exta.getComponentIdentifier()); return null; } }); } }); return null; } }); } }); } /** * Get the meta information about the agent. */ public static Object getMetaInfo() { return new MicroAgentMetaInfo("This agents benchmarks agent creation and termination.", new String[0], new IArgument[]{new IArgument() { public Object getDefaultValue(String configname) { return new Integer(5000); // Todo: support 10000 with gui. } public String getDescription() { return "Maximum number of agents to create."; } public String getName() { return "max"; } public String getTypename() { return "Integer"; } public boolean validate(String input) { boolean ret = true; try { Integer.parseInt(input); } catch(Exception e) { ret = false; } return ret; } }, new Argument("nested", "If true, each agent is created as a subcomponent of the previous agent.", "boolean", Boolean.FALSE)}, null, null, null); } }