Index: branches/5.2.x/core/install/install_data.sql
===================================================================
diff -u -r16754 -r16770
--- branches/5.2.x/core/install/install_data.sql (.../install_data.sql) (revision 16754)
+++ branches/5.2.x/core/install/install_data.sql (.../install_data.sql) (revision 16770)
@@ -100,6 +100,7 @@
INSERT INTO SystemSettings VALUES(DEFAULT, 'Backup_Path', '/home/alex/web/in-portal.rc/system/backupdata', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_backup_path', 'text', '', '', 60.07, 0, 1, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemTagCache', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_prompt_syscache_enable', 'checkbox', NULL, NULL, 60.08, 0, 0, NULL);
INSERT INTO SystemSettings VALUES(DEFAULT, 'SocketBlockingMode', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_prompt_socket_blocking_mode', 'checkbox', NULL, NULL, 60.09, 0, 0, NULL);
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SemaphoreLifetimeInSeconds', '300', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_SemaphoreLifetimeInSeconds', 'text', '', 'style=\"width: 50px;\"', 60.1, 0, 1, 'hint:la_config_SemaphoreLifetimeInSeconds');
INSERT INTO SystemSettings VALUES(DEFAULT, 'EnableEmailLog', '1', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EnableEmailLog', 'radio', NULL, '1=la_Yes||0=la_No', 65.01, 0, 1, 'hint:la_config_EnableEmailLog');
INSERT INTO SystemSettings VALUES(DEFAULT, 'EmailLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_EmailLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_EmailLogKeepForever', 65.02, 0, 0, 'hint:la_config_EmailLogRotationInterval');
INSERT INTO SystemSettings VALUES(DEFAULT, 'SystemLogRotationInterval', '2419200', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsLogs', 'la_config_SystemLogRotationInterval', 'select', NULL, '86400=la_opt_OneDay||604800=la_opt_OneWeek||1209600=la_opt_TwoWeeks||2419200=la_opt_OneMonth||7257600=la_opt_ThreeMonths||29030400=la_opt_OneYear||-1=la_opt_SystemLogKeepForever', 65.03, 0, 1, 'hint:la_config_SystemLogRotationInterval');
Index: branches/5.2.x/core/install/install_schema.sql
===================================================================
diff -u -r16754 -r16770
--- branches/5.2.x/core/install/install_schema.sql (.../install_schema.sql) (revision 16754)
+++ branches/5.2.x/core/install/install_schema.sql (.../install_schema.sql) (revision 16770)
@@ -1282,15 +1282,20 @@
);
CREATE TABLE Semaphores (
- SemaphoreId int(11) NOT NULL AUTO_INCREMENT,
- SessionKey int(10) unsigned NOT NULL DEFAULT '0',
+ `SemaphoreId` int(11) NOT NULL AUTO_INCREMENT,
+ `SessionKey` int(10) unsigned NOT NULL DEFAULT '0',
`Timestamp` int(10) unsigned NOT NULL DEFAULT '0',
- MainPrefix varchar(255) NOT NULL DEFAULT '',
- MainIDs text,
- PRIMARY KEY (SemaphoreId),
- KEY SessionKey (SessionKey),
+ `MainPrefix` varchar(255) NOT NULL DEFAULT '',
+ `MainIDs` text,
+ `UserId` int(11) DEFAULT NULL,
+ `IpAddress` varchar(15) NOT NULL DEFAULT '',
+ `Hostname` varchar(255) NOT NULL DEFAULT '',
+ `RequestURI` varchar(255) NOT NULL DEFAULT '',
+ `Backtrace` longtext,
+ PRIMARY KEY (`SemaphoreId`),
+ KEY `SessionKey` (`SessionKey`),
KEY `Timestamp` (`Timestamp`),
- KEY MainPrefix (MainPrefix)
+ KEY `MainPrefix` (`MainPrefix`)
);
CREATE TABLE CachedUrls (
Index: branches/5.2.x/core/kernel/utility/temp_handler.php
===================================================================
diff -u -r16733 -r16770
--- branches/5.2.x/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 16733)
+++ branches/5.2.x/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 16770)
@@ -1,6 +1,6 @@
30) {
- // another coping process failed to finished in 30 seconds
+ // Another coping process failed to finished in 30 seconds.
$error_message = $this->Application->Phrase('la_error_TemporaryTableCopyingFailed');
$this->Application->SetVar('_temp_table_message', $error_message);
+ $log = $this->Application->log('Parallel item saving attempt detected');
+ $log->addTrace();
+ $log->setLogLevel(kLogger::LL_ERROR);
+ $log->write();
+
return false;
}
- // mark, that we are coping from temp to live right now, so other similar attempt (from another script) will fail
- $fields_hash = Array (
- 'SessionKey' => $this->Application->GetSID(),
- 'Timestamp' => adodb_mktime(),
- 'MainPrefix' => $this->Tables['Prefix'],
- 'MainIDs' => implode(',', $master_ids),
- );
+ /*
+ * Mark, that we are coping from temp to live right now,
+ * so other similar attempt (from another script) will fail.
+ */
+ $semaphore_id = $this->createSemaphore($conn, $master_ids);
- $conn->doInsert($fields_hash, TABLE_PREFIX.'Semaphores');
- $semaphore_id = $conn->getInsertID();
-
// unlock table now to prevent permanent lock in case, when coping will end with SQL error in the middle
$conn->ChangeQuery('UNLOCK TABLES');
@@ -1023,6 +1023,33 @@
return $ids;
}
+ /**
+ * Creates a semaphore.
+ *
+ * @param IDBConnection $conn Database connection.
+ * @param array $master_ids Master record IDs.
+ *
+ * @return integer
+ */
+ protected function createSemaphore(IDBConnection $conn, array $master_ids)
+ {
+ $fields_hash = array(
+ 'SessionKey' => $this->Application->GetSID(),
+ 'Timestamp' => adodb_mktime(),
+ 'MainPrefix' => $this->Tables['Prefix'],
+ 'MainIDs' => implode(',', $master_ids),
+ 'UserId' => $this->Application->RecallVar('user_id'),
+ 'IPAddress' => $this->Application->getClientIp(),
+ 'Hostname' => $_SERVER['HTTP_HOST'],
+ 'RequestURI' => $_SERVER['REQUEST_URI'],
+ 'Backtrace' => serialize(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)),
+ );
+
+ $conn->doInsert($fields_hash, TABLE_PREFIX . 'Semaphores');
+
+ return $conn->getInsertID();
+ }
+
function CancelEdit($master=null)
{
if (!isset($master)) $master = $this->Tables;
Index: branches/5.2.x/core/install/english.lang
===================================================================
diff -u -r16754 -r16770
--- branches/5.2.x/core/install/english.lang (.../english.lang) (revision 16754)
+++ branches/5.2.x/core/install/english.lang (.../english.lang) (revision 16770)
@@ -204,6 +204,7 @@
UmVxdWlyZSBTU0wgZm9yIGxvZ2luICYgY2hlY2tvdXQ=
RnJhbWVzIGluIGFkbWluaXN0cmF0aXZlIGNvbnNvbGUgYXJlIHJlc2l6YWJsZQ==
TWluaW1hbCBTZWFyY2ggS2V5d29yZCBMZW5ndGg=
+ RGVsZXRlIFN0dWNrIFNlbWFwaG9yZXMgYWZ0ZXI=
U2Vzc2lvbiBTZWN1cml0eSBDaGVjayBiYXNlZCBvbiBCcm93c2VyIFNpZ25hdHVyZQ==
U2Vzc2lvbiBDb29raWUgRG9tYWlucyAoc2luZ2xlIGRvbWFpbiBwZXIgbGluZSk=
U2Vzc2lvbiBTZWN1cml0eSBDaGVjayBiYXNlZCBvbiBJUA==
@@ -1380,6 +1381,7 @@
Q29tbWVudHM=
TW9kdWxlIFJvb3QgU2VjdGlvbg==
U2F2ZQ==
+ c2Vjb25kcw==
U2VsZWN0
U2Vzc2lvbiBFeHBpcmVk
U2ltcGxl
Index: branches/5.2.x/core/install/upgrades.sql
===================================================================
diff -u -r16754 -r16770
--- branches/5.2.x/core/install/upgrades.sql (.../upgrades.sql) (revision 16754)
+++ branches/5.2.x/core/install/upgrades.sql (.../upgrades.sql) (revision 16770)
@@ -2964,3 +2964,11 @@
ADD COLUMN `LogCodeFragment` longtext NULL AFTER `LogSourceFileLine`,
ADD COLUMN `LogCodeFragmentsRotated` tinyint(4) NOT NULL DEFAULT '0' AFTER `LogCodeFragment`;
ALTER TABLE SystemLog ADD INDEX `TIMESTAMP_CODE_FRAGMENTS_ROTATED` (`LogTimestamp`,`LogCodeFragmentsRotated`) USING BTREE;
+
+ALTER TABLE Semaphores
+ ADD COLUMN `UserId` int(11) NULL,
+ ADD COLUMN `IpAddress` varchar(15) NOT NULL DEFAULT '',
+ ADD COLUMN `Hostname` varchar(255) NOT NULL DEFAULT '',
+ ADD COLUMN `RequestURI` varchar(255) NOT NULL DEFAULT '',
+ ADD COLUMN `Backtrace` longtext NULL;
+INSERT INTO SystemSettings VALUES(DEFAULT, 'SemaphoreLifetimeInSeconds', '300', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsSystem', 'la_config_SemaphoreLifetimeInSeconds', 'text', '', 'style=\"width: 50px;\"', 60.1, 0, 1, 'hint:la_config_SemaphoreLifetimeInSeconds');
Index: branches/5.2.x/core/units/admin/admin_events_handler.php
===================================================================
diff -u -r16664 -r16770
--- branches/5.2.x/core/units/admin/admin_events_handler.php (.../admin_events_handler.php) (revision 16664)
+++ branches/5.2.x/core/units/admin/admin_events_handler.php (.../admin_events_handler.php) (revision 16770)
@@ -1,6 +1,6 @@
Application->ConfigValue('SemaphoreLifetimeInSeconds');
+
+ $sql = 'SELECT *
+ FROM ' . TABLE_PREFIX . 'Semaphores
+ WHERE Timestamp < ' . strtotime('-' . $semaphore_lifetime . ' seconds');
+ $stuck_semaphores = $this->Conn->Query($sql, 'SemaphoreId');
+
+ if ( !$stuck_semaphores ) {
+ return;
+ }
+
+ /** @var LanguagesItem $language */
+ $language = $this->Application->recallObject('lang.current', null, array('skip_autoload' => true));
+ $date_format = $language->GetDBField('DateFormat') . ' ' . $language->GetDBField('TimeFormat');
+
+ foreach ( $stuck_semaphores as $semaphore_id => $semaphore_data ) {
+ $log = $this->Application->log('Stuck semaphore detected (unit: ' . $semaphore_data['MainPrefix'] . ')');
+ $log->setLogLevel(kLogger::LL_ERROR);
+ $log->addTrace(unserialize($semaphore_data['Backtrace']));
+ $log->setUserData(implode(PHP_EOL, array(
+ 'Main Prefix: ' . $semaphore_data['MainPrefix'],
+ 'Main IDs: ' . $semaphore_data['MainIDs'],
+ 'Created On: ' . date($date_format, $semaphore_data['Timestamp']),
+ 'Deleted On: ' . date($date_format),
+ )));
+
+ $log->setLogField('LogHostname', $semaphore_data['Hostname']);
+ $log->setLogField('LogRequestSource', 1); // Web.
+ $log->setLogField('LogInterface', kLogger::LI_ADMIN);
+ $log->setLogField('LogRequestURI', $semaphore_data['RequestURI']);
+ $log->setLogField('LogUserId', $semaphore_data['UserId']);
+ $log->setLogField('IpAddress', $semaphore_data['IpAddress']);
+ $log->setLogField('LogSessionKey', $semaphore_data['SessionKey']);
+
+ $log->write();
+
+ $sql = 'DELETE FROM ' . TABLE_PREFIX . 'Semaphores
+ WHERE SemaphoreId = ' . $semaphore_id;
+ $this->Conn->Query($sql);
+ }
+ }
+
}
Index: branches/5.2.x/core/admin_templates/config/custom_variables.tpl
===================================================================
diff -u -r15608 -r16770
--- branches/5.2.x/core/admin_templates/config/custom_variables.tpl (.../custom_variables.tpl) (revision 15608)
+++ branches/5.2.x/core/admin_templates/config/custom_variables.tpl (.../custom_variables.tpl) (revision 16770)
@@ -143,4 +143,8 @@
-
\ No newline at end of file
+
+
+
+
+
Index: branches/5.2.x/core/units/admin/admin_config.php
===================================================================
diff -u -r16664 -r16770
--- branches/5.2.x/core/units/admin/admin_config.php (.../admin_config.php) (revision 16664)
+++ branches/5.2.x/core/units/admin/admin_config.php (.../admin_config.php) (revision 16770)
@@ -1,6 +1,6 @@
Array ('EventName' => 'OnOptimizePerformance', 'RunSchedule' => '0 0 * * *'),
'purge_expired_database_cache' => Array ('EventName' => 'OnPurgeExpiredDatabaseCacheScheduledTask', 'RunSchedule' => '0 0,12 * * *'),
'populate_url_unit_cache' => array('EventName' => 'OnPopulateUrlUnitCacheScheduledTask', 'RunSchedule' => '0 * * * *'),
+ 'delete_stuck_semaphores' => array('EventName' => 'OnDeleteStuckSemaphoresScheduledTask', 'RunSchedule' => '*/5 * * * *'),
),
'TitlePresets' => Array (