У загальному сенсі, яка мета таблиці семафорів Drupal DB


9

Я розумію мету семафору в програмуванні IPC, але я не знаходжу хорошого - чи будь-якого - пояснення щодо цілей цієї таблиці.

Відповіді:


11

Таблиця семафорів використовується з механізму блокування, реалізованого за замовчуванням від Drupal. Він не відрізняється від звичайного механізму блокування, який спостерігається в програмуванні: значення використовується для перевірки того, що операція вже виконується, щоб уникнути конфліктів або перегонів. Різниця полягає в тому, що зазвичай замок - це файл, а Drupal використовує рядок у базі даних.

Фактично, механізм блокування має функції придбання блокування ( lock_acquire()) або очікування звільнення блокування ( lock_wait()). В обох випадках використовується база даних семафору.

// lock_acquire()
// Optimistically try to acquire the lock, then retry once if it fails.
// The first time through the loop cannot be a retry.
$retry = FALSE;
// We always want to do this code at least once.
do {
  try {
    db_insert('semaphore')
      ->fields(array(
        'name' => $name,
        'value' => _lock_id(),
        'expire' => $expire,
      ))
      ->execute();
    // We track all acquired locks in the global variable.
    $locks[$name] = TRUE;
    // We never need to try again.
    $retry = FALSE;
  }
  catch (PDOException $e) {
    // Suppress the error. If this is our first pass through the loop,
    // then $retry is FALSE. In this case, the insert must have failed
    // meaning some other request acquired the lock but did not release it.
    // We decide whether to retry by checking lock_may_be_available()
    // Since this will break the lock in case it is expired.
    $retry = $retry ? FALSE : lock_may_be_available($name);
  }
  //lock_may_be_available()
  $lock = db_query('SELECT expire, value FROM {semaphore} WHERE name = :name', array(':name' => $name))->fetchAssoc();
  if (!$lock) {
    return TRUE;
  }
  $expire = (float) $lock['expire'];
  $now = microtime(TRUE);
  if ($now > $expire) {
    // We check two conditions to prevent a race condition where another
    // request acquired the lock and set a new expire time. We add a small
    // number to $expire to avoid errors with float to string conversion.
    return (bool) db_delete('semaphore')
      ->condition('name', $name)
      ->condition('value', $lock['value'])
      ->condition('expire', 0.0001 + $expire, '<=')
      ->execute();
  }
  return FALSE;

У Drupal різні користувачі можуть запитувати одну і ту ж сторінку, що означає, що різні потоки або процеси можуть виконувати один і той же код одночасно. Це може спричинити проблеми, коли код, наприклад, оновлює таблицю бази даних. Використання замків - це спосіб уникнути цього, що може спричинити проблеми.

Причина використання таблиці баз даних полягає в тому, що Drupal вимагає роботи двигуна бази даних; використання таблиці бази даних також для механізму блокування - це спосіб зменшити вимоги. Механізм блокування може бути реалізований і за допомогою розширення APCu, і якщо я правильно пригадую, це робить модуль.


Відмінна відповідь. Але просто для того, щоб було зрозуміло, таблиця семафору є окремою від власних механізмів блокування в двигуні БД, що вона є власною (наприклад, mysql).
Майк

2
Таблиця семафорів створюється та використовується Drupal. Він не використовується з двигуна бази даних.
kiamlaluno

6

Відповідь від @kiamlaluno є повною та досконалою. Але, я думаю, вона фокусується на (блискучому) поясненні концепції / використання блокування db за допомогою семафорів друпала.

Я б, у свою чергу, ризикнув наблизитись до ОП:

Призначення таблиці семафору (як описано в описі створення таблиці семафор):

Таблиця для зберігання семафорів, замків, прапорів тощо, які не можна зберігати як змінні Drupal, оскільки їх не слід кешувати.

Отже, ціль цієї таблиці - це не просто механізми блокування db (поки що я можу зрозуміти з цього коментаря), і вона також стосується технічної вимоги уникати кешування змінних.

NB: Буде радий, що мене виправлять особи, які мають більше досвіду на цю тему, якщо я помиляюсь про це. Ура!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.