The wind oracle

Exercise 4 of 6 in chapter 9 · 280 XP · 5 objectives checked by tests

Topics covered: Service decoration#[AsDecorator]#[AutowireDecorated]CacheCacheInterface

The aviary now shows today's winds toward three lands, read by the tower mage. His forecasts are accurate, but he takes his time reading the stars and he bills every consultation. Every visit to the aviary means three consultations. Open the preview and reload the page: watch the bill climb.

Yet the winds only change once a day. Pippin suggests writing the mage's answers down in a notebook. But nobody touches the mage, and we don't want to change every place that asks him either.

Decorating a service

The decorator slips in between those who ask for a service and the service itself. It has the same interface (Oracle): for the controller, nothing changes. Inside, it keeps the original service and decides when to call it. Symfony does the swap: wherever someone asked for Oracle, they get the decorator, which in turn gets the mage.

That's how Symfony adds the profiler, logging or caching around its own services, without changing them.

Your mission

Write OracleEnCache (the cached oracle), Pippin's notebook:

  1. it's what you get when you ask for an Oracle;
  2. it answers exactly what the mage would have said;
  3. it consults the mage only once per land and per day, even from one request to the next (ventsDuJour() means “today's winds”, $contree is the land);
  4. the next day, the winds change: it consults him again.

Once the notebook is in place, reload the aviary: the mage's bill must stop at 3.