/**
  * Выполняет запрос, со всей инфрастуктурой - логгированием и кэшированием
  * Этот метод получает управление, когда у вызывается несуществующий метод
  * @param string $method имя вызываемого метода
  * @param array  $args   массив аргументов
  * @return Response
  * @throws NotConfiguredException
  */
 public function __call($method, array $args = [])
 {
     /* @var AbstractService $serviceName */
     $serviceName = get_class($this);
     if (!$this->isConfigured()) {
         $errorMessage = sprintf('%s is not configured', $serviceName);
         $this->loggerError($errorMessage);
         throw new NotConfiguredException($serviceName);
     }
     /* @var Response $result */
     $result = null;
     $tag = AbstractLogger::generateTag();
     $key = $this->cacherGenerateKey($method, $args);
     $expires = $this->cacherGetExpires($method);
     $isExpired = $this->cacherIsExpired($key);
     $msg = sprintf('fetching result of "%1$s(%2$s)" from service %3$s::%1$s', $method, $this->varExport($args), $serviceName);
     $this->loggerNotice($msg, $tag);
     if (!$isExpired) {
         $this->loggerNotice('found in cache, retrieving', $tag);
         $result = $this->cacherGet($key);
     } else {
         $this->loggerNotice('not found in cache, fetching', $tag);
         $result = $this->implementationCall($method, $args);
         $this->loggerNotice(print_r($result->getContent(), true), $tag);
         if ($result->isOk()) {
             $this->loggerNotice('successfully fetched', $tag);
             $this->cacherSet($key, $result, $expires);
         } else {
             $this->loggerError($result->getError(), $tag);
         }
     }
     return $result;
 }