Tutorial 5: Modify Resources Based on Load Information
This tutorial describes how to create a registered EGO client that modifies resources in accordance with changes in resource loading. A minimum of two resources is required.
Using this tutorial, you will ...
- Open a connection to the EGO Web Service endpoint
- Retrieve and print out cluster info
- Check that the cluster has enough resources
- Register the client with Platform EGO and print out the registration response
- Request a resource allocation
- Check for notification of resource allocation
- Create an activity that will run on the requested resource
- Check the resource loading
- Modify the resources
- Locate the client and print out the client info
- Unregister the client
Step 1: Import class references
Import the necessary classes and interfaces that are required by the client to invoke the Web Service.
Step 2: Retrieve cluster information
Refer to Tutorial 1: Step 2: Retrieve cluster information.
Step 3: Check that the cluster has enough resources
Pass null as an argument to the resourceInfo() method to retrieve all resources in the cluster. For this sample, we need at least two resources.
Resource [] resources = client.resourceInfo(null); int num = 0; int needed = 2; if(resources != null) { num = resources.length; } if (num < needed) { System.err.println("Cluster Requirement: Should be run on a cluster with at least " + needed + " resources, it has only "+num); notification.stop(); return; }Step 4: Register the client
Refer to Tutorial 2: Step 3: Register the client.
Step 5: Make a resource allocation request
Refer to Tutorial 3: Step 4: Make a resource allocation request. In this sample, we make an allocation request for one resource.
Step 6: Check for notification of resource allocation
Refer to Tutorial 3: Step 5: Check the allocation status.
Step 7: Create an activity that will run on a requested resource
Refer to Tutorial 3: Step 6: Create and start an activity on a resource. In this sample, we create 10 activities on a single resource.
Step 8: Check the resource loading
Wait 40 seconds and pass the activity ID to the getActivityResourceLoad() method. This method collects the resource names associated with the activity ID. Pass the resource names array to the calculateAcvtivityLoad() method, which cycles through the array and retrieves the load attribute index associated with each resource. The getLoadAttributeIndex() method cycles through the list of resource attributes looking for the r1m load index. (The r1m load index represents the average number of processes ready to use the CPU during a one-minute interval.) This method returns the attribute array index corresponding to load index r1m. The value for r1m is retrieved and converted to a double data type. This value is stored in a variable (total), which is used as an accumulator. The total sum is then divided by the number of resources to yield the average load index value of r1m. The activity ID and the average load index value are printed out.
Step 9: Modify the resources
Pass the activity ID, delta, loadThreshold, and hysteresis variables as arguments to the modifyActivity() method. The delta value represents the number of resources to be added or released based on the load. However if the load is within the hysteresis range, no change is made; this is to prevent oscillatory behaviour.
Call the getActivityResourceLoad() method to determine the average load on resources; see description for the getActivityResourceLoad() method in Step 8: Check the resource loading. Retrieve the allocation ID from the ActivityResources object (activityResources).
Check if the average load exceeds the load threshold plus the hysteresis value. If the average load exceeds the threshold, call the modifyResources() method to add another resource to the activity allocation; if it doesn't, call the modifyResources() method to drop a resource from the activity allocation.
public void modifyActivity(String activityId, int delta, double loadThreshold, double hysterisys) { // for any resource that this activity is running on // find load, how do you define activity load? on a specefic resource double load = getActivityResourceLoad(activityId); ActivityResources activityResources = activityidToResourcesMap.get(activityId); String allocationId = activityResources.getAllocationId(); // if greater than loadThreshold + hysterisys/2, release specific resources, blklist? if(load > (loadThreshold + hysterisys/2)) { // load on the resources is high, need to add resources to activity allocation modifyResources(allocationId, delta, true); } // if less than loadThreshold - hysterisis/2, add resources if(load < (loadThreshold + hysterisys/2)) { // resources are lightly loaded, can drop resources from allocation modifyResources(allocationId, delta, false); } }In the modifyResources() method, check if the client can connect to the AllocationPortType endpoint. If successful, create a resource specification (resSpec). If a resource needs to be added to the allocation, set the resSpec object so that the minimum and maximum resources is increased by one; otherwise, decrease the minimum and maximum resources by one.
Create an allocation specification (alocSpec). This allocation specification describes a request to Platform EGO for an allocation of resources. The only required variables for the allocation specification are the consumer name to charge this allocation to, and the resource specification (resSpec) of what is being requested.
Create a modify allocation request object (malocReq) and link it with the client name, allocation ID, and allocation specification (alocSpec). Create the security document and the modify allocation response (malocRes).
Call the ModifyAllocation() method with the modify allocation request document (malocReqDoc) and the logon document (logonDoc) as input arguments. This method is used to modify the parameters of an existing allocation. If an error occurs, release the resources associated with the allocation ID by calling the releaseResources() method.
public void modifyResources(String allocationId, int delta, boolean add) { if (allocPort == null) { try { allocPort = new AllocationPortTypeStub(); } catch (Exception e) { e.printStackTrace(); return; } } // release resources // another possibility is to release specific resources that are loaded ResourceSpecification[] resSpecs = new ResourceSpecification[1]; ResourceSpecification resSpec = ResourceSpecification.Factory.newInstance(); if (!add) { resSpec.setMaxResources(new BigInteger(Integer.toString(-delta))); resSpec.setMinResources(new BigInteger(Integer.toString(-delta))); } else { resSpec.setMaxResources(new BigInteger(Integer.toString(delta))); resSpec.setMinResources(new BigInteger(Integer.toString(delta))); } resSpec.setResourceGroupName("ComputeHosts"); resSpec.setResourceRequirement("LINUX86"); // NTX86 // TODO "EGO_ALLOC_EXCLUSIVE" resSpecs[0] = resSpec; AllocationSpecificationDocument alocSpecDoc = AllocationSpecificationDocument.Factory.newInstance(); AllocationSpecification alocSpec = alocSpecDoc.addNewAllocationSpecification(); alocSpec.setAllocationName("Sample3Allocation"); alocSpec.setConsumerName("/SampleApplications/EclipseSamples"); alocSpec.setResourceSpecificationArray(resSpecs); // alocSpec.setOptionArray(new String[]{"EGO_ALLOC_EXCLUSIVE"}); //TODO ModifyAllocationRequestDocument malocReqDoc = ModifyAllocationRequestDocument.Factory.newInstance(); ModifyAllocationRequest malocReq = malocReqDoc.addNewModifyAllocationRequest(); malocReq.setClientName(clientId); malocReq.setAllocationID(allocationId); malocReq.setAllocationSpecification(alocSpec); malocReq.setOptionArray(new String[] { "EGO_REALLOC_DELTA" }); ModifyAllocationResponseDocument malocResDoc; ModifyAllocationResponse malocRes;
boolean release = false; try { malocResDoc = allocPort.ModifyAllocation(malocReqDoc, logonDoc); malocRes = malocResDoc.getModifyAllocationResponse(); // TODO what is the response? } catch (RemoteException rex) { // this could be because we cannot shrink below already allocated // release the resource explicitly in that case or releaseResources(allocationId, delta); release = true; // another alternative is to cancel allocation // return; } int changes = 0; if (add) { while (changes < delta){ // TODO start a new thread to wait for Resource notification changes += checkAddResourceNotification(); createActivity(alocIds.get(0), changes); } } return; }Create an AllocatedResources object (allocatedResources) and associate it with the allocation ID.
Create a release resource request object (rrreq) and link it with the client name, allocation ID, and the resource entries for all resources. The resource entry consists of one or more elements describing which resources to remove from the allocation. They must be part of the existing allocation to be released.
Create the security documents and the release resource response (rrres)
Call the ReleaseResource() method with the release resource response document (rrreqDoc), the logon document (logonDoc), and two security documents as input arguments. This method is used to release resources from an existing allocation. In this sample, one resource is released since this was the value of delta, which represents the number of resources to add or release.
public void releaseResources(String allocationId, int delta) { AllocatedResources allocatedResources = allocidToResourcesMap.get(allocationId); Resource [] resources = allocatedResources.getResourcesToRelease(delta); if (resources == null || resources.length ==0) { return; } ReleaseResourceRequestDocument rrreqDoc = ReleaseResourceRequestDocument.Factory.newInstance(); ReleaseResourceRequest rrreq = rrreqDoc.addNewReleaseResourceRequest(); rrreq.setAllocationID(allocationId); rrreq.setClientName(clientId); ResourceEntry [] resourceEntries = new ResourceEntry[resources.length]; for(int i=0; i<resources.length; i++){ ResourceEntry entry = ResourceEntry.Factory.newInstance(); entry.setResourceName(resources[i].getResourceName()); entry.setResourceType(resources[i].getResourceType()); resourceEntries[i] = entry; } rrreq.setResourceEntryArray(resourceEntries); rrreq.setOptionArray(new String[]{"EGO_RELEASE_AUTOADJ"}); if(allocPort == null) { System.err.println("Could not release resource"); return; } SecurityDocument sdoc2 = SecurityDocument.Factory.newInstance(); SecurityHeaderType sec2 = sdoc2.addNewSecurity(); SecurityDocument sdoc3 = SecurityDocument.Factory.newInstance(); SecurityHeaderType sec3 = sdoc3.addNewSecurity(); ReleaseResourceResponseDocument rrresDoc; ReleaseResourceResponse rrres; try { rrresDoc = allocPort.ReleaseResource(rrreqDoc, logonDoc, sdoc2, sdoc3); rrres = rrresDoc.getReleaseResourceResponse(); //TODO what does the response contain? } catch (RemoteException rex) { rex.printStackTrace(); return; } }Step 10: Locate the client
Refer to Tutorial 2: Step 4: Locate the client.
Step 11: Unregister the client
Refer to Tutorial 2: Step 5: Unregister the client.
Run the client application
- Select Run > Run.
The Run dialog appears.
- In the Configurations list, either select a Java Application or click New for a new configuration.
For a new configuration, enter the configuration name.
- Enter the project name and Main class.
- Click the Arguments tab and enter the following arguments in the given order:
- URL of the web service gateway
- Port number (string) for the notification interface
- Client ID (string)
- Client description (string).
note:
Arguments must be separated by a space.
![]()
- Click Apply and then Run.
Sample Output
![]()
![]()
![]()
[ Top ]
[ Platform Documentation ]
Date Modified: July 12, 2006
Platform Computing: www.platform.com
Platform Support: support@platform.com
Platform Information Development: doc@platform.com
Copyright © 1994-2006 Platform Computing Corporation. All rights reserved.