Resumen

  • El XID de 32 bits de ONC RPC vuelve en la respuesta y permite al solicitante saber a qué llamada corresponde. El servidor puede usar la igualdad para reconocer un posible reenvío, pero no leer el campo como secuencia ni como prueba de ejecución única.
  • NFS mostró el coste de completar esa evidencia. Las cachés volátiles de duplicados reducían daños durante una ventana; NFSv4.1 limitó las solicitudes pendientes mediante sesiones, ranuras, secuencias por ranura y respuestas conservadas.

El reintento no traía el pasado consigo

Una máquina pide al servidor que cambie un nombre. El servidor termina la operación. La respuesta se pierde. Cuando expira el temporizador, el cliente sólo sabe que no vio el final; no sabe si el servidor nunca recibió la llamada, si todavía trabaja o si ya cambió el sistema de archivos.

Enviar otra copia restablece la posibilidad de obtener respuesta, pero abre otra: aplicar de nuevo el efecto. La segunda llamada puede ser byte por byte igual a la primera y, aun así, llegar a un mundo distinto. El nombre quizá ya no exista o una operación posterior quizá dependa del resultado inicial.

La primera descripción pública de esta familia, RFC 1050 de abril de 1988, dejó la fiabilidad fuera del protocolo de mensajes. Su sustituta inmediata, RFC 1057, formuló la incertidumbre sin rodeos: sobre UDP, tras reintentar, el silencio no permite contar ejecuciones; una respuesta sólo acredita que hubo al menos una.

El problema no era elegir un temporizador mejor. Ningún plazo puede distinguir por sí solo una llamada perdida de una respuesta perdida después del cambio. Hace falta evidencia en el lugar donde se produjo el efecto.

El número resolvía correspondencia, no repetición

Todo mensaje RPC versión 2 empieza con un XID sin signo de 32 bits. El REPLY copia el XID del CALL que lo originó. Un cliente con varias solicitudes simultáneas puede así entregar cada resultado a la espera correcta.

Esa función es indispensable, pero pequeña. RFC 5531 permite al servicio comparar XIDs para detectar retransmisiones y le prohíbe tratarlos como números de secuencia. El valor no dice que un CALL sea posterior a otro, no contiene la época de arranque del servidor y no declara cuánto tiempo sigue vigente.

El texto ofrece una posibilidad, no una garantía automática. El cliente puede reutilizar el XID anterior al retransmitir. El servidor puede recordarlo después de ejecutar y evitar una segunda ejecución del mismo valor. El comportamiento de “como máximo una vez” aparece sólo si ambas decisiones y la memoria del servidor coinciden.

Cambiar el XID en el reintento rompe el vínculo por igualdad. Perder la entrada de caché lo rompe en el otro extremo. Reutilizar el entero mucho después puede producir una igualdad engañosa si no se delimita por solicitante, programa, versión, procedimiento y época.

Una respuesta fiable tenía una frontera

La evolución de la especificación mantuvo la distinción. RFC 1831 conservó el modelo y RFC 5531 lo llevó a Standards Track. Ambas explican que recibir una respuesta mediante un transporte fiable permite una inferencia de ejecución exactamente una vez dentro de ese intercambio. Pero si no llega respuesta, ni siquiera TCP autoriza a concluir que la operación no ocurrió.

Una conexión ordena bytes y detecta parte de sus fallos. No guarda por sí misma el historial de la aplicación después de que el proceso se reinicia. Cuando el cliente reconecta, la nueva corriente no puede decidir si la llamada antigua alcanzó un punto de compromiso antes de desaparecer.

Tampoco el XID autentica. RPC coloca credenciales y verificadores en campos distintos. Un número coincidente relaciona mensajes según el estado local del cliente; no certifica al principal, no firma el contenido y no demuestra persistencia.

NFS convirtió la ambigüedad en pérdida posible

El diseño temprano de NFS quería servidores casi sin estado de protocolo. RFC 1094 defendía una recuperación sencilla: el cliente podía repetir solicitudes hasta que el servidor volviera, sin reconstruir una conversación almacenada.

Esa libertad exigía diseñar operaciones idempotentes siempre que fuera posible. Leer otra vez o escribir los mismos datos en el mismo intervalo tendía a un resultado equivalente. Sin embargo, REMOVE, RENAME, LINK, MKDIR y otras operaciones aparecían como potencialmente no idempotentes. Su segunda aplicación podía fallar o tocar un estado que ya había cambiado.

RFC 1813 describió para NFSv3 consecuencias más duras. Una repetición de una operación no idempotente podía ser destructiva. Una truncación repetida podía eliminar escrituras posteriores. Incluso sobre una conexión fiable, una rotura seguida de reconexión llevaba al cliente a retransmitir sin saber si la primera copia había terminado.

El servidor stateless simplificaba una clase de reinicio, pero no anulaba la causalidad. Sólo trasladaba el problema hacia las propiedades de cada operación, las reglas del cliente y cualquier memoria auxiliar del ejecutor.

La caché de duplicados tenía un horizonte

La práctica común de NFSv3 fue mantener una caché de solicitudes recientes. Tras terminar una operación, el servidor guardaba su estado de finalización. Si reconocía una copia, devolvía el resultado original y no volvía a aplicar el procedimiento.

Esa caché era parte de la corrección, no una comodidad intercambiable con cualquier acelerador. Permitía que la decisión sobre el duplicado la tomara quien había ejecutado el primer efecto. Sin embargo, RFC 1813 también fijó la reserva: la memoria solía ser RAM y se perdía en una caída. Al ser finita, podía expulsar una entrada durante una partición prolongada. El siguiente reintento entraba como nuevo.

Por eso un XID no equivale a una clave de idempotencia durable. La promesa depende del ámbito de búsqueda, la huella del procedimiento y los argumentos, la política de reemplazo, la persistencia y la identidad del servidor tras una conmutación.

La creación exclusiva de NFSv3 ofrece la contraprueba. Guardaba un verifier asociado al objeto para reconocer una creación anterior incluso cuando la caché normal ya no podía hacerlo. La evidencia más fuerte debía vivir cerca del estado que protegía.

Las sesiones limitaron la deuda de memoria

NFSv4.1 no intentó recordar un universo ilimitado de XIDs. RFC 5661 introdujo sesiones; la norma vigente, RFC 8881, asigna una tabla acotada de ranuras y a cada ranura un identificador de secuencia más la respuesta actual almacenada.

El solicitante toma una ranura libre. Una solicitud nueva avanza su secuencia; un reintento repite la misma. El servidor compara con el valor que conserva. Si es el siguiente, ejecuta trabajo nuevo. Si es igual al actual y el trabajo terminó, devuelve la respuesta guardada. Si el valor está fuera de orden, responde con el error previsto en vez de adivinar.

La ranura hace finita la obligación. El máximo negociado limita cuántas llamadas pueden quedar pendientes y cuántas respuestas necesita custodiar el servidor. Cuando llega la secuencia siguiente, también hay evidencia de que el cliente superó el resultado anterior y la entrada puede reciclarse.

RFC 8881 explica por qué el XID opaco no ofrecía ese límite. Las llamadas RPC pueden terminar fuera de orden y la replier no interpreta los 32 bits salvo por igualdad. Conservar todas las respuestas posibles sería impracticable. La sesión transforma un espacio amplio de nombres en un número acordado de responsabilidades activas.

La ejecución única seguía dependiendo de la recuperación

Ni siquiera una ranura convierte la memoria volátil en historia permanente. Para sostener EOS a través de un reinicio, el servidor debe preservar el estado de recuperación y la caché de respuestas pertinente. Si la máquina conserva los efectos pero pierde las respuestas, reaparece la duda.

NFSv4.1 mantuvo XID para la correlación RPC. La combinación de session ID, slot ID y sequence ID añade contexto al reintento; no declara que el XID anterior fuera inútil. Cada identificador conserva una tarea concreta.

La innovación fue pagar explícitamente por la afirmación más fuerte. El protocolo limitó simultaneidad, definió transiciones y señaló cuándo podía descartarse una respuesta. “Exactamente una vez” dejó de descansar en la apariencia del mismo entero y pasó a depender de estado gobernado.

Los límites de una igualdad

Un mismo XID no prueba mismos argumentos, mismo principal, misma instancia de servidor ni misma época. Un miss de caché no demuestra novedad. Un hit no demuestra que el efecto sea durable. Y la etiqueta “idempotente” no resuelve el orden: una copia antigua de WRITE que termina tarde puede sobrescribir una escritura más nueva, ejemplo que RFC 8881 usa para exigir EOS incluso en operaciones modificadoras idempotentes.

El aprendizaje histórico es más sobrio. El identificador hace posible preguntar si dos mensajes coinciden. La respuesta correcta requiere que el sistema que ejecuta conserve resultado, contexto y reglas de expiración durante toda la ventana en que el cliente todavía puede dudar.

Fuentes y límites de la evidencia

La línea de especificaciones RPC va de RFC 1050 y 1057 a RFC 1831 y 5531. RFC 1094 documenta el objetivo stateless de NFS; RFC 1813, la caché de duplicados y sus límites. RFC 5661 introdujo las sesiones NFSv4.1 y RFC 8881 contiene su formulación actual. Son normas y experiencia documentada, no un censo de productos, tamaños de caché, persistencia o cumplimiento actual.