package airport import ( "errors" "fmt" "time" ) type Checkin struct { processingTime time.Duration queue chan passengerCheckinData flightProvider FlightProvider baggageProcessor BaggageProcessor } type passengerCheckinData struct { p *Passenger err chan error } func NewCheckin(processingTime time.Duration, fp FlightProvider, bp BaggageProcessor) Checkin { return Checkin{ processingTime: processingTime, queue: make(chan passengerCheckinData), flightProvider: fp, baggageProcessor: bp, } } func (c Checkin) Process(p *Passenger) error { err := make(chan error) c.queue <- passengerCheckinData{p: p, err: err} return <-err } func (c Checkin) Start() { defer fmt.Println("checkin terminated") for element := range c.queue { time.Sleep(c.processingTime) //1. check ticket if element.p.Name != element.p.Ticket.Name { element.err <- fmt.Errorf("name %s on ticket does not match", element.p.Ticket.Name) continue } flight, err := c.flightProvider.GetFlight(element.p.Ticket.FlightNumber) if err != nil { element.err <- err continue } //2. issue boarding pass element.p.BoardingPass = &BoardingPass{element.p.Ticket, flight.GateNumber} //3. check in bags var baggageErr error for _, bag := range element.p.Bags { if err := c.baggageProcessor.ProcessBaggage(flight.Id, bag); err != nil { baggageErr = errors.Join(baggageErr, err) } } if baggageErr != nil { element.err <- baggageErr continue } element.p.Bags = []Baggage{} element.err <- nil } }