mirror of
https://github.com/Combodo/iTop.git
synced 2026-07-01 12:16:37 +02:00
N°9746 - handle timechange during synchro execution + cleanup m_bIsImportPhaseDateKnown
This commit is contained in:
@@ -3002,8 +3002,6 @@ class SynchroExecution
|
||||
* </ul>
|
||||
*/
|
||||
protected $m_oLastFullLoadStartDate = null;
|
||||
/** @var bool true if the caller script gave the datetime before import phase was launched */
|
||||
protected $m_bIsImportPhaseDateKnown;
|
||||
|
||||
/** @var \CMDBChange */
|
||||
protected $m_oChange = null;
|
||||
@@ -3028,10 +3026,7 @@ class SynchroExecution
|
||||
public function __construct($oDataSource, $oImportPhaseStartDate = null)
|
||||
{
|
||||
$this->m_oDataSource = $oDataSource;
|
||||
|
||||
$this->m_bIsImportPhaseDateKnown = ($oImportPhaseStartDate != null);
|
||||
$this->m_oImportPhaseStartDate = $oImportPhaseStartDate;
|
||||
|
||||
$this->m_oCtx = new ContextTag(ContextTag::TAG_SYNCHRO);
|
||||
$this->m_oCtx1 = new ContextTag('Synchro:'.$oDataSource->GetRawName()); // More precise context information
|
||||
}
|
||||
@@ -3108,7 +3103,7 @@ class SynchroExecution
|
||||
$this->m_oStatLog->Set('stats_nb_replica_total', $this->m_iCountAllReplicas);
|
||||
|
||||
$this->m_oStatLog->DBInsert();
|
||||
$sLastFullLoad = ($this->m_bIsImportPhaseDateKnown) ? $this->m_oImportPhaseStartDate->format('Y-m-d H:i:s') : 'not specified';
|
||||
$sLastFullLoad = (is_null($this->m_oImportPhaseStartDate)) ? 'not specified' : $this->m_oImportPhaseStartDate->format('Y-m-d H:i:s');
|
||||
$this->m_oStatLog->AddTrace("###### STARTING SYNCHRONIZATION ##### Total: {$this->m_iCountAllReplicas} replica(s). Last full load: '$sLastFullLoad' ");
|
||||
$sSql = 'SELECT NOW();';
|
||||
$sDBNow = CMDBSource::QueryToScalar($sSql);
|
||||
@@ -3212,20 +3207,18 @@ class SynchroExecution
|
||||
// Compute and keep track of the limit date taken into account for obsoleting replicas
|
||||
//
|
||||
$iFullLoadInterval = $this->m_oDataSource->Get('full_load_periodicity'); // Duration in seconds
|
||||
if ($this->m_bIsImportPhaseDateKnown) {
|
||||
$oLimitDate = clone $this->m_oImportPhaseStartDate;
|
||||
$sInterval = "-$iFullLoadInterval seconds";
|
||||
$oLimitDate->Modify($sInterval);
|
||||
} else {
|
||||
if (is_null($this->m_oImportPhaseStartDate)) {
|
||||
if ($iFullLoadInterval <= 0) {
|
||||
// we are doing exec phase alone, and the full load interval is set to 0 => we should not update/delete replicas !!
|
||||
// This will prevent actions in DoJob1() method
|
||||
$oLimitDate = new DateTime('1970-01-01');
|
||||
} else {
|
||||
$oLimitDate = self::GetDataBaseCurrentDateTime();
|
||||
$sInterval = "-$iFullLoadInterval seconds";
|
||||
$oLimitDate->Modify($sInterval);
|
||||
$this->ExactlySubtractSeconds($oLimitDate, $iFullLoadInterval);
|
||||
}
|
||||
} else {
|
||||
$oLimitDate = clone $this->m_oImportPhaseStartDate;
|
||||
$this->ExactlySubtractSeconds($oLimitDate, $iFullLoadInterval);
|
||||
}
|
||||
$this->m_oLastFullLoadStartDate = $oLimitDate;
|
||||
if ($bFirstPass) {
|
||||
@@ -3346,10 +3339,10 @@ class SynchroExecution
|
||||
$aArguments['log'] = $this->m_oStatLog->GetKey();
|
||||
$aArguments['change'] = $this->m_oChange->GetKey();
|
||||
$aArguments['chunk'] = $iMaxChunkSize;
|
||||
if ($this->m_bIsImportPhaseDateKnown) {
|
||||
$aArguments['last_full_load'] = $this->m_oImportPhaseStartDate->Format('Y-m-d H:i:s');
|
||||
} else {
|
||||
if (! is_null($this->m_oImportPhaseStartDate)) {
|
||||
$aArguments['last_full_load'] = '';
|
||||
} else {
|
||||
$aArguments['last_full_load'] = $this->m_oImportPhaseStartDate->Format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$this->m_oStatLog->DBUpdate();
|
||||
@@ -3701,13 +3694,11 @@ class SynchroExecution
|
||||
|
||||
// Get all the replicas that are to be deleted
|
||||
//
|
||||
$oDeletionDate = $this->m_oLastFullLoadStartDate;
|
||||
$oDeletionDate = clone $this->m_oLastFullLoadStartDate;
|
||||
$iDeleteRetention = $this->m_oDataSource->Get('delete_policy_retention'); // Duration in seconds
|
||||
if ($iDeleteRetention > 0) {
|
||||
$sInterval = "-$iDeleteRetention seconds";
|
||||
$oDeletionDate->Modify($sInterval);
|
||||
}
|
||||
$this->ExactlySubtractSeconds($oDeletionDate, $iDeleteRetention);
|
||||
$sDeletionDate = $oDeletionDate->Format('Y-m-d H:i:s');
|
||||
|
||||
if ($bFirstPass) {
|
||||
$this->m_oStatLog->AddTrace("Deletion date: $sDeletionDate");
|
||||
}
|
||||
@@ -3757,4 +3748,21 @@ class SynchroExecution
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Take into account timechange to apply date difference operation
|
||||
* @param \DateTime $oDate
|
||||
* @param $iDurationInSeconds
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function ExactlySubtractSeconds(DateTime $oDate, $iDurationInSeconds): void
|
||||
{
|
||||
if ($iDurationInSeconds > 0) {
|
||||
$oDate->setTimezone(new DateTimeZone('UTC'));
|
||||
$sInterval = "-$iDurationInSeconds seconds";
|
||||
$oDate->Modify($sInterval);
|
||||
$sTimezone = MetaModel::GetConfig()->Get('timezone');
|
||||
$oDate->setTimezone(new DateTimeZone($sTimezone));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,46 @@
|
||||
<?php
|
||||
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||
|
||||
class SynchroDataSourceTest extends ItopTestCase
|
||||
class SynchroExecutionTest extends ItopDataTestCase
|
||||
{
|
||||
public function () {
|
||||
private function InitAndGetTZ($sTZ = null): string
|
||||
{
|
||||
$sTZ = $sTZ ?? 'Europe/Paris';
|
||||
MetaModel::GetConfig()->Set('timezone', $sTZ);
|
||||
return $sTZ;
|
||||
}
|
||||
|
||||
public function testGetDateMinusRetentionWithTimeChange()
|
||||
{
|
||||
$sTZ = $this->InitAndGetTZ();
|
||||
$oObj = new SynchroExecution($this->createMock(SynchroDataSource::class));
|
||||
$oDate = DateTime::createFromFormat('Y-m-d H:i:s', "2026-03-29 03:30:01", new DateTimeZone($sTZ));
|
||||
|
||||
$oObj->ExactlySubtractSeconds($oDate, 3600);
|
||||
//03h30 minus 1hours => 03h minus 30mn => 03h
|
||||
// => 03h with timechange => 2h
|
||||
// => 02 minus 30mn => 01h30
|
||||
$this->assertEquals("2026-03-29 01:30:01", $oDate->Format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testGetDateMinusRetentionWithTimeChangeAndUTC()
|
||||
{
|
||||
$sTZ = $this->InitAndGetTZ('UTC');
|
||||
$oObj = new SynchroExecution($this->createMock(SynchroDataSource::class));
|
||||
$oDate = DateTime::createFromFormat('Y-m-d H:i:s', "2026-03-29 03:30:01", new DateTimeZone($sTZ));
|
||||
|
||||
$oObj->ExactlySubtractSeconds($oDate, 3600);
|
||||
$this->assertEquals("2026-03-29 02:30:01", $oDate->Format('Y-m-d H:i:s'));
|
||||
}
|
||||
|
||||
public function testGetDateMinusRetention()
|
||||
{
|
||||
$sTZ = $this->InitAndGetTZ();
|
||||
$oObj = new SynchroExecution($this->createMock(SynchroDataSource::class));
|
||||
$oDate = DateTime::createFromFormat('Y-m-d H:i:s', "2026-04-01 03:30:01", new DateTimeZone($sTZ));
|
||||
|
||||
$oObj->ExactlySubtractSeconds($oDate, 3600);
|
||||
$this->assertEquals("2026-04-01 02:30:01", $oDate->Format('Y-m-d H:i:s'));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user