Time management - Pyosch/powertac-server GitHub Wiki

up

General competition timeline

The simulation proceeds in a sequence of timeslots of an equal duration (nominally one hour sim time, 5 seconds or less real time). Each timeslot has a sequence number that starts from 0, a start time, and an end time. At any given time, a set of future timeslots is "enabled," which means that they are open for trading in the wholesale market. The current timeslot and all past timeslots are always closed.

width=480px

In the figure, we see the situation at a particular time. Two parameters define the set of timeslots open for trading at a given time: timeslotsOpen is the number of timeslots open for trading; deactivateTimeslotsAhead is the number of close timeslots between the current time and the first open timeslot.

Simulation clock

The CompetitionController sets up the TimeService to keep simulation time by setting four parameters:

  • base is the start of the simulated time period represented within the simulation. In bootstrap mode, this is the beginning of the simulation. In sim mode, it is the beginning of the bootstrap period.
  • start is the wall-clock time at which the simulation starts. In sim mode, it is when the sim starts, not when the bootstrap would have started if it were run immediately before the sim.
  • rate is the ratio of time progress inside the simulation to progress outside. So if rate=600, then time passes 600 times faster in the simulation than in the real world. This rate compresses an hour into 6 seconds.
  • modulo is the smallest increment of time represented in the simulation environment. Typically this is the length of a timeslot.

The base, rate, and modulo values are communicated to brokers at the start of a game in the Competition instance. The start value is communicated in the sim-start message once all server initialization is complete. To correctly set its clock, the broker must compute a base time that represents the beginning of the sim, by adding the duration of the bootstrap period (the sum of bootstrapDiscardedTimeslots and bootstrapTimeslotCount multiplied by timeslotDuration) to the simulationBaseTime given in the Competition instance.

The current simulation time is computed as simTime = (base + (currentTime - start) * rate) truncated to the last time when simTime % modulo = 0. This scheme keeps brokers synchronized with the server as long as both broker and server are running on machines that are synchronized with NTP. If you run a broker on an unsynchronized machine, the broker will likely have a different notion of the current sim time from the server, which can lead to a variety of "interesting" problems.

Other entities can retrieve the current time, or can post actions to be executed at a later time (although that feature is currently unused, having been superseded by the clock control). Several convenience constants are also provided, such as HOUR, DAY, and WEEK. Simulation time is derived from system time by a simple formula, so the parameters can be communicated to brokers, who may then keep their own time. This will keep server and brokers synchronized within milliseconds as long as all platforms are running ntp.

Time is represented as milliseconds since epoch in the UTC timezone, as in Unix/Linux. For convenience in representation, we use the joda.org time library. The basic type used to represent absolute time is org.joda.time.Instant. To see some examples of time representation, see org.powertac.common.TimeServiceSchedTest, under test/integration in the powertac-common repo.

Pausing the clock

If we run an aggressive schedule, there will be times when the server does not complete all its actions within the period allotted to a timeslot. Also, for debugging purposes and to support GUI-controlled agents, it may be useful to allow a broker to request a pause in the clock. Here is a scheme that supports both needs:

width=800px

Timeslot event sequence

In the server, each timeslot begins with a "tick" of the simulation clock. Following the tick, the server divides processing into a sequence of "phases". Services that implement the TimeslotPhaseProcessor interface can be notified of these phases. In the original server, phase 1 was devoted to running the customer models, phase 2 was clearing the wholesale and balancing markets, and phase 3 was accounting and weather reports. Typically, the whole process takes 2-3 seconds, so there is some idle time in each timeslot.

Brokers can submit bids and asks to the market at any time. They are simply added to a "pending" list when they arrive. At the beginning of the clearing process, the pending list is copied into a submitted list, and the pending list cleared, within a synchronized method. The submitted list is then used to clear the market.

From the broker's standpoint, there is a significant problem here. The customer model runs before the market is cleared, but brokers don't get any feedback on the customer's production and consumption behavior until after the market has cleared. This means that brokers cannot use information from the current timeslot n to inform bidding for the following timeslot n+1; there is instead a delay of an extra timeslot imposed, and information from timeslot n can at best be used to inform bidding for timeslot n+2. In addition, there is a delay between the time bids/asks for timeslot n+1 are invalid (because the market clearing process has already started) and the time when the timeslot update is sent to indicate that timeslot n+1 is closed.

So it seems that the ideal situation would be to have the market for timeslots [n+1 ... n+23] clear at the very end of timeslot n. That way, information about customer behavior in timeslot n can affect broker decisions about timeslot n+1. It would also make sense to send out the TimeslotUpdate message before the market clears, rather than afterward. Since it's not feasible to run a process step at the end of a timeslot, perhaps running the market clearing as the first activity in the new timeslot would be very nearly equivalent. This scheme is shown in the figure below. Note that this requires four phases instead of three, since balancing must come after the customer model but before accounting.

width=700px

The final piece of this puzzle from the broker's standpoint is to know when it has received all the information needed to make bid/ask decisions for the next timeslot. Tariff transactions, including signups, withdrawals, and production and consumption data, are generated and sent out by the accounting service. The last message sent to each broker in a timeslot is the TimeslotComplete message.