W ogólnym sensie, jaki jest cel tabeli semaforowej Drupal DB

9

Rozumiem cel semaforów w programowaniu IPC, ale nie znajduję dobrego - ani żadnego - wyjaśnienia co do tego celu tabel.

Mikrofon
źródło

Odpowiedzi:

11

Tabela semaforów jest używana z mechanizmu blokującego implementowanego domyślnie z Drupal. Nie różni się od zwykłego mechanizmu blokowania widocznego w programowaniu: Wartość służy do sprawdzenia, czy operacja jest już w toku, aby uniknąć konfliktów lub warunków wyścigu. Różnica polega na tym, że zwykle zamek jest plikiem, a Drupal używa wiersza w bazie danych.

W rzeczywistości mechanizm blokujący ma funkcje uzyskiwania blokady ( lock_acquire()) lub czekania na zwolnienie blokady ( lock_wait()). W obu przypadkach używana jest baza semaforów.

// 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;

W Drupal różni użytkownicy mogą żądać tej samej strony, co oznacza, że ​​różne wątki lub procesy mogą wykonywać ten sam kod w tym samym czasie. Może to powodować problemy, gdy kod na przykład aktualizuje tabelę bazy danych. Korzystanie z zamków jest sposobem na uniknięcie tego, co może powodować problemy.

Powodem użycia tabeli bazy danych jest po prostu to, że Drupal wymaga silnika bazy danych do działania; użycie tabeli bazy danych również dla mechanizmu blokującego jest sposobem na zmniejszenie wymagań. Mechanizm blokujący można również wdrożyć za pomocą rozszerzenia APCu, a jeśli dobrze pamiętam, moduł to robi.

kiamlaluno
źródło
Doskonała odpowiedź. Ale dla jasności, tablica semaforów jest oddzielna od natywnych mechanizmów blokujących w silniku DB, jest ona własna (np. Mysql).
Mike
2
Tabela semaforów jest tworzona i używana przez Drupala. Nie jest używany z silnika bazy danych.
kiamlaluno
6

Odpowiedź od @kiamlaluno jest kompletna i idealna. Ale myślę, że koncentruje się na (genialnym) wyjaśnieniu pojęcia / zastosowania blokowania db przy użyciu semaforów drupala.

Z kolei zaryzykuję zbliżenie się do PO:

Celem tabeli semaforów jest (jak opisano w opisie tworzenia tabeli semaforów):

Tabela do przechowywania semaforów, blokad, flag itp., Które nie mogą być przechowywane jako zmienne Drupala, ponieważ nie mogą być buforowane.

Tak więc celem tej tabeli jest coś więcej niż tylko mechanizmy blokowania db (jak do tej pory rozumiem z tego komentarza), a także spełnia on techniczny wymóg unikania buforowania zmiennych.

NB: Z przyjemnością poprawię je ktoś, kto ma większą wiedzę na ten temat, jeśli się mylę. Twoje zdrowie!

Stefanos Petrakis
źródło