Skip to content

joacoalvarez/Concurrentes-PedidosRust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

106 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Review Assignment Due Date

Integrantes

  • Joaquín Alvarez (107183)
  • Lucas Pérez Esnaola (107990)
  • Martín Osan (109179)

Como ejecutar la aplicacion

  • cargo run --bin restaurant
  • cargo run --bin coordinator

Diseño

alt text

PedidosRust es una aplicacion que conecta a comensales que quieren hacer su pedido con restaurants que lo realizan y repartidores que se lo envian. La aplicacion consiste de 4 aplicaciones distintas que coordinadas hacen al funcionamiento del programa.

Estas son:

Restaurant

Finalidad General

Esta aplicacion tiene como objetivo simular la actividad de un restaurant que toma pedidos y hace envios a sus comensales. Cada restaurant particular va a tener su propia instancia de la aplicacion corriendo independientemente. Su finalidad es recibir pedidos de los comensales, preparar los pedidos, y entregarlos a un repartidor que hace el envio al cliente. Tambien debe mantener informado al comensal del progreso de su pedido, y pueden cancelar pedidos aleatoriamente. Puede preparar varios pedidos concurrentemente, por lo que la cola de pedidos solo puede acceder un worker a la vez.

Estado Interno


RestaurantActor:
  id,
  name,
  orderQueue,
  position,
  workersPool, # Pool de workers que preparan pedidos concurrentemente
  activeOrders,
  tcpSender,
  tcpReceiver

Mensajes recibidos

  • OrderCreated(clientId, clientAddr): Este mensaje es enviado por un cordinador que avisa que un cliente quiere realizar un pedido en el restaurant. Recibe el ID del cliente y su direccion de red para poder comunicarle el seguimiento del pedido. Devuelve con el mensaje OrderConfirmed en caso de aceptar el pedido o OrderCanceled en caso de cancelar el pedido. El restaurant agrega el id del cliente a la cola de pedidos.
  • OrderCompleted(clientId): Este mensaje es enviado por un cordinador que avisa que un pedido llego correctamente al cliente. En este caso el restaurant borra el pedido de la lista de pedidos activos.
  • OrderFailed(clientID): Este mensaje es enviado por un coordinador que avisa que un pedido no ha llegado al cliente correctamente. En este caso el restaurant decide volver a iniciar el ciclo del pedido nuevamente.
  • Connected(coordAddr): Este mensaje es enviado por un coordinador para confirmar que el restaurant se conecto correctamente, recibiendo la direccion de red del coordinador lider.

Mensajes enviados

  • OrderConfirmed: Este mensaje es enviado al cliente cuando se confirma la aceptacion del pedido del cliente.
  • OrderCanceled: Este mensaje es enviado al cliente cuando su pedido fue cancelado.
  • PreparingOrder: Este mensaje es enviado al cliente cuando su pedido esta en preparacion.
  • OrderReadyToDeliver: Este mensaje es enviado al cliente cuando su pedido ya fue preparado y esta listo para ser retirado por un repartidor.
  • OrderReady(clientId, restaurantId): Este mensaje es enviado al coordinador cuando un pedido esta listo para ser retirado por un repartidor.
  • ConnectRestaurant(restaurantId): Este mensaje es enviado al coordinador para establecer una conexión con un coordinador en particular.

Protocolo de Comunicacion

El restaurante utilizara el protocolo de transporte TCP para la comunicacion con las demas aplicaciones. El protocolo de aplicacion sera en formato json, permitiendonos utilizar librerias que faciliten la serializacion y deserializacion de los mensajes. Por ejemplo, si se quiere enviar el mensaje OrderReady(clientId, restaurantId) se debera enviar el json: { "type": "OrderReady", "clientId": "0", "restaurantId": "5" }

Casos de interes

  • Caso Feliz: Un restaurante inicia la aplicacion, automaticamente se conecta con alguno de los coordinadores y le envia el mensaje ConnectRestaurant(restaurantId, position). El restaurante queda a la espera de recibir un pedido. Recibe el mensaje OrderCreated(clientId, clientAddr) de que un pedido fue recibido y lo acepta, insertandolo en la cola de pedidos y en el diccionario de pedidos activos. Envia el mensaje OrderConfirmed al cliente. El pool de workers se encarga de tomar el pedido de la cola de pedidos, y comenzar a prepararlo. Se envia el mensaje PreparingOrder al cliente. Cuando el pedido termina su preparacion, se le envia el mensaje OrderReady(clientId, restaurantId) al coordinador para que lo publique a los repartidores, y el mensaje OrderReadyToDeliver al cliente. El restaurant queda con el pedido activo en su diccionario hasta que le llega el mensaje OrderCompleted(clientId) y borra el pedido del diccionario de pedidos activos.
  • Caso Coordinador Caido: Si en algun momento de la ejecucion el coordinador finaliza su ejecucion, el restaurant va a buscar en su config el siguiente coordinador al que conectarse, le enviará el mensaje ConnectRestaurant(restaurantId) y quedará a la espera de recibir el mensaje Connected.
  • Caso Pedido Fallo: Si el repartidor que lleva un pedido del restaurant se desconecta por algun motivo, le llegara un mensaje del coordinador OrderFailed(clientId). En ese caso, el restaurant agregara el pedido nuevamente a la cola de pedidos para tratar de enviarlo nuevamente en el caso de que el comensal así lo prefiera.

Repartidor

Finalidad General

Esta aplicacion tiene como finalidad simular la actividad de un repartidor que toma pedidos ya listos de restaurants, pedalea hasta la ubicacion del restaurant para retirar el pedido, y luego pedalea hasta la direccion del cliente para entregarle el pedido. El repartidor debera mantener informado al cliente del estado de su envio, es decir, cuando el pedido esta en camino y cuando ya llego a su puerta. Tambien debera informar al coordinador que entrego el pedido correctamente. Cada repartidor va a tener una instancia de la aplicacion independiente, y a todos los repartidores cercanos le llegara un mensaje cuando haya un pedido para retirar de un restaurant. El primero que acepte el pedido se quedará con él.

Estado Interno


RiderActor:
  id,
  name,
  position,
  tcpSender,
  tcpReceiver

Mensajes Recibidos

  • NewDelivery(restaurantPos, clientPos, clientAddr): Este mensaje es enviado por el coordinador que avisa al repartidor que hay un pedido en un restaurant cercano listo para ser retirado. Recibe la posicion del restaurant, del cliente y la direccion de red del cliente para mantenerlo informado. Responde con el mensaje DeliveryAccepted en caso de querer aceptar la orden, si la rechaza no responde nada.
  • DeliveryConfirmed: Este mensaje es enviado por el coordinador en caso de que el pedido previamente aceptado haya sido asignado, es decir, que fue el primer repartidor en aceptar el pedido. En ese caso, el repartidor envia el mensaje OrderOnItsWay al cliente para avisarle que ya esta en camino.
  • DeliveryTaken: Este mensaje es enviado por el coordinador en caso de que el pedido haya sido asignado a otro repartidor. En ese caso el repartidor queda a la espera de recibir nuevas ordenes de delivery.
  • Connected(coordAddr): Este mensaje es enviado por un coordinador para confirmar que el repartidor se conecto correctamente, recibiendo la direccion de red del coordinador lider.

Mensajes Enviados:

  • DeliveryAccepted(riderId): Este mensaje es enviado al coordinador cuando el repartidor acepta realizar el delivery.
  • OrderOnItsWay: Este mensaje es enviado al cliente cuando el repartidor recibe la confirmacion de que el pedido le fue asignado, y comienza a realizar el pedido.
  • OrderArrived: Este mensaje es enviado al cliente cuando el repartidor llego a su domicilio con el pedido.
  • OrderDelivered(riderId): Este mensaje es enviado al coordinador para confirmarle que el pedido fue enviado con exito.
  • ConnectRider(riderId, position): Este mensaje es enviado al coordinador para avisar que el repartidor esta activo en la posicion indicada.

Protocolo de Comunicacion

El repartidor tambien utilizara el protocolo de transporte TCP para la comunicacion con las demas aplicaciones. El protocolo de aplicacion sera en formato json, permitiendonos utilizar librerias que faciliten la serializacion y deserializacion de los mensajes. Por ejemplo, si se quiere enviar el mensaje OrderDelivered(riderId) se debera enviar el json: { "type": "OrderDelivered", "riderId": "0" }

Casos de Interes

  • Caso Feliz: Un repartidor inicia la aplicacion, automaticamente se conecta con alguno de los coordinadores y le envia el mensaje ConnectRider(riderId, position). El repartidor queda a la espera de que le llegen solicitudes de delivery. Cuando le llega el mensaje NewDelivery(restaurantPos, clientPos, clientAddr), el repartidor lo acepta y responde con el mensaje DeliveryAccepted(riderId). Como fue el primero en aceptarlo, el coordinador le asigna el pedido. El repartidor recibe el mensaje DeliveryConfirmed y comienza el delivery. Primero pedalea hasta el restaurant (sleep), y cuando llega informa al cliente que esta en camino enviando el mensaje OrderOnItsWay. Luego pedalea hasta el domicilio del cliente (sleep) y cuando llega informa al cliente que llego a su domicilio enviando el mensaje OrderArrived. Por ultimo, le confirma al coordinador que entrego el pedido enviando OrderDelivered y comienza el ciclo nuevamente.
  • Caso Coordinador Caido: Si en algun momento de la ejecucion el coordinador finaliza su ejecucion, el repartidor va a intentar conectarse a otra replica del coordinador enviando el mensaje ConnectRider(riderId, position) y queda a la espera de recibir el mensaje Connected.
  • Caso Cliente Caido: Si una vez que tiene el pedido no puede comunicarse con el cliente por algun motivo, el repartidor simplemente sigue el flujo normal del pedido y espera poder comunicarse en persona. Entrega el pedido y avisa al coordinador como un caso normal.

Comensal/Cliente

Finalidad General

Esta aplicacion tiene como finalidad simular la actividad de un cliente que quiere realizar un pedido en un restaurant a domicilio. El cliente elegira un restaurante cercano a su posicion actual y realizara un pedido representado por un monto. El cliente espera que lo mantengan informado del estado de su pedido hasta que se lo entreguen en su domicilio. Su pedido puede ser rechazado por el gateway de pagos y debera comenzar el pedido nuevamente. Cada cliente tendra una instancia de la aplicacion independiente.

Estado Interno


ClientActor:
  id,
  position,
  tcpSender,
  tcpReceiver

Mensajes Recibidos

  • NearRestaurants(vec: restaurantId): Este mensaje es enviado por el coordinador cuando el cliente quiere realizar un pedido. Recibe un vector de ids de restaurantes, de los cuales el cliente elegira uno donde realizar el pedido. El cliente respondera con el mensaje PlaceOrder(clientId, restaurantId, amount) al coordinador para realizar el pedido.
  • OrderConfirmed: Este mensaje es enviado por el coordinador cuando tiene la confirmacion del restaurant y del gateway de pagos que el pedido fue recibido correctamente. El cliente queda a la espera de recibir los siguientes estados de su pedido.
  • OrderCanceled: Este mensaje es enviado por el coordinador cuando el restaurant cancelo su pedido. El cliente puede volver a realizar un nuevo pedido.
  • PaymentCanceled: Este mensaje es enviado por el coordinador cuando el gateway de pagos rechazo la tarjeta del cliente. El cliente puede volver a realizar un nuevo pedido.
  • PreparingOrder: Este mensaje es enviado por el restaurant cuando su pedido esta en preparacion. El cliente queda a la espera de recibir los siguientes estados de su pedido.
  • OrderReadyToDeliver: Este mensaje es enviado por el restaurant cuando el pedido ya fue preparado y esta listo para que un repartidor lo tome para realizar el envio. El cliente queda a la esperade recibir los siguientes estados de su pedido.
  • OrderOnItsWay: Este mensaje es enviado por el repartidor cuando esta en camino a su domicilio con el pedido. El cliente queda a la esperade recibir los siguientes estados de su pedido.
  • OrderArrived: Este mensaje es enviado por el repartidor cuando llego a su domicilio con el pedido. El cliente queda a la espera de que se efectue su pago en el gateway de pagos.
  • PaymentConfirmed: Este mensaje es enviado por el gateway de pagos cuando se efectua el pago de su pedido. El cliente puede volver a realizar un pedido.
  • Connected(coordAddr): Este mensaje es enviado por un coordinador para confirmar que el cliente se conecto correctamente, recibiendo la direccion de red del coordinador lider.

Mensajes Enviados

  • SearchRestaurants(position): Este mensaje es enviado al coordinador cuando el cliente quiere obtener los restaurantes cercanos para realizar un pedido.
  • PlaceOrder(clientId, restaurantId, amount): Este mensaje es enviado al coordinador cuando el cliente quiere realizar un pedido con el precio indicado y en el restaurant indicado.
  • ConnectClient(clientId): Este mensaje es enviado al coordinador para establecer una conexión con un coordinador en particular.

Protocolo de Comunicacion

El cliente tambien utilizara el protocolo de transporte TCP para la comunicacion con las demas aplicaciones. El protocolo de aplicacion sera en formato json, permitiendonos utilizar librerias que faciliten la serializacion y deserializacion de los mensajes. Por ejemplo, si se quiere enviar el mensaje SearchRestaurants(position) se debera enviar el json: { "type": "SearchRestaurants", "position": "(3,2)" }

Casos de Interes

  • Caso Feliz: Un cliente inicia la aplicacion, automaticamente se conecta con alguno de los coordinadores y le envia el mensaje ConnectClient(clientId, position). Luego, envia el mensaje SearchRestaurants(position) al coordinador para obtener los ids de los restaurants cercanos. El cliente elige uno al azar y envia el mensaje PlaceOrder(clientId, restaurantId, amount) al coordinador con el id del restaurant seleccionado y un precio tambien al azar. Luego el cliente recibe el mensaje OrderConfirmed, confirmandole que su tarjeta fue aceptada y el restaurante acepto su pedido. El cliente luego recibe los mensajes de PreparingOrder, OrderReadyToDeliver, OrderOnItsWay, OrderArrived y PaymentConfirmed, que representan el flujo correcto del pedido desde que se comienza a preparar al restaurant hasta que llega a su domicilio y se efectua el pago. El cliente esta en condiciones de realizar otro pedido.
  • Caso Coordinador Caido: Si en algun momento de la ejecucion el coordinador finaliza su ejecucion, el cliente va a intentar conectarse a otra replica del coordinador enviando el mensaje ConnectClient(clientId, position) y queda a la espera de recibir el mensaje Connected.
  • Caso Pedido Fallido: En caso de que haya algun problema con su pedido (por ejemplo el repartidor se desconecto), el cliente no se enterara y el pedido volvera a hacerse. Desde el punto de vista del cliente, el pedido tardara mas en llegar.

Coordinador

Finalidad General

Esta aplicacion tiene como finalidad hacer de intermediario entre los clientes, restaurants y repartidores. El coordinador conoce las posiciones de las entidades activas y esta encargado de mantener el estado de los pedidos, detectando si alguna entidad se desconecto.

Para evitar que sea un unico punto de falla, se decidio que el coordinador este replicado varias veces, permitiendo que el resto de entidades se conecten a un coordinador auxiliar si falla el lider. En el caso de que el lider falle, se implementará un algoritmo Bully para elegir a su sucesor. Para el caso de la Race Condition en la cual varios repartidores pueden querer tomar el mismo pedido, se implementará un Mutex centralizado.

Estado Interno


CoordinatorActor:
  id,
  activeOrders,
  tcpSender,
  tcpReceiver

Mensajes Recibidos

  • ConnectRider(riderId, position): Este mensaje es enviado al coordinador para avisar que el repartidor esta activo en la posicion indicada. Responde con el mensaje Connected(coordAddr), enviando la direccion de red del coordinador lider.
  • ConnectRestaurant(restaurantId): Este mensaje es enviado al coordinador para avisar que el restaurant esta activo en la posicion indicada. Responde con el mensaje Connected(coordAddr), enviando la direccion de red del coordinador lider.
  • ConnectClient(clientId, position): Este mensaje es enviado al coordinador para avisar que el cliente esta activo en la posicion indicada. Responde con el mensaje Connected(coordAddr), enviando la direccion de red del coordinador lider.
  • DisconnectClient(clientId): Este mensaje es enviado al coordinador para avisar que el cliente se desconecto.
  • OrderReady(clientId, restaurantId): Este mensaje es recibido cuando un pedido de un restaurant esta listo para ser retirado por un repartidor. Ante esto, el coordinador envia el mensaje NewDelivery(restaurantPos, clientPos, clientAddr) a los repartidores cercanos.
  • DeliveryAccepted(riderId): Este mensaje es enviado al coordinador cuando el repartidor acepta realizar el delivery. Responde con el mensaje DeliveryConfirmed o DeliveryTaken, en caso de asignar o no el pedido al repartidor.
  • OrderDelivered(riderId): Este mensaje es enviado al coordinador para confirmarle que el pedido fue enviado con exito.
  • SearchRestaurants(position): Este mensaje es enviado al coordinador cuando el cliente quiere obtener los restaurantes cercanos para realizar un pedido.
  • PlaceOrder(clientId, restaurantId, amount): Este mensaje es enviado al coordinador cuando el cliente quiere realizar un pedido con el precio indicado y en el restaurant indicado.

Mensajes Enviados

  • OrderCreated(clientId, clientAddr): Este mensaje es enviado por un cordinador que avisa que un cliente quiere realizar un pedido en el restaurant. Recibe el ID del cliente y su direccion de red para poder comunicarle el seguimiento del pedido. Devuelve con el mensaje OrderConfirmed en caso de aceptar el pedido o OrderCanceled en caso de cancelar el pedido. El restaurant agrega el id del cliente a la cola de pedidos.
  • NewDelivery(restaurantPos, clientPos, clientAddr): Este mensaje es enviado por el coordinador que avisa al repartidor que hay un pedido en un restaurant cercano listo para ser retirado. Recibe la posicion del restaurant, del cliente y la direccion de red del cliente para mantenerlo informado. Responde con el mensaje DeliveryAccepted en caso de querer aceptar la orden, si la rechaza no responde nada.
  • DeliveryConfirmed: Este mensaje es enviado por el coordinador en caso de que el pedido previamente aceptado haya sido asignado, es decir, que fue el primer repartidor en aceptar el pedido. En ese caso, el repartidor envia el mensaje OrderOnItsWay al cliente para avisarle que ya esta en camino.
  • DeliveryTaken: Este mensaje es enviado por el coordinador en caso de que el pedido haya sido asignado a otro repartidor. En ese caso el repartidor queda a la espera de recibir nuevas ordenes de delivery.
  • Connected(coordAddr): Este mensaje es enviado por un coordinador para confirmar que el repartidor se conecto correctamente, recibiendo la direccion de red del coordinador lider.
  • NearRestaurants(vec: restaurantId): Este mensaje es enviado por el coordinador cuando el cliente quiere realizar un pedido. Recibe un vector de ids de restaurantes, de los cuales el cliente elegira uno donde realizar el pedido. El cliente respondera con el mensaje PlaceOrder(clientId, restaurantId, amount) al coordinador para realizar el pedido.
  • OrderConfirmed: Este mensaje es enviado por el coordinador cuando tiene la confirmacion del restaurant y del gateway de pagos que el pedido fue recibido correctamente. El cliente queda a la espera de recibir los siguientes estados de su pedido.
  • OrderCanceled: Este mensaje es enviado por el coordinador cuando el restaurant cancelo su pedido. El cliente puede volver a realizar un nuevo pedido.
  • PaymentCanceled: Este mensaje es enviado por el coordinador cuando el gateway de pagos rechazo la tarjeta del cliente. El cliente puede volver a realizar un nuevo pedido.
  • Connected(coordAddr): Este mensaje es enviado por un coordinador para confirmar que el cliente se conecto correctamente, recibiendo la direccion de red del coordinador lider.

Protocolo de Comunicacion

El coordinador tambien utilizara el protocolo de transporte TCP para la comunicacion con las demas aplicaciones. El protocolo de aplicacion sera en formato json, permitiendonos utilizar librerias que faciliten la serializacion y deserializacion de los mensajes. Por ejemplo, si se quiere enviar el mensaje Connected(coordAddr) se debera enviar el json: { "type": "Connected", "coordAddr": "127.0.0.1:9000" }

Casos de Interes

  • Caso Restaurante con pedido caído: El coordinador cancelará el pedido y le solicitará al gateway de pagos que devuelva el dinero al cliente.
  • Caso Repartidor yendo a buscar un pedido caído: El coordinador hará otra selección de repartidor utilizando nuevamente el Mutex centralizado.
  • Caso Comensal caído: El coordinador ignorará la caída.

Gateway de Pagos

Finalidad General

Esta aplicacion tiene como finalidad simular la actividad de un gateway de pagos, aceptando o rechazando la tarjeta de los usuarios aleatoriamente y efectuando el pago una vez que finaliza el pedido.

Estado Interno


PaymentsGatewayActor:
  clientOrders,
  tcpSender,
  tcpReceiver

Mensajes Recibidos

  • AuthPayement(clientId, clientAddr, amount): Este mensaje es enviado por el coordinador cuando un cliente quiere realizar un pedido. El gateway puede autorizar o rechazar el pago aleatoriamente, respondiendo al coordinador con los mensajes PaymentAuthorized o PaymentCancelled, respectivamente.
  • MakePayment(clientId): Este mensaje es enviado por el coordinador cuando el pedido fue entregado al cliente y debe efectuarse el pago. El gateway informa al cliente que su pago fue efectuado enviando PaymentDone. El pedido es eliminado del diccionario de pedidos.
  • Connected: Este mensaje es enviado por un coordinador para confirmar que el gateway se conecto correctamente.

Mensajes Enviados

  • PaymentAuthorized: Este mensaje es enviado al coordinador si la tarjeta del cliente fue autorizada.
  • PaymentCancelled: Este mensaje es enviado al coordinador si la tarjeta del cliente fue rechazada.
  • PaymentDone: Este mensaje es enviado al cliente cuando el pago fue efectuado.
  • ConnectGateway: Este mensaje es enviado al coordinador para avisar que el gateway esta activo.

Protocolo de Comunicacion

El gateway tambien utilizara el protocolo de transporte TCP para la comunicacion con las demas aplicaciones. El protocolo de aplicacion sera en formato de string terminados en '\n' y con parametros separados por '-'. El string enviado debera ser igual al mensaje que desea que represente. Por ejemplo, si se quiere enviar el mensaje PaymentAuthorized se debera enviar el string "PaymentAuthorized\n". El protocolo de aplicacion sera en formato json, permitiendonos utilizar librerias que faciliten la serializacion y deserializacion de los mensajes. Por ejemplo, si se quiere enviar el mensaje PaymentDone se debera enviar el json: { "type": "PaymentDone" }

Casos de Interes

  • Caso Feliz: El gateway inicia la aplicacion y se conecta automaticamente a uno de los coordinadores y le envia el mensaje ConnectGateway. Cuando recibe el mensaje Connected, el gateway queda a la espera de la solicitud de autorizacion mediante los mensajes AuthPayment(clientId, clientAddr, amount). Cuando recibe ese mensaje, analiza si aceptar o rechazar la tarjeta. En caso de aceptarla, devuelve al coordinador el mensaje de PaymentAuthorized y agrega al cliente al diccionario de pedidos. Queda a la espera de recibir otra solicitud de autorizacion o de efectuar el pago. Si recibe el mensaje de MakePayment(clientId), envia el mensaje PaymentDone al cliente y queda nuevamente a la espera de mensajes.
  • Caso Coordinador Caido: Si en algun momento de la ejecucion el coordinador finaliza su ejecucion, el gateway va a intentar conectarse a otra replica del coordinador enviando el mensaje ConnectGateway y queda a la espera de recibir el mensaje Connected.

Ejemplo de flujo de mensajes

alt text

Herramientas de Concurrencia utilizadas

Redundancia del Coordinador

Como planteamos el diseño de la aplicacion, el Coordinador puede ser un unico punto de falla. Para mejorar la resiliencia de nuestro programa, se decidio que el Coordinador tendra varias replicas listas para continuar con la ejecucion del programa si el Coordinador lider falla por algun motivo.

Cuando alguna entidad (repartidor, cliente, restaurant) detecta que el coordinador lider no responde, intenta conectarse a otro coordinador enviando el mensaje de ConnectRestaurant (por ejemplo). Internamente, cada Coordinador sabe cual es el lider, por lo que si un coordinador que no es lider recibe este mensaje, implica que el lider fallo. Ante esto, los coordinadores entraran en un estado de eleccion de lider. Mediante el Algoritmo Bully, procederan a elegir cual de los Coordinadores actuara como lider. Una vez que se elija el coordinador lider, los coordinadores responderan al mensaje de cada entidad con el mensaje Connect(coordAddr), enviando la direccion de red del nuevo coordinador lider elegido.

alt text

Segunda Entrega

Ejecución

Para ejecutar cada actor del sistema, usá el siguiente comando desde la raíz del proyecto:

cargo run --bin <actor> <id>

<actor>: el nombre del binario a ejecutar. Puede ser uno de:

  • restaurant
  • client
  • rider
  • coordinator

<id>: el identificador único del actor según el archivo de configuración (config.json).

En el caso del gateway NO requiere cargo run --bin gateway

Cambios

Restaurant

Se refactorizó el comportamiento del actor RestaurantActor para simplificar la lógica de preparación de pedidos. Eliminado:

  • orderQueue
  • activeOrders
  • workersPool

Ahora:

  • Todo el flujo de preparación de un pedido se maneja directamente desde el handler de OrderCreated.
  • La preparación se simula con un delay asincrónico (sleep) por cada pedido recibido.
  • Los mensajes al cliente (OrderConfirmed, PreparingOrder, OrderReadyToDeliver) se envían desde dentro de ese handler.

Nuevos Mensajes recibidos

  • NoLeader: Este mensaje es enviado por un coordinador que avisa que aún no hay un lider definido entre los coordinadores.
  • NotLeader(coord_addr): Este mensaje es enviado por un coordinador para redirigir la conexión del actor hacia el lider actual.

Nuevos Mensajes enviados

Repartidor

Se actualizaron los atributos del RiderActor para permitir un mejor seguimiento de los pedidos en proceso y los que están pendientes de confirmación.


RiderActor {
  id,            
  name,              
  position,              
  tcpSender,          
  tcpReceiver,            
  coord_addr,                                                // address del lider
  delivery_confirmed: Option,                           // Pedido que está entregando actualmente (client_id)
  pending_deliveries: HashMap // Pedidos aceptados aún no confirmados, mapeo de client_id → (restaurant_pos, client_pos)
}

Nuevos Mensajes Recibidos

  • NoLeader: Este mensaje es enviado por un coordinador que avisa que aún no hay un lider definido entre los coordinadores.
  • NotLeader(coord_addr): Este mensaje es enviado por un coordinador para redirigir la conexión del actor hacia el lider actual.

Nuevos Mensajes Enviados o Modificados:

  • DeliveryAccepted(riderId, clientId): Este mensaje es enviado al coordinador cuando el repartidor acepta realizar el delivery. Ahora tambien envia el clientId para identificar el pedido.
  • OrderOnItsWay(riderId): Este mensaje ahora es enviado al coordinador cuando el repartidor llega al restaurant y se dirige hacia el cliente. Ahora tambien envia el clientId para identificar el delivery.
  • OrderDelivered(riderId): Este mensaje es enviado al coordinador para confirmarle que el pedido fue enviado con exito. Ahora tambien envia el clientId para identificar el delivery
  • ConnectRider(riderId): Este mensaje es enviado al coordinador para avisar que el repartidor esta activo. ya no envía la posicion, se obtiene por archivo de configuración.
  • AlreadyAssigned(riderId, clientId): Este mensaje es enviado al coordinador para avisar que ya habia sido confirmado con otro pedido.

Mensajes No Enviados:

  • OrderArrived: Ya no hay comunicación entre el rider y los actores que no sean el coordinador

Comensal/Cliente

Ahora toda la comunicación pasa a través del Coordinador, en lugar de ser directa con los restaurantes o riders.

Nuevos Mensajes recibidos

  • NoLeader: Este mensaje es enviado por un coordinador que avisa que aún no hay un lider definido entre los coordinadores.
  • NotLeader(coord_addr): Este mensaje es enviado por un coordinador para redirigir la conexión del actor hacia el lider actual.

Coordinador

El coordinador ahora actua como intermediario de todos los mensajes del sistema, tambien se implemento 2PC para la transaccion de datos entre el lider y el resto de coordinadores, si el coordinador se conecta pide el estado al lider actual. Se agregaron los mensajes necesarios para la elección del lider Bully y la transacción 2PC

Mensajes Nuevos

  • BullyElection(sender_id): Inicia una elección de líder Bully. El coordinador con mayor id debe responder.
  • BullyOk(sender_id): Respuesta a una elección Bully, indicando que hay un coordinador con id mayor activo.
  • BullyLeader(leader_id): Notifica a todos los coordinadores quién es el nuevo líder.
  • Start2PC(operation): El líder inicia la fase de preparación de una transacción 2PC para una operación.
  • Prepare(operation): El líder pide a los coordinadores que preparen la operación (fase 1 de 2PC).
  • Ready(sender_id): Un coordinador responde que está listo para comprometer la operación (fase 1 de 2PC).
  • Commit(operation): El líder ordena a todos los coordinadores que confirmen la operación (fase 2 de 2PC).
  • Abort(operation): El líder ordena abortar la operación (por timeout o error en 2PC).
  • Ping(sender_id): Mensaje de latido (heartbeat) para detectar actores activos.
  • Pong(sender_id, entity_type): Respuesta al Ping, confirma que el actor está activo.
  • StateUpdate(state): El líder envía el estado actualizado a un coordinador que se conecta o se recupera.
  • AlreadyAssigned(rider_id, client_id): Un rider avisa que ya tiene un pedido asignado y no puede tomar otro.

Gateway de Pagos

Nuevos Mensajes recibidos

  • DeletePayment(clientId): Este mensaje es enviado por el coordinador cuando el pedido fue cancelado por el restaurant y debe borrarse el registro del pago.
  • NoLeader: Este mensaje es enviado por un coordinador que avisa que aún no hay un lider definido entre los coordinadores.
  • NotLeader(coord_addr): Este mensaje es enviado por un coordinador para redirigir la conexión del actor hacia el lider actual.

Exclusion Mutua Distribuida para manejar el acceso a la oferta de delivery

Cuando un restaurant finaliza la preparacion de un pedido, avisa al coordinador que tiene un pedido listo con el mensaje OrderReady(clientId, restaurantId). El coordinador avisa a todos los repartidores cercanos que hay un pedido para retirar con el mensaje NewDelivery(restaurantPos, clientPos, clientAddr). Los repartidores que quieran realizar el pedido responderan al coordinador con DeliveryAccepted(riderId). El coordinador respondera con DeliveryConfirmed al primer repartidor que acepte y con DeliveryConfirmed

Reentrega

Nuevo manejo de conexiones TCP

Se modificó el manejo de las conexiones TCP entre actores para que persistan durante la comunicación. Para eso, se refactorizó el TcpSender de la siguiente forma:


TcpSender {
  writers: HashMap // (address, writer)
}

De esta forma, se reutilizan los writers de las conexiones activas entre actores al guardarlos en el hash de writers. Cuando un actor decide enviar un mensaje TCP mediante su tcp_sender, debe indicarle a qué direccion hacerlo, y con esta información el TcpSender utiliza el writer indicado.

Los nuevos metodos de conexión entre actores son los siguientes:

  • Entre Coordinadores: Luego de pedir el estado inicial, el coordinador que ingresa al sistema intenta conectarse a todos los coordinadores. Para eso, por cada coordinador se autoenvia el mensaje StartConnection, mensaje que inicia una conexion con el coordinador y le envia EstablishConnection. El coordinador que recibe EstablishConnection se guarda el writer de la conexion entrante, y reenvia el mensaje ConfirmConnection al coordinador inicial. Este, al recibir ConfirmConnection tambien se guarda el writer de la conexion. De esta forma, ambos estan conectados entre si y almacenaron el writer de su conexion TCP para poder reutilizarlo.
  • Actor externo entrante: La conexión se realiza de la misma forma que antes, pero al recibir el mensaje Connected de parte del coordinador, el actor externo (Restaurant, Rider, Cliente o Gateway) almacena el writer de la conexion en su Tcp_Sender.
  • Cambio de Lider: Al proclamarse lider mediante el mensaje MakeMeLeader, el nuevo lider envia el mensaje NewLeaderConnection a todas las entidades activas. Al recibir este mensaje, las entidades se guardan el writer de la nueva conexion, y responden con ConfirmConnection. El nuevo lider al recibir este ultimo mensaje tambien se guarda el writer, y asi las entidades quedan correctamente conectadas al nuevo coordinador lider.

Corrección de errores

En la primera entrega se detectó que al remover un restaurant, el cliente quedaba bloqueado al realizar una nueva órden. Esto fue resuelto eliminando todas las órdenes activas del restaurant caído.

Mejoras

Además de lo corregido, mejoramos el caso de caída de cliente. Anteriormente, cuando el cliente se caía y se volvía a conectar, empezaba una órden nueva por más que ya tenia una creada en el sistema. Con las mejoras, el cliente al conectarse nuevamente no empieza una nueva órden si ya tenia una creada, y queda a la espera del seguimiento de su pedido original.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors