[Pregunta]: ¿Una forma eficiente de hacer algo como esto?

Iniciado por Leguim, 13 Junio 2020, 22:26 PM

0 Miembros y 1 Visitante están viendo este tema.

Leguim

Básicamente tengo un sistema de versiones (v0.0.1, v.1.5.2, etcétera) que al agregar una quiero que se les envíe una notificación a todos los usuarios avisándoles, pero quiero hacerlo de la mejor forma posible para que el sistema no vaya lento o se "atasque"...

imaginemos una aplicación con 1 millón de usuarios...

Código (php) [Seleccionar]

$id_version = versiones::Agregar($x);
notificaciones::Agregar($id_user, $id_version, 'versiones.php');


se me ocurre hacer un for por medio de la cantidad de usuarios en total registrados, pero como dije un for con 1 millón de iteraciones no me parece una buena solución...

Código (php) [Seleccionar]

$id_version = versiones::Agregar($x);

for($i = 0; $i < count($usuarios_total); $i++)
{
       notificaciones::Agregar($id_user, $id_version, 'versiones.php');
}


Gracias!

MinusFour

Pues lo ideal sería que usara concurrencia y paralelismo. Por ejemplo, podrías dividir la carga entre 4 diferentes procesos (250,000 registros por proceso) aunque ahí también va a depender del scheduler del sistema operativo.

Realmente, 1 millon de usuarios conectados al mismo tiempo a un solo servidor es bastante de por sí... Ni se diga que tienes que cargar 1 millon de registros. Imagina que son 250 bytes de información por registro, 1 millon de registros es cerca de 250MB en RAM.

Leguim

Cita de: MinusFour en 14 Junio 2020, 05:16 AM
Pues lo ideal sería que usara concurrencia y paralelismo. Por ejemplo, podrías dividir la carga entre 4 diferentes procesos (250,000 registros por proceso) aunque ahí también va a depender del scheduler del sistema operativo.

Realmente, 1 millon de usuarios conectados al mismo tiempo a un solo servidor es bastante de por sí... Ni se diga que tienes que cargar 1 millon de registros. Imagina que son 250 bytes de información por registro, 1 millon de registros es cerca de 250MB en RAM.

Estaba pensando algo parecido, pero lo dejé como una utopía... pero ahora que vos también lo comentas veré si no hago algo como eso.

No tengo del todo claro como debería hacerlo igualmente...

@XSStringManolo

#3
Y hacer una pagina UltimaVersion.html y que los clientes le hagan GET? Si cambia haces un alert. Así cachean, cuando la modifiques cambias la url para evitar cachear y que se actualice:

<?php echo "<img src='example.com/UltimaVersion.html?'".$VERSION.">"; ?>

Mientras el valor de $VERSION no cambie, no recibirás peticiones más de una vez a ella porque se cachea el archivo.

Podrías meter dentro del hexadecimal de la imagen tu código javascript raw, fetchearlo y extraerlo. Es una técnica conocida para esconder exploits escritos en js.
https://blog.malwarebytes.com/threat-analysis/2019/12/new-evasion-techniques-found-in-web-skimmers/amp/

Leguim

Estaba pensando en hacerlo con una consulta SQL,
no se si se podrá, que dicha consulta diga de agregar una notificación a todos los usuarios registros en lugar de usar un for en php, no se si será el mismo gasto la verdad...

[u]nsigned

#5
Cita de: MiguelCanellas en 16 Junio 2020, 00:16 AM
Estaba pensando en hacerlo con una consulta SQL,
no se si se podrá, que dicha consulta diga de agregar una notificación a todos los usuarios registros en lugar de usar un for en php, no se si será el mismo gasto la verdad...

Hacelo de forma inversa. Crea un tabla donde guardas las notificaciones a medida que los usuarios son notificados...

Así cuando un user entra, revisas en esa tabla si ya se notifico de X versión, si lo está no haces nada, si no lo esta, le mostras la notificación y luego creas el registro. entonces tu tabla no tendría un millón de registro de entrada, sino que se iría poblando a medida que van entrando los usuarios y solo se notificará a los usuarios activos.

Todo esto es en teoria, pero en un escenario real yo no usaría una base SQL para eso, mejor usaria una base como Redis que es mucho más eficiente y rápida y es el estándar de la industria para el realtime o cosas que necesiten mucha velocidad y el menor consumo manejando un volumen gigante de datos. Trabaja sobre la memoria ram, pero si tenes un sistema con un millón de usuarios supongo que tendrás un servidor con sobrados GB's de ram....  :silbar:

Otra forma que se me ocurre, un poco mas cutre, seria usar algun servicio de archivos estáticos con un cdn global, como Github.

Simplemente tendrías que crear un archivo json e ir metiendo ahí tus versiones. Entonces sería el cliente el que tendría que consultar el contenido de dicho archivo. Asi podes sacar toda la lógica de negocio de tu propia infraestructura, y a github un millón de peticiones no le hacen ni cosquillas...

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

@XSStringManolo


[u]nsigned

Cita de: @XSStringManolo en 16 Junio 2020, 22:53 PM
Probastes lo de github? Igual chapan con un 301

Con la version 'raw' no debería tener problemas.

Código (bash) [Seleccionar]
curl -H "Accept: application/json" https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json

No hay atajo ante la duda, el misterio se hace aquí...
Se hace carne en cada uno, el misterio es existir!

@XSStringManolo

[quote author=nsigned link=topic=505329.msg2223808#msg2223808 date=1592365395]
Con la version 'raw' no debería tener problemas.

Código (bash) [Seleccionar]
curl -H "Accept: application/json" https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json
[/quote]

Ostraaas, y se puede fetchear cross origen. Pensaba que hacían lo mismo que con los .js a pesar de ser json.

Código (javascript) [Seleccionar]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<body>
<script>
function PeticionGET(url, callback) {
 var peticion = new XMLHttpRequest();
 peticion.open("GET", url , true);
 peticion.send();
 peticion.onreadystatechange = function() {
   if (peticion.readyState == 4) {
     if (peticion.status == 0 || peticion.status == 200) {
       callback(peticion.responseText);
     }
   }
 }      
}

PeticionGET("https://raw.githubusercontent.com/LearnWebCode/json-example/master/animals-1.json", function(respuesta) {
 try {
  document.write(JSON.stringify(respuesta));
 } catch (err) {
   alert(err);
 }
});
</script>
</body>
</html>