cas

(se requiere Workerman versión >= 3.3.0)

bool \GlobalData\Client::cas(string $key, mixed $old_value, mixed $new_value)

Sustitución atómica, usando $new_value para reemplazar $old_value.
Solo se puede escribir el valor si, después de que el cliente actual haya obtenido el último valor, el valor correspondiente a esa clave no ha sido modificado por otros clientes.

Parámetros

$key

Clave. (por ejemplo, $global->abc, donde abc es la clave)

$old_value

Datos antiguos

$new_value

Datos nuevos

Valor de retorno

Retorna true si la sustitución es exitosa, de lo contrario, retorna false.

Descripción:

Cuando múltiples procesos operan simultáneamente sobre una misma variable compartida, a veces hay que considerar problemas de concurrencia.

Por ejemplo, los procesos A y B añaden un miembro a la lista de usuarios simultáneamente.
La lista de usuarios de los procesos A y B es actualmente $global->user_list = array(1,2,3).
El proceso A opera sobre la variable $global->user_list, añadiendo un usuario 4.
El proceso B opera sobre la variable $global->user_list, añadiendo un usuario 5.
El proceso A establece la variable $global->user_list = array(1,2,3,4) con éxito.
El proceso B establece la variable $global->user_list = array(1,2,3,5) con éxito.
En este momento, la variable establecida por el proceso B sobrescribirá la variable establecida por el proceso A, provocando la pérdida de datos.

Lo anterior se debe a que la lectura y establecimiento no son una operación atómica, lo que provoca problemas de concurrencia.
Para resolver este tipo de problemas de concurrencia, se puede utilizar la interfaz de sustitución atómica cas.
La interfaz cas, antes de cambiar un valor,
verifica si ese valor ha sido modificado por otros procesos, según el $old_value.
Si se ha modificado, no se reemplaza y retorna false. De lo contrario, se reemplaza y retorna true.
Véase el siguiente ejemplo.

Nota:
No hay problema en que algunos datos compartidos sean sobreescritos de manera concurrente, por ejemplo, la oferta máxima actual de un artículo en un sistema de subastas, o el stock actual de un producto.

Ejemplo

$global = new GlobalData\Client('127.0.0.1:2207');

// Inicializar la lista
$global->user_list = array(1,2,3);

// Agregar un valor de manera atómica a user_list
do
{
    $old_value = $new_value = $global->user_list;
    $new_value[] = 4;
}
while(!$global->cas('user_list', $old_value, $new_value));

var_export($global->user_list);