{"id":31960242,"url":"https://github.com/gabrieldiem/pedidos-rust","last_synced_at":"2026-07-22T05:35:30.242Z","repository":{"id":316573329,"uuid":"1006634322","full_name":"gabrieldiem/pedidos-rust","owner":"gabrieldiem","description":"Distribuited and resilient software system for food delivery for riders, customers and restaurants. Built primarily with the actor model of concurrency [1Q2025]","archived":false,"fork":false,"pushed_at":"2025-09-25T10:52:09.000Z","size":26106,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-22T05:35:09.247Z","etag":null,"topics":["actor-model","distributed-systems","rust","serde-json","tcp","udp"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabrieldiem.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-22T17:31:28.000Z","updated_at":"2025-09-25T10:52:13.000Z","dependencies_parsed_at":"2025-09-25T12:34:45.552Z","dependency_job_id":null,"html_url":"https://github.com/gabrieldiem/pedidos-rust","commit_stats":null,"previous_names":["gabrieldiem/pedidos-rust"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gabrieldiem/pedidos-rust","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldiem%2Fpedidos-rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldiem%2Fpedidos-rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldiem%2Fpedidos-rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldiem%2Fpedidos-rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabrieldiem","download_url":"https://codeload.github.com/gabrieldiem/pedidos-rust/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabrieldiem%2Fpedidos-rust/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35750066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-22T02:00:06.236Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actor-model","distributed-systems","rust","serde-json","tcp","udp"],"created_at":"2025-10-14T15:57:07.429Z","updated_at":"2026-07-22T05:35:30.225Z","avatar_url":"https://github.com/gabrieldiem.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/YmMajyCa)\n\nPara información sobre setup del proyecto ver el documento [`./docs/contribute.md`](./docs/contribute.md).\n\n---\n\n# PedidosRust - Grupo MutexMasters\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/pedidos_rust_logo.png\" alt=\"PedidosRust logo\" height=\"300px\"\u003e\n\u003c/p\u003e\n\nPedidosRust es una nueva aplicación para conectar restaurantes, repartidores y comensales. Gracias a su innovadora implementación distribuida, permitirá reducir los costos y apuntar a ser líder en el mercado.\n\nLos comensales podrán solicitar un pedido a un restaurante, los restaurantes notifican cuando el pedido está listo, y los repartidores buscan pedidos cercanos y los entregan.\n\n### Integrantes\n\n| Nombre                            | Padrón | Email              |\n| --------------------              | ------ | -----------------  |\n| Avalos, Victoria                  | 108434 | vavalos@fi.uba.ar  |\n| Chacón, Ignacio                   | 108298 | ichacons@fi.uba.ar |\n| Diem, Walter Gabriel              | 105618 | wdiem@fi.uba.ar    |\n| Funes Cabanelas, Nicolás Ezequiel | 109830 | nfunes@fi.uba.ar   |\n\n---\n\n### Table of contents\n\n1. [Aplicaciones](#Aplicaciones)\n1. [Estructura del repositorio y sistema](#Estructura-del-repositorio-y-sistema)\n1. [Uso](#Uso)\n1. [Diagrama de funcionamiento general de protocolo](#Diagrama-de-funcionamiento-general-de-protocolo)\n1. [Topología real física](#Topología-real-física)\n1. [Diagrama de elecciones](#Diagrama-de-elecciones)\n1. [Data ring](#Data-ring)\n1. [First connection probing](#First-connection-probing)\n1. [Diseño](#Diseño)\n   1. [Pedidos-rust](#Pedidos-rust)\n   1. [Customer](#Customer)\n   1. [Rider](#Rider)\n   1. [Restaurant](#Restaurant)\n   1. [PaymentSystem](#PaymentSystem)\n1. [Mensajes](#Mensajes)\n1. [Resiliencia distribuida](#Resiliencia-distribuida)\n\n## Aplicaciones\n\nHay 5 aplicaciones ejecutables, las cuales son referenciados por sus nombres en inglés (por consistencia con la convención de programación):\n\n- Requeridas por la consigna (4 apps): comensales (`customers`), restaurantes (`restaurants`), repartidores (`riders`), gateway de pagos (`payment-system`).\n\n- Adicional (1 app): aplicación para simplificar el manejo de mensajes entre actores llamada `pedidos-rust`.\n\n## Estructura del repositorio y sistema\n\nEl root del repositorio es un workspace que contiene los proyectos (ejecutables binarios separados, cada uno con su `Cargo.toml`) y el código en común:\n\n```\n.\n├── common          Código compartido entre aplicaciones y protocolo\n├── customer        Project del customer\n├── docs\n├── payment-system         Project del payment gateway\n├── pedidos-rust    Project del pedidos-rust\n├── restaurant      Project del restaurant\n├── rider           Project del rider\n└── Cargo.toml      Configuración del workspace\n```\n\n## Uso\n\nSe deja las instrucciones para ejecutar las diversas apps:\n\n**Customer:**\n\n```bash\ncargo run -p customer\n```\n\n**Payment-System:**\n\n```bash\ncargo run -p payment-system\n```\n\n**Pedidos-rust:**\n\n```bash\ncargo run -p pedidos-rust\n```\n\n**Restaurant:**\n\n```bash\ncargo run -p restaurant\n```\n\n**Rider:**\n\n```bash\ncargo run -p rider\n```\n\n---\n\n## Diagrama de funcionamiento general de protocolo\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/protocol.png\" alt=\"Protocol diagram\" height=\"500px\"\u003e\n\u003c/p\u003e\n\n## Topología real física\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/physical_network_topology.png\" alt=\"Physical Network topology diagram\" height=\"500px\"\u003e\n\u003c/p\u003e\n\n## Diagrama de elecciones\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/elections.png\" alt=\"Elections diagram\" height=\"600px\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/elections_colors.png\" alt=\"Elections colors diagram\" height=\"250px\"\u003e\n\u003c/p\u003e\n\n## Data ring\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/data_ring.png\" alt=\"Data ring diagram\" height=\"600px\"\u003e\n\u003c/p\u003e\n\n## First connection probing\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/first_connection_probing.png\" alt=\"First connection probing diagram\" height=\"500px\"\u003e\n\u003c/p\u003e\n\n## Diseño\n\n### \u003cins\u003eApplication level\u003c/ins\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/c4_app_level.png\" alt=\"PedidosRust logo\" height=\"800px\"\u003e\n\u003c/p\u003e\n\n### \u003cins\u003ePedidos-rust\u003c/ins\u003e\n\n#### Finalidad\n\nAplicación que es un servidor distribuido que recibe pedidos de los customers, autoriza los pagos con el payment gateway, coordina con los restaurantes la preparación del pedido y una vez listo le ofrece los pedidos a los riders más cercanos para que realicen el delivery y le da la asignación final al que acepte primero, mantiene actualizado al customer del estado del pedido en todo momento y efectiviza el cobro del pedido una vez se confirma que el delivery fue entregado al customer.\n\n#### Estado interno\n\nLa estructura de la app consta de una entidad `Server` que es dueña del welcomming socket de TCP (usado de manera asíncrona para recibir conexiones), por cada conexión recibida de tiene un actor `ClientConnection` y estos pueden solicitar funcionalidades que requieren visibilidad de todas las conexiones del actor `ConnectionManager`. Todo el modelado de actores apalanca los handlers asíncronos para la concurrencia.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/pedidos_rust_app.png\" alt=\"pedidos_rust_app\" height=\"500px\"\u003e\n\u003c/p\u003e\n\nEn una situación donde hay sólo 1 customer y 1 rider conectados al PedidosRust, los actores presentes serían:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/pedidos_rust_app_1_customer_1_rider.png\" alt=\"pedidos_rust_app_1_customer_1_rider\" height=\"400px\"\u003e\n\u003c/p\u003e\n\n**Variables internas de `Server`:**\n\n```rust\npub struct Server {\n    logger: Logger,\n    connection_manager: Addr\u003cConnectionManager\u003e,\n}\n```\n\n**Variables internas de `ClientConnection`:**\n\n```rust\npub struct ClientConnection {\n    pub tcp_sender: Addr\u003cTcpSender\u003e,\n    pub logger: Logger,\n    pub id: u32,\n    pub connection_manager: Addr\u003cConnectionManager\u003e,\n    pub peer_location: Option\u003cLocation\u003e,\n}\n```\n\n**Variables internas de `ConnectionManager`:**\n\n```rust\npub struct ConnectionManager {\n    pub logger: Logger,\n    pub riders: HashMap\u003cRiderId, Addr\u003cClientConnection\u003e\u003e,\n    pub customers: HashMap\u003cCustomerId, CustomerData\u003e,\n    pub orders_in_process: HashMap\u003cRiderId, CustomerId\u003e,\n    pub pending_delivery_requests: VecDeque\u003cMessage\u003e,\n}\n```\n\n### \u003cins\u003eCustomer\u003c/ins\u003e\n\n#### Finalidad\n\nAplicación que utiliza el customer para poder consultar los restaurantes donde puede hacer un pedido, elegir un restaurante para realizarle un pedido y recibir notificaciones (push notifications) de cómo progresa el pedido a medida que se avanza en el proceso de delivery.\n\nProceso de delivery:\n\n1. Pago autorizado\n1. Restaurante está preparando el pedido\n1. Pedido está listo\n1. Rider 1234 está llevando el pedido\n1. Pedido entregado\n\n#### Estado interno\n\nEstá modelado como un actor con handlers asíncronos para manejar la concurrencia. Utiliza TCP para la comunicación por la red.\n\n**Variables internas de `Customer`:**\n\n```rust\nstruct Customer {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n    location: Location,\n}\n```\n\n### \u003cins\u003eRider\u003c/ins\u003e\n\n#### Finalidad\n\nAplicación que utiliza el rider para actualizar su ubicación al PedidosRust, recibir ofertas de deliveries (se le dice _oferta_ porque PedidosRust ofrece a los riders la posibilidad de realizar un delivery, el rider puede aceptar o no, y PedidosRust confirma si el rider fue elegido como el que efectivamente va a realizar el envío), ir a retirar el pedido del restaurante para llevarle al customer, y viajar hasta la ubicación del customer para realizar la entrega del pedido.\n\n#### Estado interno\n\nEstá modelado como un actor con handlers asíncronos para manejar la concurrencia. Utiliza TCP para la comunicación por la red.\n\n**Variables internas de `Rider`:**\n\n```rust\nstruct Rider {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n    location: Location,\n    customer_location: Option\u003cLocation\u003e,\n    busy: bool,\n}\n```\n\n### \u003cins\u003eRestaurant\u003c/ins\u003e\n\n#### Finalidad\n\nAplicación que utilizan los restaurantes para recibir pedidos de los comensales, notificar cuando los comienza a preparar y cuando el pedido está listo para ser retirado por el rider. El restaurante puede cancelar un pedido por falta de stock con una probabilidad aleatoria del 10% (simulando que el stock se agota en el momento de la preparación).\n\n#### Estado interno\n\nEstá modelado con tareas asíncronas de tokio para manejar los pedidos concurrentemente, asignando cada pedido a una tarea asíncrona.\nSe comunica con PedidosRust mediante TCP para recibir los pedidos y contestar.\n\n**Variables internas de `Restaurant`:**\n\n```rust\nstruct Restaurant {\n    location: Location,\n   name: String\n}\n```\n\n### \u003cins\u003ePaymentSystem\u003c/ins\u003e\n\n#### Finalidad\n\nAplicación que autoriza y efectiviza un cobro. El flujo de un pago consta de dos fases secuenciales: primero se autoriza el pago y luego se efectiviza el cobro. La primera fase (la autorización del pago) puede fallar debido a un rechazo. Pero la efectivización del mismo (debitar el dinero) se realiza sin posibilidad de falla.\n\nSe entiende al payment gateway como un servicio externo de terceros, como podría ser Visa o MasterCard.\n\n#### Estado interno\n\nEstá modelado con tareas asíncronas para manejar la concurrencia. Utiliza TCP para la comunicación por la red.\n\n**Variables internas de `PaymentSystem`:**\n\n```rust\nstruct PaymentSystem {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n}\n```\n\n## Mensajes\n\nSe muestra a continuación un diagrama de secuencia que representa el flujo de mensajes entre las aplicaciones en un caso de uso exitoso donde un cliente realiza un pedido a un restaurante.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/caso_feliz.png\" alt=\"Diagrama de Secuencia\" height=\"700px\"\u003e\n\u003c/p\u003e\n\nSe presentan los mensajes que intercambian las aplicaciones para poder llevar a cabo el envío de pedidos de manera efectiva y resiliente:\n\n| Mensaje                   | Emisor                 | Receptor               | Payload                                                              | Propósito                                                                                                           |\n|---------------------------| ---------------------- | ---------------------- |----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------|\n| Get Restaurants           | Customer👨🏻‍🦱             | PedidosRust🦀          | `customer_location: Location` (`Location` son dos enteros `x` e `y`) | Solicitar restaurantes para realizar un pedido                                                                      |\n| Restaurants               | PedidosRust🦀          | Customer👨🏻‍🦱             | `data: String`                                                       | Comunicar los restaurantes disponibles                                                                              |\n| Order                     | Customer👨🏻‍🦱             | PedidosRust🦀          | `restaurant: String, amount: f64`                                    | Realizar un pedido                                                                                                  |\n| Push Notification         | PedidosRust🦀          | Customer👨🏻‍🦱             | `notification_msg: String`                                           | Envío de información para seguimiento en tiempo real del estado del pedido                                          |\n| Location Update           | Rider🛵                | PedidosRust🦀          | `new_location: Location`                                             | Informar nueva ubicación                                                                                            |\n| Delivery Offer            | PedidosRust🦀          | Rider🛵                | `customer_id: u32, customer_location: Location`                      | Ofrecer un pedido al rider que puede aceptar o no                                                                   |\n| Delivery Offer Accepted   | Rider🛵                | PedidosRust🦀          | `customer_id: u32, customer_location: Location`                      | Aceptar el ofrecimiento de pedido                                                                                   |\n| Delivery Offer Confirmed  | PedidosRust🦀          | Rider🛵                | `customer_id: u32, customer_location: Location`                      | Confirmar que el rider es el elegido para hacer el delivery                                                         |\n| Picked Up From Restaurant | Rider🛵                | PedidosRust🦀          | `rider_id: u32`                                                      | Informar que el rider ya hizo el retiro de la orden del restaurante                                                 |\n| Delivery Done             | Rider🛵                | PedidosRust🦀          | `rider_id: u32`                                                      | Informar que el rider llegó a la ubicación del customer y entregó el pedido                                         |\n| Finish Delivery           | PedidosRust🦀          | Customer👨🏻‍🦱             |                                                                      | Realizar última actualización del pedido para marcar que se completó el mismo, y que el cliente pueda realizar otro |\n| Authorize Payment         | PedidosRust🦀          | Payment 💲             | `customer_id: u32, amount: f64`                                      | Solicitar la autorización del pago                                                                                  |\n| Payment Authorized        | Payment 💲             | PedidosRust🦀          | `customer_id: u32, amount: f64`                                      | Informar que el pago se autorizó exitosamente                                                                       |\n| Payment Denied            | Payment 💲             | PedidosRust🦀          | `customer_id: u32, amount: f64`                                      | Informar que el pago no se pudo autorizar                                                                           |\n| Execute Payment           | PedidosRust🦀          | Payment 💲             | `customer_id: u32, amount: f64`                                      | Debitar/efectivizar el pago                                                                                         |\n| Payment Executed          | Payment 💲             | PedidosRust🦀          | `customer_id: u32, amount: f64`                                      | Informar que el débito del pago fue exitoso                                                                         |\n Order In Progress         | Restaurant🍴           | PedidosRust🦀          | `customer_id: u32`                                                   | Comenzar a preparar orden                                                                                           |\n| Prepare Order             | PedidosRust🦀          | Restaurant🍴           | `customer_id: u32, price: u64`                                       | Preparar orden para un customer                                                                                     |\n| Order In Progress         | Restaurant🍴           | PedidosRust🦀          | `customer_id: u32`                                                   | Comenzar a preparar orden                                                                                           |\n| Inform Location           | Restaurant🍴           | PedidosRust🦀          | `restaurant_location: Location`                                      | Informar su posición a PedidosRust                                                                                  |\n| Order Ready               | Restaurant🍴           | PedidosRust🦀          | `customer_id: u32`                                                   | Informar que la orden está lista para ser retirada                                                                  |\n| Rider Assigned            | PedidosRust🦀          | Restaurant🍴           | `rider_id: u32`                                                      | Informar que el rider con ID proveída se encargará del envío                                                        |\n| Ping Request              | PedidosRust🦀          | Restaurant🍴 ó Rider🛵 |                                                                      | Consultar si el servicio está on-line mediante UDP                                                                  |\n| Ping Response             | Restaurant🍴 ó Rider🛵 | PedidosRust🦀          |                                                                      | Informar mediante UDP que el servicio sí está on-line       \n\nA nivel actores, todos poseen un automensaje `Start`, que se envía al comienzo de su ejecución, y `Stop` para marcar la finalización de su ejecución.\n\n## Resiliencia distribuida\n\nPara garantizar la resiliencia del sistema distribuido, se tomarán dos medidas: hacer que PedidosRust sea resistente a caídas, y para las demás aplicaciones, implementar un mecanismo de detección de desconexiones mediante un pinger.\n\n### PedidosRust resistente a caídas\n\nEn primer lugar, PedidosRust contará con réplicas del proceso original que estarán a la espera de que el proceso **coordinador** deje de poder responder a peticiones externas. Las réplicas se enterarán de esto mediande un mecanismo de *heartbeat* que envía mensajes periódicos al coordinador, utilizando UDP. Si el coordinador deja de responder a estos mensajes, las réplicas asumirán que el coordinador ha fallado.\nCuando una réplica detecte este suceso, llamará a elecciones internas mediante un *algoritmo de elección distribuido* de tipo *bully* entre las réplicas para decidir el próximo coordinador.\nTras la elección, el nuevo coordinador envía por UDP mensajes a todos los clientes de PedidosRust para que actualicen quién es el coordinados, y actualiza sus propias conexiones usando su estado interno.\n\nPor otro lado, con el objetivo de garantizar la integridad de datos entre las réplicas de `PedidosRust` y que todas posean el mismo estado interno para que cualquiera pueda pasar a ser el nuevo líder, se implementará un algoritmo de tipo *ring* para el pasaje de datos entre las réplicas. De esta forma, cuando el coordinador recibe un mensaje de una entidad, lo procesa y envía su actualización a la réplica siguiente en el anillo. Esta réplica procesa el mensaje y lo envía a la siguiente, y así sucesivamente hasta que el mensaje regresa al coordinador.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/algos_distribuidos.jpeg\" alt=\"algos_distribuidos\" height=\"500px\"\u003e\n\u003c/p\u003e\n\nLa solicitud de reconexión del nuevo líder luego de tomar el liderazgo se ve así:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/reconnection_mandate.png\" alt=\"reconnection_mandate\" height=\"600px\"\u003e\n\u003c/p\u003e\n\nLuego:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./docs/imgs/reconnection.png\" alt=\"reconnection\" height=\"600px\"\u003e\n\u003c/p\u003e\n\n#### Mecanismo de pinger\nPara garantizar la detección de desconexiones de riders y restaurantes, habrá un componente “pinger” dentro del ConnectionManager. Este módulo recibe como entrada los identificadores (puertos UDP) de todos los actores que está rastreando y les envía, cada 500 ms, un paquete “ping” a través de UDP, separando así el canal de verificación de la conexión del flujo principal de mensajes TCP. Si un mismo actor deja de responder durante cinco pings consecutivos, se asume su desconexión. Una vez marcado como desconectado, el actor entra en un periodo de gracia de 40 s durante el cual puede volver a reconectarse sin pérdida de estado. Transcurrido este plazo sin respuesta, el pinger notifica al ConnectionManager que la conexión es irrecuperable y se procede a limpiar recursos asociados y a informar al resto del sistema la indisponibilidad definitiva de ese actor.\n\n\n## Cambios realizados\n\nAlgunas consideraciones:\n- Las ofertas de delivery se envian al top N_RIDERS_TO_NOTIFY de repartidores más cercanos al restaurante. Esta es una constante que se puede configurar. De esta forma, se evita enviar mensajes innecesarios.\n- Al customer se le envían únicamente los restaurantes más cercanos a su ubicación, y no todos los restaurantes disponibles. Esto se hizo para simular a las aplicaciones de delivery reales.\n- Las instancias del servidor PedidosRust, además de los clientes, restaurantes y repartidores se encuentran en el archivo `config.json`, donde se pueden configurar sus ubicaciones y otros parámetros. \n\n## Uso\n\n#### Como ejecutar script.sh\n\nLa primera vez que se ejecuta, darle permisos con:\n```bash\nchmod +x script.sh\n```\nPara ejecutarlo:\n```bash\n./script.sh\n```\n\nSe deja las instrucciones para ejecutar las diversas apps:\n\n**Customer:**\n\n```bash\ncargo run -p customer \u003cid\u003e \n```\n\n**Payment-System:**\n\n```bash\ncargo run -p payment-system\n```\n\n**Pedidos-rust:**\n\n```bash\ncargo run -p pedidos-rust \u003cid\u003e\n```\n\n**Restaurant:**\n\n```bash\ncargo run -p restaurant \u003cid\u003e\n```\n\n**Rider:**\n\n```bash\ncargo run -p rider \u003cid\u003e\n```\n\n---\n\n\n#### Mensajes\n\n| Mensaje                      | Emisor                      | Receptor                    | Payload                                                                 | Propósito                                                                                                         |\n|-----------------------------|-----------------------------|-----------------------------|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|\n| Get Restaurants              | Customer👨🏻‍🦱                | PedidosRust🦀               | `customer_location: Location, new_customer: bool`                       | Solicitar restaurantes para realizar un pedido                                                                  |\n| Restaurants                  | PedidosRust🦀               | Customer👨🏻‍🦱                | `data: String`                                                          | Comunicar los restaurantes disponibles                                                                          |\n| Order                        | Customer👨🏻‍🦱                | PedidosRust🦀               | `restaurant: String, amount: f64`                                       | Realizar un pedido                                                                                              |\n| Push Notification            | PedidosRust🦀               | Customer👨🏻‍🦱                | `notification_msg: String`                                              | Enviar información de seguimiento del estado del pedido                                                        |\n| Location Update              | Rider🛵                     | PedidosRust🦀               | `new_location: Location`                                                | Informar nueva ubicación                                                                                        |\n| Delivery Offer               | PedidosRust🦀               | Rider🛵                     | `customer_id: u32, customer_location: Location`                         | Ofrecer un pedido al rider                                                                                      |\n| Delivery Offer Accepted      | Rider🛵                     | PedidosRust🦀               | `customer_id: u32`                                                      | Aceptar el ofrecimiento de pedido                                                                               |\n| Delivery Offer Confirmed     | PedidosRust🦀               | Rider🛵                     | `customer_id: u32, customer_location: Location`                         | Confirmar que el rider fue asignado                                                                             |\n| Picked Up From Restaurant    | Rider🛵                     | PedidosRust🦀               | `rider_id: u32`                                                         | El rider retiró el pedido del restaurante                                                                       |\n| Delivery Done                | Rider🛵                     | PedidosRust🦀               | `customer_id: u32`                                                      | El rider llegó al destino y entregó el pedido                                                                   |\n| Finish Delivery              | PedidosRust🦀               | Customer👨🏻‍🦱                | `reason: String`                                                        | Notificar que el pedido finalizó y habilitar uno nuevo                                                         |\n| Authorize Payment            | PedidosRust🦀               | Payment 💲                  | `customer_id: u32, amount: f64, restaurant_name: String`                | Solicitar autorización del pago                                                                                 |\n| Payment Authorized           | Payment 💲                  | PedidosRust🦀               | `customer_id: u32, amount: f64, restaurant_name: String`                | Confirmar que el pago fue autorizado                                                                            |\n| Payment Denied               | Payment 💲                  | PedidosRust🦀               | `customer_id: u32, amount: f64, restaurant_name: String`                | Informar rechazo del pago                                                                                       |\n| Execute Payment              | PedidosRust🦀               | Payment 💲                  | `customer_id: u32, amount: f64`                                         | Ejecutar el débito                                                                                              |\n| Payment Executed             | Payment 💲                  | PedidosRust🦀               | `customer_id: u32, amount: f64`                                         | Confirmar que el pago fue debitado                                                                             |\n| Prepare Order                | PedidosRust🦀               | Restaurant🍴                | `customer_id: u32, price: f64`                                          | Pedir al restaurante que prepare la orden                                                                      |\n| Order In Progress            | Restaurant🍴               | PedidosRust🦀               | `customer_id: u32`                                                      | Notificar que se está preparando la orden                                                                      |\n| Order Cancelled              | Restaurant🍴               | PedidosRust🦀               | `customer_id: u32`                                                      | Informar que la orden fue cancelada                                                                            |\n| Order Ready                  | Restaurant🍴               | PedidosRust🦀               | `customer_id: u32, restaurant_location: Location`                       | Notificar que la orden está lista                                                                              |\n| Inform Location              | Restaurant🍴               | PedidosRust🦀               | `restaurant_location: Location, restaurant_name: String`               | Enviar posición del restaurante                                                                                 |\n| Rider Assigned               | PedidosRust🦀               | Restaurant🍴                | `rider_id: u32`                                                         | Informar qué rider pasará a retirar                                                                             |\n| Ping Request                 | PedidosRust🦀               | Restaurant🍴 / Rider🛵       |                                                                         | Consultar estado de conexión (UDP)                                                                             |\n| Ping Response                | Restaurant🍴 / Rider🛵      | PedidosRust🦀               |                                                                         | Confirmar que está en línea (UDP)                                                                              |\n| Register Payment System      | Payment 💲 / Admin          | PedidosRust🦀               |                                                                         | Registrar subsistema de pago                                                                                    |\n| Rider Arrived At Customer    | Rider🛵                     | PedidosRust🦀               |                                                                         | Confirmar llegada a destino                                                                                     |\n| Is Connection Ready          | Cliente/Rider/Restaurante  | PedidosRust🦀               |                                                                         | Consultar si hay conexión con CM                                                                                |\n| Connection Available         | PedidosRust🦀               | Cliente/Rider/Restaurante  |                                                                         | Confirmar conexión activa                                                                                       |\n| Connection Not Available     | PedidosRust🦀               | Cliente/Rider/Restaurante  | `port: u32`                                                             | Indicar que no hay líder; opcionalmente el puerto conocido                                                     |\n| Connection Available For Peer| PedidosRust🦀               | Cliente/Rider/Restaurante  |                                                                         | Indicar que hay un peer disponible para conexión                                                               |\n| Election Call                | PedidosRust🦀                        | PedidosRust🦀                        |                                                                         | Mensaje de inicio de elección de líder                                                                         |\n| Election Ok                  | PedidosRust🦀                        | PedidosRust🦀                        |                                                          | Confirmación de participación en la elección                                                                   |\n| Election Coordinator         | PedidosRust🦀                        | PedidosRust🦀                        |                                                                         | Notificar nuevo coordinador                                                                                    |\n| Leader Query                 | PedidosRust🦀                   | PedidosRust🦀                |                                                                         | Consulta por el líder actual                                                                                   |\n| Leader Data                  | PedidosRust🦀                       | PedidosRust🦀                       | `port: u32`                                                             | Informar quién es el líder                                                                                      |\n| Update Customer Data         | Cliente                     | PedidosRust🦀               | `customer_id: u32, location: Location, maybe_amount: Option\u003cf64\u003e`       | Actualizar datos del cliente                                                                                    |\n| Update Restaurant Data       | Restaurante                 | PedidosRust🦀               | `restaurant_name: String, location: Location`                          | Actualizar datos del restaurante                                                                                |\n| Update Rider Data            | Rider                       | PedidosRust🦀               | `rider_id: u32, maybe_location: Option\u003cLocation\u003e`                      | Actualizar datos del rider                                                                                      |\n| Update OrderInProgress Data | PedidosRust🦀               | PedidosRust🦀                     | `customer_id: u32, location: Location, maybe_amount: Option\u003cf64\u003e, maybe_rider: Option\u003cu32\u003e` | Actualizar estado de orden en curso                                                                |\n| Remove OrderInProgress Data | PedidosRust🦀               | PedidosRust🦀                     | `customer_id: u32`                                                      | Eliminar seguimiento de orden                                                                                   |\n| Push Pending Delivery Request | PedidosRust🦀             | PedidosRust🦀                     | `customer_id: u32, location: Location, from_new_customer: bool`         | Agregar orden pendiente                                                                                         |\n| Pop Pending Delivery Request | PedidosRust🦀              | PedidosRust🦀                     |                                                                         | Extraer orden pendiente                                                                                         |\n| Reconnection Mandate | PedidosRust🦀              | Customer/Rider/Restaurante/Payment 💲                |  `new_leader_id: u32, new_leader_port: u32`                        | Informa quien es el nuevo lider al que se tienen que conectar las entidades\n\n\n## Connection Gateway\n\nConnectionGateway se encarga de recibir y reenviar mensajes que circulan entre peers a través del anillo. Su rol puede resumirse así:\n\n    - Acepta conexiones entrantes desde otros peers del ring.\n\n    - Escucha en un socket TCP para recibir mensajes serializados.\n\n    - Deserializa esos mensajes a través del tipo Message (definido en messages.rs).\n\n    - Los reenvía a través de un canal interno al ConnectionManager, que se encarga de su interpretación y posible propagación.\n\nEsto permite que:\n\n    -Los pedidos nuevos (NewPedido) puedan pasar de peer en peer hasta que uno los tome.\n\n    -Los mensajes de control (Ping, EntityDisconnected, etc.) se propaguen a lo largo del ring.\n\n    -Se mantenga la comunicación y coherencia del sistema distribuido sin depender de un único punto central.\n\n## Restaurant\n\nEl restaurante se refactorizó como actor, para facilitar la conexión como los demás actores al PedidosRust que sea líder mediante TcpConnector, y poder reconectarse.\nAhora todas las entidades se comunican con PedidosRust de la misma manera, utilizando TcpSender, y tienen nuevos campos de estado interno para manejar la conexión con la instancia Líder de PedidosRust.\nAdemás, al igual que las demás entidades, se configura mediante el archivo de configuración, el cual se accede mediante Configuration.\n\nEstado interno: \n\n```bash\npub struct Restaurant {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n    location: Location,\n    config: Configuration,\n    my_port: u32,\n    peer_port: u32,\n    tcp_connector: Addr\u003cTcpConnector\u003e,\n    name: String,\n    udp_socket: Arc\u003cUdpSocket\u003e,\n}\n```\n\n## Payment System\n\nEl payment system también se refactorizó como actor por el mismo motivo que el restaurante. El sistema de pagos es única por lo que no tiene entradas en el archivo de configuración, pero sí tiene un puerto para conectarse al PedidosRust que sea líder.\n\nEstado interno:\n```bash\npub struct PaymentSystem {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n    config: Configuration,\n    my_port: u32,\n    peer_port: u32,\n    tcp_connector: Addr\u003cTcpConnector\u003e,\n    udp_socket: Arc\u003cUdpSocket\u003e,\n}\n```\n\n## Rider\n\nEl rider ahora posee un option de la ubicación del customer. Cuando no está realizando ninguna entrega, este campo es None.\nAdemás, tiene el estado interno necesario para la conexión con el PedidosRust líder, al igual que las demás entidades.\n\nEstado interno:\n```bash\npub struct Rider {\ntcp_sender: Addr\u003cTcpSender\u003e,\nlogger: Logger,\nlocation: Location,\nconfig: Configuration,\nmy_port: u32,\npeer_port: u32,\ntcp_connector: Addr\u003cTcpConnector\u003e,\ncustomer_location: Option\u003cLocation\u003e,\nbusy: bool,\ncustomer_id: Option\u003cu32\u003e,\nudp_socket: Arc\u003cUdpSocket\u003e,\n}\n```\n\n## Customer\n\nEl customer tiene los mismos cambios que las demás entidades, ahora se conecta al PedidosRust líder mediante TcpSender y TcpConnector, y tiene un estado interno para manejar la conexión.\nEstado interno:\n```bash\npub struct Customer {\n    tcp_sender: Addr\u003cTcpSender\u003e,\n    logger: Logger,\n    location: Location,\n    config: Configuration,\n    my_port: u32,\n    peer_port: u32,\n    tcp_connector: Addr\u003cTcpConnector\u003e,\n    udp_socket: Arc\u003cUdpSocket\u003e,\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieldiem%2Fpedidos-rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabrieldiem%2Fpedidos-rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabrieldiem%2Fpedidos-rust/lists"}