package airport import ( "fmt" "time" ) type BaggageProcessor interface { ProcessBaggage(FlightNumber, Baggage) error } type BaggageHandlingSystem struct { processingTime time.Duration sinks map[FlightNumber]BaggageProcessor lostBaggage chan LostBaggage } type LostBaggage struct { Baggage FlightNumber FlightNumber Err error } var _ BaggageProcessor = &BaggageHandlingSystem{} func NewBaggageHandlingSystem(processingTime time.Duration, sinks map[FlightNumber]BaggageProcessor) BaggageHandlingSystem { return BaggageHandlingSystem{ processingTime: processingTime, sinks: sinks, lostBaggage: make(chan LostBaggage), } } func (bhs *BaggageHandlingSystem) ProcessBaggage(fn FlightNumber, b Baggage) error { sink, ok := bhs.sinks[fn] if !ok { return fmt.Errorf("invalid flight %v", fn) } go func() { time.Sleep(bhs.processingTime) if err := sink.ProcessBaggage(fn, b); err != nil { bhs.lostBaggage <- LostBaggage{b, fn, err} } }() return nil } func (bhs *BaggageHandlingSystem) CollectLostBaggage() []LostBaggage { lostBaggage := []LostBaggage{} for { select { case lb := <-bhs.lostBaggage: lostBaggage = append(lostBaggage, lb) default: return lostBaggage } } } func (bhs *BaggageHandlingSystem) Start() { defer fmt.Println("baggage handling terminated") select {} }