github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/worker/caasunitsmanager/worker.go (about) 1 // Copyright 2022 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package caasunitsmanager 5 6 import ( 7 "github.com/juju/clock" 8 "github.com/juju/errors" 9 "github.com/juju/worker/v3" 10 "github.com/juju/worker/v3/catacomb" 11 12 message "github.com/juju/juju/pubsub/agent" 13 ) 14 15 // Hub is a pubsub hub used for internal messaging. 16 type Hub interface { 17 Publish(topic string, data interface{}) func() 18 Subscribe(topic string, handler func(string, interface{})) func() 19 } 20 21 type manager struct { 22 catacomb catacomb.Catacomb 23 24 logger Logger 25 clock clock.Clock 26 27 hub Hub 28 unsub func() 29 } 30 31 type Config struct { 32 Logger 33 Clock clock.Clock 34 35 Hub 36 } 37 38 // NewWorker returns a worker that runs on CAAS agent and subscribes and handles unit topics. 39 func NewWorker(config Config) (worker.Worker, error) { 40 w := manager{ 41 logger: config.Logger, 42 clock: config.Clock, 43 hub: config.Hub, 44 } 45 unsubStop := w.hub.Subscribe(message.StopUnitTopic, w.stopUnitRequest) 46 unsubStart := w.hub.Subscribe(message.StartUnitTopic, w.startUnitRequest) 47 unsubStatus := w.hub.Subscribe(message.UnitStatusTopic, w.unitStatusRequest) 48 w.unsub = func() { 49 unsubStop() 50 unsubStart() 51 unsubStatus() 52 } 53 err := catacomb.Invoke(catacomb.Plan{ 54 Site: &w.catacomb, 55 Work: w.loop, 56 }) 57 if err != nil { 58 return nil, errors.Trace(err) 59 } 60 return &w, nil 61 } 62 63 func (w *manager) stopUnitRequest(topic string, data interface{}) { 64 units, ok := data.(message.Units) 65 if !ok { 66 w.logger.Errorf("data should be a Units structure") 67 } 68 response := message.StartStopResponse{ 69 "error": errors.NotSupportedf("stop units for %v", units).Error(), 70 } 71 w.hub.Publish(message.StopUnitResponseTopic, response) 72 } 73 74 func (w *manager) startUnitRequest(topic string, data interface{}) { 75 units, ok := data.(message.Units) 76 if !ok { 77 w.logger.Errorf("data should be a Units structure") 78 } 79 response := message.StartStopResponse{ 80 "error": errors.NotSupportedf("start units for %v", units).Error(), 81 } 82 w.hub.Publish(message.StartUnitResponseTopic, response) 83 } 84 85 func (w *manager) unitStatusRequest(topic string, _ interface{}) { 86 response := message.Status{ 87 "error": errors.NotSupportedf("units status").Error(), 88 } 89 w.hub.Publish(message.UnitStatusResponseTopic, response) 90 } 91 92 func (w *manager) Kill() { 93 w.unsub() 94 w.catacomb.Kill(nil) 95 } 96 97 func (w *manager) Wait() error { 98 return w.catacomb.Wait() 99 } 100 101 func (w *manager) loop() error { 102 <-w.catacomb.Dying() 103 return w.catacomb.ErrDying() 104 }