Este documento es un borrador y no se debe asumir que representa la arquitectura final.
Este documento describe como Wikibase propaga los cambios en el repositorio a las wikis clientes.
Resumen
- Cada cambio en el repositorio se registra en la tabla de cambios que actúa como una fuente de actualización para cualquier wikis cliente (como las Wikipedias).
- Los scripts del despachador comprueban periódicamente la tabla de cambios.
- Cada wiki cliente es notificado de cualquier cambio en los cambios del repositorio a través de una entrada en su cola de trabajos. Estos trabajos se utilizan para invalidar y volver a renderizar la(s) página(s) relevante(s) en el wiki cliente
- Las notificaciones sobre los cambios se inyectan en la tabla de cambios recientes del cliente, para hacerlos visibles en las listas de seguimiento, etc.
- Las ediciones consecutivas realizadas por el mismo usuario en el mismo elemento de datos pueden combinarse en una sola, para evitar el desorden.
Suposiciones y Terminología
Los datos gestionados por el repositorio Wikibase están estructurados en entidades (de datos). Cada entidad se mantenida como una página wiki que contiene datos estructurados. Hay varios tipos de entidades, pero una es particularmente importante en este contexto: los ítems. Los artículos son especiales porque están vinculados con páginas de artículos en cada wiki cliente (por ejemplo, cada Wikipedia). Para más información, consulta la página imagen del modelo de datos.
El mecanismo de propagación se basa en la suposición de que cada elemento de datos en el repositorio de Wikidata tiene como máximo un enlace con cada wiki cliente, y que sólo un elemento del repositorio puede enlazar con cualquier página de un wiki cliente determinado. Es decir, cualquier página de cualquier wiki cliente puede estar asociada a un solo elemento de datos en el repositorio.
(Véase el comentario en la página de discusión sobre las consecuencias de limitar la propagación de los cambios a los casos en que la página de Wikipedia y el elemento de Wikidata tienen una relación 1:1)
Este mecanismo también supone que todos los wikis, el repositorio y los clientes (es decir, Wikidata y las Wikipedias), pueden conectarse directamente a las bases de datos de los demás. Normalmente, esto significa que residen en la misma red local. Sin embargo, los wikis pueden utilizar servidores de bases de datos separados: los wikis se agrupan en secciones, donde cada sección tiene una base de datos maestra y potencialmente muchas bases de datos esclavas (formando juntas un clúster de bases de datos).
La comunicación entre el repositorio (Wikidata) y los clientes (Wikipedias) se realiza mediante un feed de actualización. Por ahora, esto se implementa como una tabla de base de datos (la tabla de cambios) a la que acceden los scripts de envío directamente, utilizando el mecanismo de "base de datos extranjera".
El soporte para clientes de terceros, es decir, wikis clientes y otros consumidores fuera de Wikimedia, actualmente no es esencial y no se implementará por ahora. Sin embargo, se tendrá en en cuenta para todas las decisiones de diseño.
Registro de cambios
Cada cambio realizado en el repositorio se registra en una tabla (la "tabla de cambios", a saber wb_changes) en la base de datos del repositorio. La tabla de cambios se comporta de forma similar a la tabla de MediaWiki, en el sentido de que sólo mantiene los cambios durante un cierto tiempo (por ejemplo, un día o una semana), las entradas más antiguas se purgan periódicamente. Las entradas más antiguas se purgan periódicamente. Sin embargo, a diferencia de la tabla recentchanges, wb_changes contiene toda la información necesaria para informar y reproducir el cambio en un wiki cliente: además de la información información sobre cuándo se hizo el cambio y por quién, contiene una diferencia estructural con la revisión anterior de la entidad. revisión anterior de la entidad.
Efectivamente, la tabla de cambios actúa como una fuente de actualización. Se debe tener cuidado de aislar la tabla de la base de datos de la base de datos como un detalle de la implementación del feed de actualización, para que pueda ser reemplazado más tarde por un mecanismo alternativo, como PubHub o un bus de eventos. mecanismo alternativo, como PubHub o un bus de eventos. Sin embargo, hay que tener en cuenta que un protocolo con semántica de cola no es apropiado (requeriría una cola por cliente).
Distribución de cambios
Los cambios en el repositorio (por ejemplo, wikidata.org) se envían a los wikis clientes (por ejemplo, Wikipedias) mediante un script de envío. Este script consulta la tabla wb_changes del repositorio en busca de cambios, y los envía y los envía a los wikis clientes enviando los trabajos apropiados a la cola de trabajos del cliente.
El script del despachador está diseñado de manera que permite que cualquier número de instancias se ejecute y comparta la carga sin ningún conocimiento previo de los demás. Se coordinan a través de la base de datos del repoysitorio utilizando la tabla wb_changes_dispatch:
- chd_client: el nombre de la base de datos del cliente (clave primaria).
- chd_latest_change: el ID del último cambio que se envió al cliente.
- chd_touched: una marca de tiempo que indica cuándo se enviaron las últimas actualizaciones al cliente.
- chd_lock_name: el nombre del bloqueo global utilizado por el despachador que está actualizando ese cliente (o NULL).
El despachador funciona siguiendo los siguientes pasos:
- Bloquear e inicializar
- Elija un cliente para actualizar de la lista de clientes conocidos.
- Iniciar la transacción en la base de datos maestra del repositorio.
- Leer la fila del cliente dado desde wb_changes_dispatch (si falta, asumir chd_latest_change = 0).
- Si chd_lock_name no es null, llama a IS_FREE_LOCK(chd_lock_name) en la base de datos maestra del cliente.
- Si eso devuelve 0, otro despachador está manteniendo el bloqueo. Salir (o intentar con otro cliente).
- Decide un nombre de bloqueo (dbname.wb_changes_dispatch.client o algo así) y usa GET_LOCK() para coger ese bloqueo en la base de datos maestra del cliente.
- Actualizar la fila del cliente en wb_changes_dispatch con el nuevo nombre del bloqueo en chd_lock_name.
- Confirmar la transacción en la base de datos maestra del repositorio.
- Realizar el envío
- Obtener n cambios con IDs > chd_latest_change de wb_changes en la base de datos del repo. n es el tamaño de lote configurado.
- Filtrar los cambios para aquellos que son relevantes para este wiki cliente (opcional, y puede resultar complicado en casos complejos, por ejemplo, consultas en caché).
- Colocar los correspondientes trabajos de notificación de cambios en la cola de trabajos del wiki cliente.
- Log y desbloqueo
- Iniciar la transacción DB en la base de datos maestra del repo.
- Actualizar la fila del cliente en wb_changes_dispatch con chd_lock_name=NULL y actualizar chd_latest_change y chd_touched.
- Llamar a RELEASE_LOCK() para liberar el bloqueo global que teníamos.
- Confirmar la transacción en la base de datos maestra del repositorio.
Esto se puede repetir varias veces por un proceso, con un retraso configurable entre ejecuciones.
Procesos para la notificación de cambios
El despachador envía trabajos de notificación de cambios a la cola de trabajos del wiki cliente. Estos trabajos contienen una lista de cambios en los wikidatos. Cuando se procesa un trabajo de este tipo, el wiki cleint realiza los siguientes pasos:
- Si el cliente mantiene una caché local de datos de entidades, actualícela.
- Encuentra las páginas que necesitan ser re-renderizadas después del cambio. Invalidarlas y purgarlas de las cachés web. Opcionalmente, programar trabajos de re-renderización (o actualización de enlaces), o incluso re-renderizar la página directamente.
- Encontrar qué páginas tienen cambios que no necesitan volver a renderizar el contenido, pero influyen en la salida de la página, y por lo tanto necesitan ser purgados de la caché web (esto puede ser en algún momento el caso de los cambios en los enlaces de idioma).
- Inyectar notificaciones sobre cambios relevantes en la tabla recentchanges del cliente. Para ello, las ediciones consecutivas del mismo usuario en el mismo elemento pueden ser coalesced.
- Posiblemente también inyectar una "entrada nula" en el historial de las páginas respectivas, es decir, en la tabla de revisiones.
(Véase el comentario en la página de discusión sobre la tabla de cambios recientes frente a la tabla histórica)
Eventos de coalescencia
El sistema descrito anteriormente significa varias escrituras en la base de datos por cada cambio - y potencialmente muchas lecturas, dependiendo de lo que se necesite para renderizar la página. Y esto sucede en cada wiki cliente (potencialmente cientos) por cada cambio en el repositorio. Dado que las ediciones en el repositorio de Wikibase tienden a ser de grano muy fino (como el establecimiento de una etiqueta o la adición de un enlace al sitio), esto puede ser rápidamente problemático. La coalescencia de las actualizaciones podría ayudar a resolver este problema:
Como se explica en la sección Dispatching, las entradas en el feed de cambios se procesan por lotes (por defecto, no más de 100 entradas a la vez).
Si se procesan varios cambios en el mismo elemento en el mismo lote, estos cambios pueden unirse si fueron realizados consecutivamente por el mismo usuario. Esto reduciría el número de veces que las páginas son invalidadas (y por lo tanto, eventualmente re-renderizadas. Todas las entradas necesarias en la tabla recentchanges (y posiblemente en la tabla de revisiones) pueden ser insertadas usando una sola petición a la base de datos. Este proceso puede ser ajustado mediante el ajuste del tamaño del lote y el retraso entre lotes.