mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
Cache improved
This commit is contained in:
@@ -806,14 +806,19 @@ $config['max_login_attempts'] = 3;
|
||||
| Controls file-based caching for DXCluster features. Two independent settings:
|
||||
|
|
||||
| 1. enable_dxcluster_file_cache_band
|
||||
| - Caches spot lists (per band/mode/continent) from DXCache API
|
||||
| - Caches processed spot lists (WITHOUT worked status) from DXCache API
|
||||
| - Cache is INSTANCE-WIDE (shared by all users)
|
||||
| - Cache duration: 59 seconds
|
||||
| - Cache key includes: band, max age, continent, mode, user_id, logbook_id
|
||||
| - Cache key format: dxcluster_raw_{maxage}_{continent}_{mode}_{band}
|
||||
| - Example: dxcluster_raw_60_Any_All_20m
|
||||
| - Contains: callsign, frequency, DXCC, mode, age, metadata
|
||||
| - Does NOT contain: worked/confirmed status (always false in cache)
|
||||
| - Set to TRUE to reduce API calls and speed up spot list loading
|
||||
| - Set to FALSE to always fetch fresh data from API
|
||||
|
|
||||
| 2. enable_dxcluster_file_cache_worked
|
||||
| - Caches worked/confirmed status lookups from database
|
||||
| - Cache is USER-SPECIFIC (separate for each user/logbook)
|
||||
| - Cache duration: 15 minutes (900 seconds)
|
||||
| - Cache includes: All bands/modes combinations per callsign/DXCC/continent
|
||||
| - Set to TRUE to significantly reduce database load
|
||||
@@ -821,8 +826,10 @@ $config['max_login_attempts'] = 3;
|
||||
|
|
||||
| Default: false (both caching disabled)
|
||||
|
|
||||
| Recommendation: Enable both on high-traffic installations for best performance.
|
||||
| Warning: May cause high disk usage on large multi-user installations.
|
||||
| Recommendation:
|
||||
| - Enable BAND cache on all installations to reduce API load (instance-wide)
|
||||
| - Enable WORKED cache on high-traffic multi-user installations to reduce DB queries
|
||||
| Warning: WORKED cache may cause high disk usage on large multi-user installations.
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -48,23 +48,14 @@ class Dxcluster_model extends CI_Model {
|
||||
$this->load->helper(array('psr4_autoloader'));
|
||||
|
||||
// Check if file caching is enabled in config
|
||||
$cache_enabled = $this->config->item('enable_dxcluster_file_cache_band') === true;
|
||||
$cache_band_enabled = $this->config->item('enable_dxcluster_file_cache_band') === true;
|
||||
$cache_worked_enabled = $this->config->item('enable_dxcluster_file_cache_worked') === true;
|
||||
|
||||
// Only load cache driver if caching is enabled
|
||||
if ($cache_enabled) {
|
||||
if ($cache_band_enabled || $cache_worked_enabled) {
|
||||
$this->load->driver('cache', array('adapter' => 'file', 'backup' => 'file'));
|
||||
}
|
||||
|
||||
// Check cache first for processed spot list (only if caching is enabled)
|
||||
$user_id = $this->session->userdata('user_id');
|
||||
$logbook_id = $this->session->userdata('active_station_logbook');
|
||||
$cache_key = "spotlist_{$band}_{$maxage}_{$de}_{$mode}_{$user_id}_{$logbook_id}";
|
||||
|
||||
// Try to get cached processed results (59 second cache) only if caching is enabled
|
||||
if ($cache_enabled && ($cached_spots = $this->cache->get($cache_key))) {
|
||||
return $cached_spots;
|
||||
}
|
||||
|
||||
if($this->session->userdata('user_date_format')) {
|
||||
$custom_date_format = $this->session->userdata('user_date_format');
|
||||
} else {
|
||||
@@ -82,14 +73,17 @@ class Dxcluster_model extends CI_Model {
|
||||
$this->load->model('logbook_model');
|
||||
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
|
||||
|
||||
// Check cache for raw DX cluster data (only if caching is enabled)
|
||||
$jsonraw = null;
|
||||
if ($cache_enabled) {
|
||||
$jsonraw = $this->cache->get('dxcache'.$band);
|
||||
// Cache key for RAW cluster response (instance-wide, no worked status)
|
||||
$raw_cache_key = "dxcluster_raw_{$maxage}_{$de}_{$mode}_{$band}";
|
||||
|
||||
// Check cache for raw processed spots (without worked status)
|
||||
$spotsout = null;
|
||||
if ($cache_band_enabled) {
|
||||
$spotsout = $this->cache->get($raw_cache_key);
|
||||
}
|
||||
|
||||
if (!$jsonraw) {
|
||||
// CURL Functions
|
||||
if (!$spotsout) {
|
||||
// Fetch raw DX cluster data from API
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $dxcache_url);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Wavelog '.$this->optionslib->get_option('version').' DXLookup');
|
||||
@@ -106,50 +100,44 @@ class Dxcluster_model extends CI_Model {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Save to cache only if caching is enabled
|
||||
if ($cache_enabled) {
|
||||
$this->cache->save('dxcache'.$band, $jsonraw, 59); // Cache DXClusterCache Instancewide for 59seconds
|
||||
}
|
||||
}
|
||||
|
||||
// Validate JSON before decoding
|
||||
if (empty($jsonraw) || strlen($jsonraw) <= 20) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$json = json_decode($jsonraw);
|
||||
|
||||
// Check for JSON decode errors
|
||||
if (json_last_error() !== JSON_ERROR_NONE || !is_array($json)) {
|
||||
log_message('error', 'DXCluster: Invalid JSON received: ' . json_last_error_msg());
|
||||
return [];
|
||||
}
|
||||
$date = date('Ymd', time());
|
||||
|
||||
$dxccObj = new DXCC($date);
|
||||
|
||||
// DXCC lookup cache to avoid duplicate lookups
|
||||
$dxcc_cache = [];
|
||||
|
||||
$spotsout=[];
|
||||
|
||||
// Cache current time outside loop (avoid creating DateTime on every iteration)
|
||||
$currentTimestamp = time();
|
||||
|
||||
// Normalize continent filter once
|
||||
$de_lower = strtolower($de);
|
||||
$filter_continent = ($de != '' && $de != 'Any');
|
||||
|
||||
foreach($json as $singlespot){
|
||||
// Early filtering - skip invalid spots immediately
|
||||
if (!is_object($singlespot) || !isset($singlespot->frequency) || !is_numeric($singlespot->frequency)) {
|
||||
continue;
|
||||
// Validate JSON before decoding
|
||||
if (empty($jsonraw) || strlen($jsonraw) <= 20) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Ensure frequency is always a number (not a string)
|
||||
$singlespot->frequency = floatval($singlespot->frequency);
|
||||
$json = json_decode($jsonraw);
|
||||
|
||||
$spotband = $this->frequency->GetBand($singlespot->frequency*1000); // Apply band filter early (before expensive operations)
|
||||
// Check for JSON decode errors
|
||||
if (json_last_error() !== JSON_ERROR_NONE || !is_array($json)) {
|
||||
log_message('error', 'DXCluster: Invalid JSON received: ' . json_last_error_msg());
|
||||
return [];
|
||||
}
|
||||
$date = date('Ymd', time());
|
||||
|
||||
$dxccObj = new DXCC($date);
|
||||
|
||||
// DXCC lookup cache to avoid duplicate lookups
|
||||
$dxcc_cache = [];
|
||||
|
||||
$spotsout=[];
|
||||
|
||||
// Cache current time outside loop (avoid creating DateTime on every iteration)
|
||||
$currentTimestamp = time();
|
||||
|
||||
// Normalize continent filter once
|
||||
$de_lower = strtolower($de);
|
||||
$filter_continent = ($de != '' && $de != 'Any');
|
||||
|
||||
foreach($json as $singlespot){
|
||||
// Early filtering - skip invalid spots immediately
|
||||
if (!is_object($singlespot) || !isset($singlespot->frequency) || !is_numeric($singlespot->frequency)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure frequency is always a number (not a string)
|
||||
$singlespot->frequency = floatval($singlespot->frequency);
|
||||
|
||||
$spotband = $this->frequency->GetBand($singlespot->frequency*1000); // Apply band filter early (before expensive operations)
|
||||
if (($band != 'All') && ($band != $spotband)) {
|
||||
continue;
|
||||
}
|
||||
@@ -233,12 +221,17 @@ class Dxcluster_model extends CI_Model {
|
||||
// Extract park references from message
|
||||
$singlespot = $this->enrich_spot_metadata($singlespot);
|
||||
|
||||
// Collect spots for batch processing
|
||||
$spotsout[] = $singlespot;
|
||||
// Collect spots for batch processing
|
||||
$spotsout[] = $singlespot;
|
||||
}
|
||||
|
||||
// Cache the RAW processed spots (WITHOUT worked status) - instance-wide
|
||||
if ($cache_band_enabled && !empty($spotsout)) {
|
||||
$this->cache->save($raw_cache_key, $spotsout, 59);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Batch process all spot statuses in a single optimized database query
|
||||
// NOW add worked status if enabled (user-specific)
|
||||
if (!empty($spotsout)) {
|
||||
$batch_statuses = $this->logbook_model->get_batch_spot_statuses(
|
||||
$spotsout,
|
||||
@@ -308,17 +301,21 @@ class Dxcluster_model extends CI_Model {
|
||||
|
||||
$spotsout[$index] = $spot;
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the processed results for 59 seconds (matches DXCache server TTL) only if caching is enabled
|
||||
if ($cache_enabled && !empty($spotsout)) {
|
||||
$this->cache->save($cache_key, $spotsout, 59);
|
||||
} else {
|
||||
// No worked status check - set all to false
|
||||
foreach ($spotsout as $index => $spot) {
|
||||
$spot->worked_dxcc = false;
|
||||
$spot->worked_call = false;
|
||||
$spot->cnfmd_dxcc = false;
|
||||
$spot->cnfmd_call = false;
|
||||
$spot->cnfmd_continent = false;
|
||||
$spot->worked_continent = false;
|
||||
$spotsout[$index] = $spot;
|
||||
}
|
||||
}
|
||||
|
||||
return $spotsout;
|
||||
}
|
||||
|
||||
// Determine mode with priority: POTA/SOTA mode > message keywords > frequency-based
|
||||
} // Determine mode with priority: POTA/SOTA mode > message keywords > frequency-based
|
||||
function get_mode($spot) {
|
||||
// Priority 0: If spot already has a valid mode from cluster, use it
|
||||
if (isset($spot->mode) && !empty($spot->mode)) {
|
||||
|
||||
@@ -2775,7 +2775,7 @@ class Logbook_model extends CI_Model {
|
||||
if (!isset($this->spot_status_cache[$cache_key])) {
|
||||
// Check file cache
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_call_{$logbook_ids_key}_{$callsign}";
|
||||
$file_cache_key = "dxcluster_worked_call_{$logbook_ids_key}_{$callsign}";
|
||||
$cached_data = $this->cache->get($file_cache_key);
|
||||
if ($cached_data !== false) {
|
||||
// Load from file cache into in-memory cache
|
||||
@@ -2793,7 +2793,7 @@ class Logbook_model extends CI_Model {
|
||||
|
||||
if (!isset($this->spot_status_cache[$cache_key])) {
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_dxcc_{$logbook_ids_key}_{$dxcc}";
|
||||
$file_cache_key = "dxcluster_worked_dxcc_{$logbook_ids_key}_{$dxcc}";
|
||||
$cached_data = $this->cache->get($file_cache_key);
|
||||
if ($cached_data !== false) {
|
||||
$this->spot_status_cache[$cache_key] = $cached_data;
|
||||
@@ -2809,7 +2809,7 @@ class Logbook_model extends CI_Model {
|
||||
|
||||
if (!isset($this->spot_status_cache[$cache_key])) {
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_cont_{$logbook_ids_key}_{$cont}";
|
||||
$file_cache_key = "dxcluster_worked_cont_{$logbook_ids_key}_{$cont}";
|
||||
$cached_data = $this->cache->get($file_cache_key);
|
||||
if ($cached_data !== false) {
|
||||
$this->spot_status_cache[$cache_key] = $cached_data;
|
||||
@@ -3052,7 +3052,7 @@ class Logbook_model extends CI_Model {
|
||||
|
||||
// Save to file cache for 15 minutes
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_call_{$logbook_ids_key}_{$callsign}";
|
||||
$file_cache_key = "dxcluster_worked_call_{$logbook_ids_key}_{$callsign}";
|
||||
$this->cache->save($file_cache_key, $data, $cache_ttl);
|
||||
}
|
||||
}
|
||||
@@ -3070,12 +3070,10 @@ class Logbook_model extends CI_Model {
|
||||
$this->spot_status_cache[$cache_key] = $data;
|
||||
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_cont_{$logbook_ids_key}_{$cont}";
|
||||
$file_cache_key = "dxcluster_worked_cont_{$logbook_ids_key}_{$cont}";
|
||||
$this->cache->save($file_cache_key, $data, $cache_ttl);
|
||||
}
|
||||
}
|
||||
|
||||
// Cache NOT WORKED items (negative results) - store empty arrays
|
||||
} // Cache NOT WORKED items (negative results) - store empty arrays
|
||||
// This prevents redundant database queries for callsigns/dxccs/continents not in logbook
|
||||
foreach ($callsigns_array as $callsign) {
|
||||
if (!isset($call_data[$callsign])) {
|
||||
@@ -3105,13 +3103,11 @@ class Logbook_model extends CI_Model {
|
||||
$this->spot_status_cache[$cache_key] = [];
|
||||
|
||||
if ($cache_enabled) {
|
||||
$file_cache_key = "spot_status_cont_{$logbook_ids_key}_{$cont}";
|
||||
$file_cache_key = "dxcluster_worked_cont_{$logbook_ids_key}_{$cont}";
|
||||
$this->cache->save($file_cache_key, [], $cache_ttl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now map all spots to their status using cached data (query results + previously cached)
|
||||
} // Now map all spots to their status using cached data (query results + previously cached)
|
||||
foreach ($spots_by_callsign as $callsign => $callsign_spots) {
|
||||
foreach ($callsign_spots as $spot) {
|
||||
$statuses[$callsign] = $this->map_spot_status_from_cache($spot, $logbook_ids_key);
|
||||
|
||||
Reference in New Issue
Block a user