diff --git a/python/Modulo-11-Herramientas-Nerve/104-cli-bridge/reto.md b/python/Modulo-11-Herramientas-Nerve/104-cli-bridge/reto.md new file mode 100644 index 0000000..acc0615 --- /dev/null +++ b/python/Modulo-11-Herramientas-Nerve/104-cli-bridge/reto.md @@ -0,0 +1,30 @@ +# Reto 104: El Recepcionista en Acción 🤖 + +Ya sabemos que `nerve bridge` funciona como un puente que conecta el mundo exterior (como una página web vía WebSockets en el puerto `50506`) con el mundo interno de Nerve (el Hub local en `50505`). + +Tu misión en este nivel es crear el script trabajador que recibirá esos mensajes traducidos y procesará la información. + +## 📝 Instrucciones + +Crea un archivo llamado `reto.py` en esta misma carpeta y escribe código que haga lo siguiente: + +1. Importa las herramientas necesarias de `nerve` (`NexusClient`) y `time`. +2. Crea una instancia de `NexusClient` llamada `trabajador`. +3. Conecta al trabajador a la red de Nerve bajo el nombre `"procesador_web"`. +4. Define una función callback llamada `procesar_datos` que acepte un parámetro (los datos del mensaje). Dentro de la función: + - Imprime el mensaje: `"¡Mensaje recibido del puente web!"`. + - Imprime el contenido de los datos. +5. Registra el callback llamando a `.listen(procesar_datos)` en tu cliente `trabajador`. +6. Crea un bucle infinito que mantenga el script en ejecución para que el trabajador no se retire antes de recibir trabajo (utiliza `time.sleep(1)`). + +## 🛑 Reglas Estrictas +- El archivo DEBE llamarse `reto.py`. +- Debes conectarte a la red bajo el nombre `"procesador_web"`. +- Debes usar la función `.listen(procesar_datos)`. + +## 🎯 Resultado Esperado en Terminal +Al arrancar el Hub (`nerve start`), el puente (`nerve bridge`) y ejecutar tu `reto.py`, cuando un cliente web envíe un mensaje a la red, tu terminal del reto debería imprimir: +```text +¡Mensaje recibido del puente web! +Contenido: ... +``` diff --git a/python/Modulo-12-Arquitectura-Avanzada/111-auto-reconexion/reto.py b/python/Modulo-12-Arquitectura-Avanzada/111-auto-reconexion/reto.py new file mode 100644 index 0000000..8128454 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/111-auto-reconexion/reto.py @@ -0,0 +1,12 @@ +from nerve.core import NexusClient + +def leer_transmision(payload): + print(f"[COMUNICADO]: {payload}") + +def alerta_red_restablecida(): + print("⚠️ ENLACE DE COMUNICACIONES RESTABLECIDO ⚠️") + +if __name__ == "__main__": + cliente = NexusClient() + cliente.connect("monitor_alpha") + cliente.listen(on_payload=leer_transmision, on_reconnect=alerta_red_restablecida) diff --git a/python/Modulo-12-Arquitectura-Avanzada/112-heartbeats/reto.py b/python/Modulo-12-Arquitectura-Avanzada/112-heartbeats/reto.py new file mode 100644 index 0000000..4a37a41 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/112-heartbeats/reto.py @@ -0,0 +1,17 @@ +from nerve.core import NexusHub, NexusClient +import time + +if __name__ == "__main__": + maquina_central = NexusHub(heartbeat_interval=1.5) + maquina_central.start() + print("🏥 Maquina Central encendida: Monitor cardiaco cada 1.5s") + + androide_azul = NexusClient() + androide_azul.connect("androide_azul") + print("🤖 Androide Azul conectado.") + + time.sleep(4) + + androide_azul.disconnect() + maquina_central.stop() + print("🛑 Desconexion exitosa.") diff --git a/python/Modulo-12-Arquitectura-Avanzada/113-multiprocessing/reto.py b/python/Modulo-12-Arquitectura-Avanzada/113-multiprocessing/reto.py new file mode 100644 index 0000000..907d804 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/113-multiprocessing/reto.py @@ -0,0 +1,20 @@ +import nerve +import multiprocessing +import time + +def cargar_y_disparar(): + print("Cargando cañon laser...") + time.sleep(4) + print("💥 ¡BOOM! Nave destruida.") + +if __name__ == '__main__': + clon1 = multiprocessing.Process(target=cargar_y_disparar) + clon2 = multiprocessing.Process(target=cargar_y_disparar) + + clon1.start() + clon2.start() + + clon1.join() + clon2.join() + + print("🏆 Base salvada, buen trabajo comandante.") diff --git a/python/Modulo-12-Arquitectura-Avanzada/114-asyncio-bridge/reto.py b/python/Modulo-12-Arquitectura-Avanzada/114-asyncio-bridge/reto.py new file mode 100644 index 0000000..1d93da4 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/114-asyncio-bridge/reto.py @@ -0,0 +1,11 @@ +from nerve.core import NexusHub +from nerve.bridge import NerveBridge + +if __name__ == "__main__": + hub = NexusHub() + hub.start() + + print("🌀 Abriendo portal interdimensional...") + + puente = NerveBridge(host="127.0.0.1", port=8080) + puente.start() diff --git a/python/Modulo-12-Arquitectura-Avanzada/115-manejo-estado/reto.py b/python/Modulo-12-Arquitectura-Avanzada/115-manejo-estado/reto.py new file mode 100644 index 0000000..76193a9 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/115-manejo-estado/reto.py @@ -0,0 +1,34 @@ +from nerve.core import NexusHub, NexusClient +import time + +estado_tamagotchi = { + "hambre": 50, + "felicidad": 50 +} + +def procesar_comando(payload): + if payload == "alimentar": + estado_tamagotchi["hambre"] -= 10 + print(f"🍕 Tamagotchi comio. Hambre actual: {estado_tamagotchi['hambre']}") + elif payload == "jugar": + estado_tamagotchi["felicidad"] += 10 + print(f"⚽ Tamagotchi jugo. Felicidad actual: {estado_tamagotchi['felicidad']}") + +if __name__ == "__main__": + hub = NexusHub() + hub.start() + + cliente = NexusClient() + cliente.connect("tamagotchi") + cliente.listen(on_payload=procesar_comando) + + time.sleep(1) + cliente.send(to="tamagotchi", payload="alimentar") + time.sleep(1) + cliente.send(to="tamagotchi", payload="alimentar") + time.sleep(1) + cliente.send(to="tamagotchi", payload="jugar") + time.sleep(1) + + cliente.disconnect() + hub.stop() diff --git a/python/Modulo-12-Arquitectura-Avanzada/116-pipelines-datos/reto.py b/python/Modulo-12-Arquitectura-Avanzada/116-pipelines-datos/reto.py new file mode 100644 index 0000000..4d89712 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/116-pipelines-datos/reto.py @@ -0,0 +1,36 @@ +from nerve.core import NexusHub, NexusClient +import time + +if __name__ == "__main__": + hub = NexusHub() + hub.start() + + amasadora = NexusClient() + horno = NexusClient() + vitrina = NexusClient() + + amasadora.connect("amasadora") + horno.connect("horno") + vitrina.connect("vitrina") + + def trabajo_horno(payload): + print(f"🔥 [HORNO] Recibi {payload['estado']}. Horneando a 200 grados...") + payload["estado"] = "Pan Horneado" + horno.send(to="vitrina", payload=payload) + + def trabajo_vitrina(payload): + print(f"🍞 [VITRINA] ¡Pan fresco listo para la venta! {payload}") + + horno.listen(on_payload=trabajo_horno) + vitrina.listen(on_payload=trabajo_vitrina) + + masa = {"ingredientes": "Harina, Agua y Levadura", "estado": "Masa Cruda"} + print("🥣 [AMASADORA] Mezclando ingredientes y enviando masa al horno...") + amasadora.send(to="horno", payload=masa) + + time.sleep(3) + + amasadora.disconnect() + horno.disconnect() + vitrina.disconnect() + hub.stop() diff --git a/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/cocina.py b/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/cocina.py new file mode 100644 index 0000000..e69de29 diff --git a/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/mesero.py b/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/mesero.py new file mode 100644 index 0000000..e69de29 diff --git a/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/reto.py b/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/reto.py new file mode 100644 index 0000000..6df2713 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/117-mensajeria-robusta/reto.py @@ -0,0 +1,48 @@ +from nerve.core import NexusHub, NexusClient +import time + +ordenes_pendientes = {} + +def trabajo_cocina(payload): + try: + id_orden = payload["id_orden"] + platillo = payload["platillo"] + + print(f"🍳 [COCINA] Preparando: {platillo} (Orden {id_orden})...") + print(f"🔔 [COCINA] ¡Orden {id_orden} terminada! Avisando al mesero...") + + ack = {"id_orden": id_orden, "status": "LISTO"} + cocina.send(to="mesero", payload=ack) + except Exception as e: + print(f"Error procesando orden en cocina: {e}") + +def trabajo_mesero(payload): + if payload.get("status") == "LISTO": + id_orden = payload.get("id_orden") + if id_orden in ordenes_pendientes: + platillo = ordenes_pendientes[id_orden] + print(f"🏃 [MESERO] Recibí ACK. ¡Llevando {platillo} a la mesa! Órdenes pendientes: {len(ordenes_pendientes) - 1}") + del ordenes_pendientes[id_orden] + +if __name__ == "__main__": + hub = NexusHub() + hub.start() + + mesero = NexusClient() + cocina = NexusClient() + + mesero.connect("mesero") + cocina.connect("cocina") + + cocina.listen(on_payload=trabajo_cocina) + mesero.listen(on_payload=trabajo_mesero) + + ordenes_pendientes[42] = "Hamburguesa con Papas" + print("📝 [MESERO] Orden 42 anotada. Enviando a cocina...") + mesero.send(to="cocina", payload={"id_orden": 42, "platillo": "Hamburguesa con Papas"}) + + time.sleep(3) + + mesero.disconnect() + cocina.disconnect() + hub.stop() diff --git a/python/Modulo-12-Arquitectura-Avanzada/118-restricciones-rate-limit/reto.py b/python/Modulo-12-Arquitectura-Avanzada/118-restricciones-rate-limit/reto.py new file mode 100644 index 0000000..bc102e2 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/118-restricciones-rate-limit/reto.py @@ -0,0 +1,26 @@ +from nerve.core import NexusHub, NexusClient +import time + +def escuchar_cajero(payload): + print(f"🏦 [CAJERO] Procesando petición: {payload}") + +if __name__ == "__main__": + hub = NexusHub(rate_limit_messages_per_sec=1) + hub.start() + + cajero = NexusClient() + cajero.connect("cajero") + cajero.listen(on_payload=escuchar_cajero) + + cliente_impaciente = NexusClient() + cliente_impaciente.connect("cliente_impaciente") + + for i in range(5): + cliente_impaciente.send(to="cajero", payload={"peticion": "¡Quiero mi dinero ya!"}) + time.sleep(0.2) + + time.sleep(2) + + cliente_impaciente.disconnect() + cajero.disconnect() + hub.stop() diff --git a/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/nerve.config b/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/nerve.config new file mode 100644 index 0000000..6ea91e9 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/nerve.config @@ -0,0 +1 @@ +port=7777 diff --git a/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/reto.py b/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/reto.py new file mode 100644 index 0000000..7bbdd24 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/119-arquitectura-produccion/reto.py @@ -0,0 +1,19 @@ +from nerve.core import NexusClient +import time + +def mensaje_torre(payload): + print(f"🗼 [TORRE] Mensaje recibido: {payload}") + +if __name__ == "__main__": + torre_control = NexusClient() + torre_control.connect("torre_control") + torre_control.listen(on_payload=mensaje_torre) + + avion_01 = NexusClient() + avion_01.connect("avion_01") + avion_01.send(to="torre_control", payload={"mensaje": "Solicito permiso para aterrizar"}) + + time.sleep(2) + + torre_control.disconnect() + avion_01.disconnect() diff --git a/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/alarma.py b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/alarma.py new file mode 100644 index 0000000..7c42470 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/alarma.py @@ -0,0 +1,12 @@ +from nerve import NexusClient + +def procesar_alarma(payload, sender): + tamano = payload.get("tamano", 0) + print(f"🚨 ¡PELIGRO! Asteroide gigante detectado de {tamano} metros 🚨") + +if __name__ == "__main__": + print("--- INICIANDO SISTEMA DE ALARMA ---") + print("Esperando alertas de asteroides...") + alarma = NexusClient(name="alarma") + alarma.connect() + alarma.listen(procesar_alarma) diff --git a/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/filtro.py b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/filtro.py new file mode 100644 index 0000000..c744dbe --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/filtro.py @@ -0,0 +1,14 @@ +from nerve import NexusClient + +def procesar_asteroide(payload, sender): + tamano = payload.get("tamano", 0) + if tamano < 50: + print("Roca inofensiva.") + else: + # Enviar mensaje a alarma + filtro.send(to="alarma", payload={"tamano": tamano}) + +if __name__ == "__main__": + filtro = NexusClient(name="filtro") + filtro.connect() + filtro.listen(procesar_asteroide) diff --git a/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/radar.py b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/radar.py new file mode 100644 index 0000000..c4c0ec1 --- /dev/null +++ b/python/Modulo-12-Arquitectura-Avanzada/120-RETO-FINAL-DISTRIBUIDO/radar.py @@ -0,0 +1,12 @@ +from nerve import NexusClient +import time +import random + +if __name__ == "__main__": + cliente = NexusClient(name="radar") + cliente.connect() + + while True: + tamano = random.randint(1, 100) + cliente.broadcast({"tamano": tamano}) + time.sleep(1)