Сделал модуль который отображает погоду в конкретном городе.
Но получил такие замечения по коду:
1. Интересный вопрос, а что происходит с данными вашего кеша, если на сайт сначала заходит человек из города Madrid, а потом Dublin?
Я так понимаю имеется в виду что человек из Дублина когда зайдет на сайт будет видеть погоду Мадрида, потому что она возьмется из кэша. Но я ведь кладу данные в кэш чтобы не было слишком много запросов, сделал один раз запрос, положил данные в кэш и следующие разы уже брал данные из кэша.
2. В небольшой функции вы дважды вызываете конечную точку http://ip-api.com/json/. Что происходит, когда сайт посещает тысяча человек в минуту?
Тут, я вообще не понимаю в чем проблема. Если имелось ввиду что будет исчерпан лимит подключения к ресурсу, то как решить эту проблему? В функции getCity() данные класть в кэш также как я делаю в функции build()? Но тогда вылезает та же проблема, что и в первом замечании, если на сайт зайдет человек из другого города, то возьмутся данные из кэша (название города Мадрид) а не название его настоящего города. Как тогда быть?
_________________________________________________________________________________
Подскажите пожалуйста что нужно исправить в моем коде?
Ниже напишу немного сокращенный код моего рhp файла. Полный вариант здесь: https://phpsandbox.io/n/sweet-forest-1lew-1wmof
<?php
// ....
use Drupal\Core\Cache\CacheBackendInterface;
use GuzzleHttp\Client;
//....
public function getCity() {
$ip = '193.62.157.66'; // статический чисто для теста
try {
$response_ip = $this->httpClient->get('http://ip-api.com/json/' . $ip);
$response_data_ip = $response_ip->getBody();
$data_ip = json_decode($response_data_ip);
if (
$data_ip->status == 'success') {
return $data_ip->city;
}
else {
return $this->configFactory->get('sydneypro_weather.settings')->get('weather_city');
}
}
catch (
RequestException $e) {
return FALSE;
}
}
public function
build() {
$client = $this->httpClient;
$api_key = $this->configFactory->get('sydneypro_weather.settings')->get('weather_api_key');
$cid = 'sydneypro_weather';
$weather_config = $this->configFactory->get('sydneypro_weather.settings');
if (!
$weather_config) {
$this->logger->get('sydneypro_weather')->error('Config "sydneypro_weather.settings" is missing4');
return [];
}
if (empty(
$api_key) || empty($this->getCity())) {
return [
'#type' => 'markup',
'#markup' => $this->t('Please enter your API key and City in the Admin panel to see the weather'),
];
}
try {
if (
$cache = $this->cacheBackend->get($cid)) {
$data = $cache->data;
}
else {
$response = $client->get('http://api.openweathermap.org/data/2.5/weather?q=' . $this->getCity() . ',&appid=' . $api_key . '&units=metric');
$response_data = $response->getBody();
$data = json_decode($response_data);
$this->cacheBackend->set($cid, $data, $this->time->getRequestTime() + 21600);
}
$build = [
'#theme' => 'weather_block',
'#data' => $data,
'#attached' => [
'library' => [
'sydneypro_weather/sydneypro_weather',
],
],
];
return
$build;
}
// ....
?>
Комментарии
Да
Проблем с эти может быть несколько. Во-первых вы можете исчерпать лимит подключений к ресурсу (если лимиты есть). Во-вторых при обращении к этому ресурсу, если соединение подвиснет, то и загрузка вашего сайта подвиснет.
Но я ведь кладу данные в кэш чтобы не было слишком много запросов, сделал один раз запрос, положил данные в кэш и следующие разы уже брал данные из кэша.
Если имелось ввиду что будет исчерпан лимит подключения к ресурсу, то как решить эту проблему? В функции getCity() данные класть в кэш также как я делаю в функции build()? Но тогда вылезает та же проблема, что и в первом замечании, если на сайт зайдет человек из другого города, то возьмутся данные из кэша (название города Мадрид) а не название его настоящего города. Как тогда быть?
Навскидку. Как минимум нужен уникальный
$cid
для кеширования каждого результата запросаgetCity()
по отдельному городу. Иначе "не взлетит". У вас общий$cid
для всех запросов, что сводит кеширование результатов только к последнему полученному.