MSIN-4328 — Increase AJAX timeout for preview synchronization in the ChronoTrack admin interface to improve user experience during long operations. Enhance error messaging for better clarity on network issues and session handling. Update participant classification function to allow optional payload building. Increment version code.
This commit is contained in:
@ -1453,7 +1453,7 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
url: strAjaxUrl,
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
timeout: 60000,
|
||||
timeout: 120000,
|
||||
data: { a: 'sync_preview', eve_id: intEveId }
|
||||
}).done(function (res) {
|
||||
if (rejectIfSessionLost(res)) {
|
||||
@ -1465,14 +1465,21 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
if (strStatus === 'abort') {
|
||||
return;
|
||||
}
|
||||
var strMsg = (strStatus === 'timeout')
|
||||
? 'Délai dépassé — réessayez Actualiser.'
|
||||
: 'Erreur réseau (preview).';
|
||||
var strMsg;
|
||||
if (strStatus === 'timeout') {
|
||||
strMsg = 'Délai dépassé (preview) — réessayez Actualiser.';
|
||||
} else if (strStatus === 'parsererror') {
|
||||
strMsg = 'Réponse invalide (preview) — souvent un envoi encore en cours ou erreur PHP.';
|
||||
} else if (jqXHR && jqXHR.status) {
|
||||
strMsg = 'Erreur preview HTTP ' + jqXHR.status + ' — réessayez Actualiser.';
|
||||
} else {
|
||||
strMsg = 'Erreur réseau (preview). Si un envoi tourne, attendez la fin puis Actualiser.';
|
||||
}
|
||||
if ($status.length) {
|
||||
$status.removeClass('ct-api-push-status--ok ct-api-push-status--todo ct-api-push-status--loading')
|
||||
.html(
|
||||
'<p class="ct-api-push-status__title text-danger mb-1">' + escHtml(strMsg) + '</p>'
|
||||
+ '<p class="ct-api-push-status__hint mb-0 text-muted">Réessayez Actualiser.</p>'
|
||||
+ '<p class="ct-api-push-status__hint mb-0 text-muted">Les derniers compteurs affichés sont conservés.</p>'
|
||||
+ '<p id="ct_api_status_refresh_cd" class="small text-muted mb-0 mt-1"></p>'
|
||||
);
|
||||
}
|
||||
@ -1836,6 +1843,9 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
var blnFatal = false;
|
||||
|
||||
blnPushRunning = true;
|
||||
if (xhrPushPreview && xhrPushPreview.readyState !== 4) {
|
||||
xhrPushPreview.abort();
|
||||
}
|
||||
$('#ct_api_btn_push, #ct_api_btn_push_full, #ct_api_btn_push_refresh, #ct_api_btn_ct_count, #ct_api_btn_logs').prop('disabled', true);
|
||||
|
||||
function renderProgress(intDone, intTot, strExtra) {
|
||||
@ -1879,7 +1889,13 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
}
|
||||
|
||||
function pushChunk() {
|
||||
renderProgress(intOffset, intTotal, 'lot en cours…');
|
||||
var intLot = Math.floor(intOffset / Math.max(1, intChunk)) + 1;
|
||||
var intLots = Math.max(1, Math.ceil(intTotal / Math.max(1, intChunk)));
|
||||
renderProgress(
|
||||
intOffset,
|
||||
intTotal,
|
||||
'lot ' + intLot + '/' + intLots + ' (POST ' + Math.min(intChunk, intTotal - intOffset) + ')…'
|
||||
);
|
||||
$.ajax({
|
||||
url: strAjaxUrl,
|
||||
type: 'POST',
|
||||
@ -1967,7 +1983,7 @@ function fxChronotrackApiAdminRenderPageScript($intEveId, $arrConfig, $blnClosed
|
||||
});
|
||||
}
|
||||
|
||||
renderProgress(0, intTotal, 'préparation…');
|
||||
renderProgress(0, intTotal > 0 ? intTotal : 1, 'préparation MS1 (liste + job)…');
|
||||
$.ajax({
|
||||
url: strAjaxUrl,
|
||||
type: 'POST',
|
||||
|
||||
@ -403,7 +403,7 @@ function fxChronotrackApiSyncGroupBlockedByType(array $tabBlocked) {
|
||||
/**
|
||||
* Classe les participants MS1 : transférables vs exclus (dossard, sexe, doublons MS1, mapping).
|
||||
*/
|
||||
function fxChronotrackApiSyncClassifyParticipants(array $tabParticipants, array $arrRaceMap, $intCtEventId = 0) {
|
||||
function fxChronotrackApiSyncClassifyParticipants(array $tabParticipants, array $arrRaceMap, $intCtEventId = 0, $blnBuildPayloads = true) {
|
||||
$tabCandidates = array();
|
||||
$tabBlocked = array();
|
||||
$tabBibCounts = array();
|
||||
@ -560,9 +560,12 @@ function fxChronotrackApiSyncClassifyParticipants(array $tabParticipants, array
|
||||
continue;
|
||||
}
|
||||
|
||||
$arrPayload = fxChronotrackApiSyncBuildEntryPayload($arrRow, $arrRaceMap, $intCtEventId);
|
||||
if ($arrPayload === null) {
|
||||
continue;
|
||||
$arrPayload = null;
|
||||
if ($blnBuildPayloads) {
|
||||
$arrPayload = fxChronotrackApiSyncBuildEntryPayload($arrRow, $arrRaceMap, $intCtEventId);
|
||||
if ($arrPayload === null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$tabTransferable[] = array(
|
||||
@ -630,9 +633,12 @@ function fxChronotrackApiSyncClassifyParticipants(array $tabParticipants, array
|
||||
continue;
|
||||
}
|
||||
|
||||
$arrPayload = fxChronotrackApiSyncBuildEntryPayload($arrRep, $arrRaceMap, $intCtEventId);
|
||||
if ($arrPayload === null) {
|
||||
continue;
|
||||
$arrPayload = null;
|
||||
if ($blnBuildPayloads) {
|
||||
$arrPayload = fxChronotrackApiSyncBuildEntryPayload($arrRep, $arrRaceMap, $intCtEventId);
|
||||
if ($arrPayload === null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$tabTransferable[] = array(
|
||||
@ -2018,7 +2024,8 @@ function fxChronotrackApiSyncBuildPreview($intEveId) {
|
||||
$intCtEventId = intval($arrConfig['ct_event_id']);
|
||||
$arrRaceMap = fxChronotrackApiRaceMapGetForEvent($intEveId);
|
||||
$tabParticipants = fxChronotrackApiSyncLoadMs1Participants($intEveId);
|
||||
$arrClass = fxChronotrackApiSyncClassifyParticipants($tabParticipants, $arrRaceMap, $intCtEventId);
|
||||
// MSIN-4328 — preview rapide : pas de build payloads / entry_notes (seulement compteurs + exclus)
|
||||
$arrClass = fxChronotrackApiSyncClassifyParticipants($tabParticipants, $arrRaceMap, $intCtEventId, false);
|
||||
|
||||
$intMs1Total = count($tabParticipants);
|
||||
$intTransferable = count($arrClass['transferable']);
|
||||
@ -2036,7 +2043,7 @@ function fxChronotrackApiSyncBuildPreview($intEveId) {
|
||||
'transferable' => $intTransferable,
|
||||
'blocked_count' => $arrClass['blocked_count'],
|
||||
'blocked_by_type' => $arrClass['blocked_by_type'],
|
||||
'blocked' => $arrClass['blocked'],
|
||||
// Pas de liste plate « blocked » (doublon lourd) — l’UI utilise blocked_by_type
|
||||
'eligible' => $intTransferable,
|
||||
'skipped_no_race' => $arrClass['skipped_no_race'],
|
||||
'skipped_no_external' => $arrClass['skipped_no_external'],
|
||||
@ -2048,7 +2055,6 @@ function fxChronotrackApiSyncBuildPreview($intEveId) {
|
||||
'anomaly_no_sex' => $arrClass['blocked_no_sex'],
|
||||
'anomaly_duplicate_bib' => $arrClass['blocked_duplicate_bib'],
|
||||
'duplicate_bib_numbers' => $arrClass['duplicate_bib_numbers'],
|
||||
'anomalies' => $arrClass['blocked'],
|
||||
'ct_total' => null,
|
||||
'ct_total_loaded' => false,
|
||||
'already_in_ct' => null,
|
||||
@ -2290,11 +2296,10 @@ function fxChronotrackApiSyncPushPrepare($intEveId, $arrOptions = array()) {
|
||||
$tabPending = fxChronotrackApiSyncFilterChangedSincePush($arrClass['transferable'], $strLastPushAt);
|
||||
}
|
||||
|
||||
// Plus de scan CT à la préparation : POST upsert (crée ou maj) sans entry_id.
|
||||
// Garder entry_id en meta/job pour retry dossard ; l’envoi lot utilise POST upsert (pas PUT unitaire).
|
||||
$tabBatch = array();
|
||||
$tabMeta = array();
|
||||
foreach ($tabPending as $arrItem) {
|
||||
// Garder entry_id si déjà lié CT → push chunk fera PUT (maj dossard fiable).
|
||||
$arrPayload = $arrItem['payload'];
|
||||
$strCtEntryId = preg_replace('/[^0-9]/', '', (string)($arrItem['row']['ct_entry_id'] ?? ''));
|
||||
if ($strCtEntryId !== '') {
|
||||
@ -2443,34 +2448,17 @@ function fxChronotrackApiSyncPushEvent($intEveId, $arrOptions = array()) {
|
||||
$tabErrors = array();
|
||||
$tabBibRetryChunk = array();
|
||||
|
||||
// MSIN-4328 — entries liées (ct_entry_id) : PUT unitaire (+ clear bib si swap).
|
||||
// Sans entry_id : POST lot (upsert). Ne plus stripper entry_id avant adaptive.
|
||||
// MSIN-4328 — toujours POST en lot (upsert par external_id).
|
||||
// Avant : PUT unitaire si ct_entry_id → ~100 appels/lot = 1–2 min figé à 0/N.
|
||||
// entry_id reste sur le payload pour la 2e passe dossard ; retiré seulement à l’appel POST.
|
||||
$tabPostEntries = array();
|
||||
$tabPostMeta = array();
|
||||
foreach ($tabBatch as $intI => $arrPayload) {
|
||||
if (!is_array($arrPayload)) {
|
||||
continue;
|
||||
}
|
||||
$strEntryId = trim((string)($arrPayload['entry_id'] ?? ''));
|
||||
if ($strEntryId !== '') {
|
||||
$arrOne = fxChronotrackApiSyncPushOneEntryWithBibConflictHandling(
|
||||
$intCtEventId,
|
||||
$arrPayload,
|
||||
$tabMeta[$intI] ?? array('par_id' => 0, 'external_id' => ''),
|
||||
$intEveId
|
||||
);
|
||||
$intOk += intval($arrOne['ok'] ?? 0);
|
||||
$intErr += intval($arrOne['err'] ?? 0);
|
||||
$intPutOk += intval($arrOne['ok'] ?? 0);
|
||||
if (!empty($arrOne['bib_retry']) && is_array($arrOne['bib_retry'])) {
|
||||
foreach ($arrOne['bib_retry'] as $arrR) {
|
||||
$tabBibRetryChunk[] = $arrR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$tabPostEntries[] = $arrPayload;
|
||||
$tabPostMeta[] = $tabMeta[$intI] ?? array('par_id' => 0, 'external_id' => '');
|
||||
}
|
||||
$tabPostEntries[] = $arrPayload;
|
||||
$tabPostMeta[] = $tabMeta[$intI] ?? array('par_id' => 0, 'external_id' => '');
|
||||
}
|
||||
|
||||
if (count($tabPostEntries) > 0) {
|
||||
|
||||
@ -6,6 +6,10 @@ require_once dirname(__FILE__) . '/php/inc_functions.php';
|
||||
require_once dirname(__FILE__) . '/../php/chronotrack_api/inc_bootstrap.php';
|
||||
|
||||
$intUsaId = fxSuperadmAjaxAuthOrJsonExit();
|
||||
// MSIN-4328 — libérer le verrou session : sinon un push long bloque Actualiser / preview (Erreur réseau).
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
$strAction = trim((string)($_REQUEST['a'] ?? ''));
|
||||
$intEveId = intval($_REQUEST['eve_id'] ?? 0);
|
||||
@ -91,7 +95,7 @@ switch ($strAction) {
|
||||
$tabRetour = array('state' => 'error', 'message' => 'eve_id manquant');
|
||||
break;
|
||||
}
|
||||
set_time_limit(60);
|
||||
set_time_limit(120);
|
||||
$tabRetour = fxChronotrackApiSyncBuildPreview($intEveId);
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user