¿Existen enfoques comunes en la programación para elegir dinámicamente si realizar un cálculo en el cliente o en el servidor, en función de información como la carga del servidor o la latencia de la red?

El rendimiento de un sistema distribuido es difícil de modelar. Para ilustrar:

  • Cualquier conocimiento del cliente sobre la carga del servidor o los tiempos de ida y vuelta puede quedar obsoleto rápidamente. Un enrutador se reinicia o el servidor se atasca bajo algunas solicitudes grandes y de repente las características de rendimiento cambian.
  • Los clientes son parte del sistema que intentan modelar. Eso crea el potencial para un sistema dinámico. Supongamos que el servidor se sobrecarga y luego todos los clientes se desconectan. Ahora el sistema está descargado, por lo que todos los clientes comienzan a emitir solicitudes nuevamente. El servidor se sobrecarga, los clientes retroceden, etc.
  • La latencia a menudo está dominada por efectos estocásticos. La misma solicitud puede tardar 1 ms o 100 ms en función de factores impredecibles como la pérdida de paquetes. El asunto se complica aún más por las asimetrías. Dejar caer un paquete SYNACK puede ser mucho más costoso (en términos de latencia) que dejar caer un paquete en medio de una transmisión. (Los paquetes de establecimiento de conexión se emiten en serie y tienen tiempos de espera más largos que los paquetes de transmisión de datos).

Un modelo demasiado simple puede dar lugar a muchas respuestas incorrectas, lo que anula el propósito de tener un modelo.

Los modelos complejos pueden dar lugar a mejores predicciones, sin embargo, vienen con sus propios desafíos:

  • Son difíciles de construir y mantener.
  • Pueden ser caros de calcular. (Esta es la razón por la cual muchos equilibradores de carga tempranos usarían tareas extremadamente simples como round-robin. En sistemas de alto volumen, el rendimiento del equilibrador de carga era más importante que la carga uniforme del servidor).
  • Siempre surgirán algunas circunstancias por las cuales el modelo no tiene en cuenta.

Dicho esto, aquí está el algo súper increíble de Paul para un rendimiento óptimo:

  • Enviar dos solicitudes idénticas al servidor.
  • Inicie un hilo para hacer el cálculo localmente.
  • Toma el resultado del primero en regresar y matar a los otros dos.

Hay sistemas operativos de investigación que pueden hacer esto.

Por ejemplo: Amoeba (sistema operativo)

Este es el proyecto para el que se desarrolló originalmente el lenguaje Python, para proporcionar una forma independiente de plataforma e procesador para ejecutar el código en la máquina virtual Amoeba.

Sin embargo, el problema al tomar esta decisión es que:

  1. Los clientes superan enormemente en número a los servidores; así que estás loco para transferir cualquier trabajo que se pueda hacer en el cliente al servidor
  2. El trabajo en el que el servidor debe poder confiar en los resultados no puede realizarse en el cliente por razones de seguridad (como sistema operativo de investigación, la seguridad es algo que un estudiante graduado debe hacer más adelante)
  3. El trabajo que puede realizarse en el servidor o en el cliente debe ser descargado al cliente por el servidor (corolario al # 1)

Así que sabemos, a priori, según quién tiene que confiar en los datos, dónde debe llevarse a cabo el cálculo.

Esta no es una decisión que los sistemas bien diseñados toman dinámicamente.

Sí, y es realmente super fácil.

  • Realice siempre la operación en el cliente , a menos que se aplique una excepción.

Eso es todo. Agradable y fácil de recordar.

Desafortunadamente, como la regla implica, hay algunas excepciones. La primera es que, para cualquier cosa que le interese, esta regla es reemplazada por otra:

  • Nunca confíes en el cliente.

Entonces, cualquier cosa que le interese, cualquier cosa en la que el lado del cliente pueda ser convencido de “hacer trampa”, especialmente de una manera que pueda afectar el dinero u otros usuarios en su sistema, no puede confiar en el lado del cliente, así que debe hacerlo el lado del servidor de cálculo. El servidor se convierte en la “última fuente de verdad”.

Otra excepción, y esto casi nunca sucede, es cuando el resultado del cálculo solo se puede almacenar en caché si el servidor realiza el cálculo.

Otra rara excepción es aquella en la que la carga causada por enviar al cliente los datos que necesita para calcular la respuesta, luego el cliente que envía su respuesta al servidor, es mayor que la carga causada por el servidor que calcula la respuesta y la envía al cliente .

Estoy seguro de que puede pensar en otros casos en los que hacer cosas en el servidor podría darle una ventaja, tal vez para ser más justo para los destinatarios de los datos, en lugar de dar el resultado primero a aquel cuya computadora lo resolvió; o porque es más rápido resolverlo en el servidor, enviarlo a todos, que pedirlo a un cliente, recibirlo de ese cliente y luego enviarlo a todos.

Pero básicamente; hazlo en el lado del cliente a menos que tengas que hacerlo en el servidor.

La validación es un buen ejemplo. La validación de Clienside se puede evitar o subvertir, por lo tanto, siempre valide los datos enviados al servidor. Pero eso no significa no hacerlo también del lado del cliente. En un formulario web, por ejemplo, la validación del lado del cliente le da al usuario una respuesta más rápida y fluida a sus entradas, de inmediato rellenan el campo incorrecto, en lugar de cuando envían el formulario. Pero todavía tiene que validar en el servidor también.