In senso generale, qual è lo scopo della tabella dei semafori di Drupal DB


9

Capisco lo scopo di un semaforo nella programmazione IPC ma non sto trovando una buona, o nessuna, spiegazione su questo scopo delle tabelle.

Risposte:


11

La tabella dei semafori viene utilizzata dal meccanismo di blocco implementato di default da Drupal. Non è diverso dal solito meccanismo di blocco visto in programmazione: un valore viene utilizzato per verificare che un'operazione sia già in corso, per evitare conflitti o condizioni di gara. La differenza è che, normalmente, il blocco è un file, mentre Drupal utilizza la riga in un database.

In effetti, il meccanismo di blocco ha funzioni per acquisire un blocco ( lock_acquire()) o attendere il rilascio di un blocco ( lock_wait()). In entrambi i casi, viene utilizzato il database dei semafori.

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

In Drupal, diversi utenti possono richiedere la stessa pagina, il che significa che thread o processi diversi potrebbero eseguire lo stesso codice contemporaneamente. Ciò potrebbe causare problemi quando, ad esempio, il codice aggiorna una tabella del database. L'uso dei lucchetti è un modo per evitare che ciò possa causare problemi.

Il motivo per cui viene utilizzata una tabella di database è semplicemente che Drupal richiede un motore di database per funzionare; l'utilizzo di una tabella di database anche per il meccanismo di blocco è un modo per ridurre i requisiti. Il meccanismo di blocco potrebbe essere implementato anche usando l'estensione APCu, e se ricordo bene, c'è un modulo che lo fa.


Risposta eccellente. Ma per essere chiari, la tabella dei semafori è separata dai meccanismi di blocco nativi nel motore DB, è autonoma (ad esempio mysql).
Mike,

2
La tabella dei semafori viene creata e utilizzata da Drupal. Non viene utilizzato dal motore di database.
kiamlaluno

6

La risposta di @kiamlaluno è completa e perfetta. Ma penso che si concentri sulla spiegazione (brillantemente) del concetto / uso del blocco db usando i semafori di Drupal.

Mi azzerei a mia volta avvicinandomi all'OP:

Lo scopo della tabella dei semafori è (come descritto nella descrizione della creazione della tabella dei semafori):

Tabella per contenere semafori, blocchi, flag, ecc. Che non possono essere memorizzati come variabili Drupal poiché non devono essere memorizzati nella cache.

Quindi, lo scopo di quella tabella è qualcosa di più dei semplici meccanismi di blocco dei db (finora posso capire da quel commento), e affronta anche il requisito tecnico di evitare la memorizzazione nella cache delle variabili.

NB: Sarò felice di essere corretto da qualcuno con maggiori competenze su questo argomento se ho sbagliato. Saluti!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.