New Year’s Eve

This example illustrates a simple usage of resource management, balancing resources between two servers based on client traffic. The example is inspired by mobile phone users on New Year’s Eve, who change their behavior from alternating between making phone calls and sending SMS to flooding the SMS server with messages during the “midnight window” on New Year’s Eve.

1 Modeling the Servers

We consider two simple services:

Telephone Service: This service allows clients to place calls with a given duration

The two services are implemented by servers. For this example we consider very simple servers, implemented by ABS classes. The telephone server offers a method call which takes the remaining time of the call as parameter. The remaining time of a call decrements for every time interval, as expressed by the ABS statement await duration(1,1). The SMS server offers a method sendSMS. Each server has a counter to keep track of the number of client requests they have received.

By uncommenting the print-statements, you will be able to see the activity of the servers on the console.

2 Modeling a Client

We model a client Handset which interacts with the telephone and SMS services. The handset makes requests to the two servers. The normal behavior of the handset is to alternate between sending an SMS and making a call at each time interval. When it makes a call, it waits for the call to end before proceeding. (In our example, the duration of the call is 1 time interval.) This gives us the following scenario:

However, every year at at midnight on New Year’s Eve, the behavior changes. For a certain period, the handsets stop making calls and flood the server with SMS messages. Therefore, we model the handset with a spike. In our example, the spike starts at time 50 and ends at time 70. This gives us the following scenario:

This handset’s spike occurs periodically, every 100 time intervals. During a spike, the handset asynchronously sends 10 SMS requests. To evaluate whether the current time is in a spike period, the expression timeValue(now()) returns the current time as a Rat, which we compare modulo the spikeperiod to the interval starting at 50 and ending at 70.

4 Deploying the Servers

Let us now make this model resource-sensitive by deploying the servers on (virtual) machines.

We first extend the servers with a very simple cost model. We add a cost of 1 for each time interval during a call and for each sendSMS invocation. The costs are added as annotations to the two server classes (which are otherwise unchanged):

We then define two deployment components in the main block, one for the telephone server and the other for the SMS server.This results in the following model:

We let the two deployment components have the same processing speed, 90. To create some more traffic, let us consider a model with 20 handsets.

{ // Main block:
DC smscomp = new DeploymentComponent("smscomp", map[Pair(Speed, 90)]);
DC telcomp = new DeploymentComponent("telcomp", map[Pair(Speed, 90)]);
println("[Time: "+toString(timeValue(now()))+"] Starting servers");
[DC: smscomp] SMSService sms = new SMSServer();
[DC: telcomp] TelephoneService tel = new TelephoneServer();
println("[Time: "+toString(timeValue(now()))+"] Starting handsets");
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
await duration(1,1); // Slightly out of phase
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
new Handset(100,tel,sms);
}

If we compile and run the resource-sensitive model in the Erlang simulator, the console shows us when the handsets enter and leave the spike periods. In order to see the effect of the spike periods on the resource-aware model, we look at the deployment view. The two images below show the processing capacity and load of the two machines after slightly more 500 time intervals:

We see that the load on the telephone server (“telcomp”) drops to 0 in the spike periods, and that the load on the SMS server (“smscomp”) goes to 100%. Obersve that there is a backlog of sendSMS requests on the SMS server: although the spike period ends at time interval 70, the server resumes normal load slightly before time 100.

5 Load-Balancing of Resources

We now consider how the model can be made resource-aware and enable the two machines hosting the telephone and SMS servers to exchange resources. The idea we pursue here is to define a simple resource manager (“Balancer”) for each server which monitors load and requests resources from the other machine if necessary. Each Balancer has an interface which allows the partner Balancer to be specified and resources to be requested:

The class itself takes as parameters a name (for friendly console-messages) and a minimum value for the locally available resources. The class has an active process defined by its run() method, which monitors the local load. Note that thisDC() is a reference to the deployment component on which an object is deployed and the method call load(Speed, 1) returns the percentwise usage of processing speed in the previous time interval. If the load is above 90%, the Balancer requests resources from its partner. If a Balancer receives a request for resources, it will transfer 1/3 of its available processing speed to its partner, unless this would reduce its own capacity below the minimum.

Here, there are two thresholds which regulate the behavior of the local Balancer objects:

Threshold 1: Local load has reached a critical limit (here: ld>90). In this case, the Balancer will request resources from the partner Balancer.

Threshold 2: Available processing speed has reached a critical limit (here represented by ld < 50 && (finvalue(total)-requested>minimum). In this case, the Balancer will not transfer resources to the partner Balancer.

We add the Balancers to the main block of the model and set the partner Balancer: