github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/state/life.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/mgo/v3/bson" 9 10 "github.com/juju/juju/core/life" 11 "github.com/juju/juju/mongo" 12 ) 13 14 // Life represents the lifecycle state of the entities 15 // Relation, Unit, Application and Machine. 16 type Life int8 17 18 const ( 19 Alive Life = iota 20 Dying 21 Dead 22 ) 23 24 // String is deprecated, use Value. 25 func (l Life) String() string { 26 switch l { 27 case Alive: 28 return "alive" 29 case Dying: 30 return "dying" 31 case Dead: 32 return "dead" 33 default: 34 return "unknown" 35 } 36 } 37 38 // Value returns the core.life.Value type. 39 func (l Life) Value() life.Value { 40 switch l { 41 case Alive: 42 return life.Alive 43 case Dying: 44 return life.Dying 45 case Dead: 46 return life.Dead 47 default: 48 return life.Value("unknown") 49 } 50 } 51 52 // LifeFromValue converts a life.Value into it's corresponding 53 // state.Life 54 func LifeFromValue(value life.Value) Life { 55 return valueMap[value] 56 } 57 58 var ( 59 isAliveDoc = bson.D{{"life", Alive}} 60 isDyingDoc = bson.D{{"life", Dying}} 61 isDeadDoc = bson.D{{"life", Dead}} 62 notDeadDoc = bson.D{{"life", bson.D{{"$ne", Dead}}}} 63 64 errDeadOrGone = errors.New("neither alive nor dying") 65 errAlreadyDying = errors.New("already dying") 66 errAlreadyRemoved = errors.New("already removed") 67 ) 68 69 var valueMap = map[life.Value]Life{ 70 life.Alive: Alive, 71 life.Dying: Dying, 72 life.Dead: Dead, 73 } 74 75 // Living describes state entities with a lifecycle. 76 type Living interface { 77 Life() Life 78 Destroy() error 79 Refresh() error 80 } 81 82 // AgentLiving describes state entities with a lifecycle and an agent that 83 // manages it. 84 type AgentLiving interface { 85 Living 86 EnsureDead() error 87 Remove() error 88 } 89 90 func isAlive(mb modelBackend, collName string, id interface{}) (bool, error) { 91 coll, closer := mb.db().GetCollection(collName) 92 defer closer() 93 return isAliveWithSession(coll, id) 94 } 95 96 func isAliveWithSession(coll mongo.Collection, id interface{}) (bool, error) { 97 return checkLifeWithSession(coll, id, bson.DocElem{"life", Alive}) 98 } 99 100 func isNotDead(mb modelBackend, collName string, id interface{}) (bool, error) { 101 coll, closer := mb.db().GetCollection(collName) 102 defer closer() 103 return isNotDeadWithSession(coll, id) 104 } 105 106 func isNotDeadWithSession(coll mongo.Collection, id interface{}) (bool, error) { 107 return checkLifeWithSession(coll, id, bson.DocElem{"life", bson.D{{"$ne", Dead}}}) 108 } 109 110 func isDying(mb modelBackend, collName string, id interface{}) (bool, error) { 111 coll, closer := mb.db().GetCollection(collName) 112 defer closer() 113 return isDyingWithSession(coll, id) 114 } 115 116 func isDyingWithSession(coll mongo.Collection, id interface{}) (bool, error) { 117 return checkLifeWithSession(coll, id, bson.DocElem{"life", Dying}) 118 } 119 120 func checkLifeWithSession(coll mongo.Collection, id interface{}, sel bson.DocElem) (bool, error) { 121 n, err := coll.Find(bson.D{{"_id", id}, sel}).Count() 122 return n == 1, err 123 }