historia ejemplos clojure stm

historia - clojure ejemplos



¿Cómo debo hacer persistente un programa STM clojure? (4)

Estoy escribiendo un programa de clojure que usa el STM. En este momento, estoy llenando el STM (usando refs) al inicio desde una base de datos, y luego actualizo la base de datos de forma asíncrona cada vez que una transacción de dosync tiene éxito. No tengo idea de si estoy haciendo esto de la manera correcta, o si hay una técnica estándar mejor para hacerlo. ¿Podría alguien explicarme cómo convierten las propiedades ACI de STM en ACID en sus programas de Clojure?


El modelo STM es muy adecuado para rastrear el acceso múltiple a los sistemas a medida que cambian. Se adapta menos directamente a la persistencia de datos donde los cambios deben ser accesibles más allá de la vida de los hilos que los acceden.

En general, es bueno pensar en la ''D'' en ACID por separado del STM


En general, agregar la ''D'' en ACID a cualquier programa no es trivial y depende de los requisitos del programa. Hay una especificación importante que debe determinarse antes de que se pueda determinar la implementación.

¿Hay acceso multiproceso / multiproceso a la base de datos?

Desde el cuerpo de la pregunta, su programa parece leer solo al inicio y escribir después de un cambio en el STM, donde la base de datos retrasaría los valores en el STM por una pequeña cantidad de tiempo. Sin embargo, si otros programas, incluyendo otras instancias de su programa, acceden a la base de datos, deberá usar los bloqueos donde bloquea el acceso a la base de datos justo antes de las transacciones y desbloquearlos después de la escritura en la base de datos (como nota al margen, tenga en cuenta que la base de datos en su caso puede ser cualquier cosa, incluido un archivo simple en el sistema de archivos). No hay forma de evitar esto cuando tiene múltiples lecturas y escrituras, ya que ambos son efectos secundarios que involucran a la base de datos.

Si no hay acceso múltiple , entonces la escritura asíncrona está bien porque se garantiza que el código siempre funcionará en orden, ya que su programa tiene un solo hilo cuando se accede.

Si solo tiene varios subprocesos de escritura y no hay lecturas después del inicio con solo una instancia , entonces solo necesita garantizar el orden de escritura correcto. Puede hacer esto con agentes, donde el agente es básicamente una cola de operaciones de escritura en la base de datos. Envuelve la dosync alrededor de las transacciones de referencia y el agente, lo que le proporciona durabilidad además de persistencia.

En general, cuanto más complicados sean los requisitos que involucran efectos secundarios, más trucos tendrá que hacer para garantizar ACID. Si tiene requisitos adicionales, entonces las implementaciones que di podrían tener que cambiar.

EDITAR:

(def db-agent (agent dummy-value)) (defn db-write [_ data] ;; make this intelligent to handle when db is not up (try (write-to-db data) (catch ... database fails, do a retry or let user know of problem)) _) ;; in the transaction code (dosync (alter my-ref ...) (send-off db-agent db-write @my-ref)) ;; ensure db gets written to


Si desea una base de datos que tenga acceso rápido a la memoria y que persista entre bambalinas de vez en cuando, use un almacén de datos real, en lugar de intentar construir su propia base, lo que sería un trabajo bastante importante.

Redis y MongoDB son dos buenas opciones, pero hay muchas otras. Puede encontrar las bibliotecas de Clojure en https://github.com/ragnard/redis-clojure y https://github.com/somnium/congomongo para Redis y Mongo, respectivamente.