De um modo geral, qual é o objetivo da tabela de semáforo do Drupal DB

9

Entendo o propósito de semáforos na programação do IPC, mas não estou encontrando uma explicação boa - ou nenhuma - sobre o objetivo dessas tabelas.

Mike
fonte

Respostas:

11

A tabela de semáforo é usada no mecanismo de bloqueio implementado por padrão no Drupal. Não é diferente do mecanismo usual de travamento visto na programação: Um valor é usado para verificar se uma operação já está em andamento, para evitar conflitos ou condições de corrida. A diferença é que, normalmente, o bloqueio é um arquivo, enquanto o Drupal usa a linha em um banco de dados.

De fato, o mecanismo de bloqueio possui funções para adquirir um bloqueio ( lock_acquire()) ou aguardar que um bloqueio seja liberado ( lock_wait()). Nos dois casos, o banco de dados de semáforo é usado.

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

No Drupal, diferentes usuários podem solicitar a mesma página, o que significa que diferentes threads ou processos podem executar o mesmo código ao mesmo tempo. Isso pode causar problemas quando o código está, por exemplo, atualizando uma tabela de banco de dados. Usar bloqueios é uma maneira de evitar que isso possa causar problemas.

A razão pela qual uma tabela de banco de dados é usada é simplesmente porque o Drupal exige que um mecanismo de banco de dados funcione; O uso de uma tabela de banco de dados também para o mecanismo de bloqueio é uma maneira de reduzir os requisitos. O mecanismo de bloqueio também pode ser implementado usando a extensão APCu, e se bem me lembro, existe um módulo fazendo isso.

kiamlaluno
fonte
Excelente resposta. Mas, para ficar claro, a tabela de semáforo é separada dos mecanismos de bloqueio nativos no mecanismo de banco de dados em si (por exemplo, mysql).
Mike
2
A tabela de semáforo é criada e usada pelo Drupal. Não é usado no mecanismo de banco de dados.
Kiamlaluno
6

A resposta de @kiamlaluno é completa e perfeita. Mas, acho que ele se concentra em explicar (brilhantemente) o conceito / uso do bloqueio de banco de dados usando os semáforos do drupal.

Por sua vez, eu me aventuraria a me aproximar do OP:

O objetivo da tabela de semáforo é (conforme descrito na descrição da criação da tabela de semáforo):

Tabela para conter semáforos, bloqueios, sinalizadores etc. que não podem ser armazenados como variáveis ​​do Drupal, pois não devem ser armazenados em cache.

Portanto, o objetivo dessa tabela é mais do que apenas mecanismos de bloqueio de banco de dados (até agora eu entendo a partir desse comentário), e também aborda o requisito técnico de evitar o armazenamento em cache de variáveis.

NB: Teremos o maior prazer em ser corrigido por alguém com mais experiência neste tópico, se eu entendi errado. Felicidades!

Stefanos Petrakis
fonte