github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/state/pool.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package state 5 6 import ( 7 "sync" 8 9 "github.com/juju/errors" 10 "gopkg.in/juju/names.v2" 11 ) 12 13 // NewStatePool returns a new StatePool instance. It takes a State 14 // connected to the system (controller model). 15 func NewStatePool(systemState *State) *StatePool { 16 return &StatePool{ 17 systemState: systemState, 18 pool: make(map[string]*State), 19 } 20 } 21 22 // StatePool is a simple cache of State instances for multiple models. 23 type StatePool struct { 24 systemState *State 25 // mu protects pool 26 mu sync.Mutex 27 pool map[string]*State 28 } 29 30 // Get returns a State for a given model from the pool, creating 31 // one if required. 32 func (p *StatePool) Get(modelUUID string) (*State, error) { 33 if modelUUID == p.systemState.ModelUUID() { 34 return p.systemState, nil 35 } 36 37 p.mu.Lock() 38 defer p.mu.Unlock() 39 40 st, ok := p.pool[modelUUID] 41 if ok { 42 return st, nil 43 } 44 45 st, err := p.systemState.ForModel(names.NewModelTag(modelUUID)) 46 if err != nil { 47 return nil, errors.Annotatef(err, "failed to create state for model %v", modelUUID) 48 } 49 p.pool[modelUUID] = st 50 return st, nil 51 } 52 53 // SystemState returns the State passed in to NewStatePool. 54 func (p *StatePool) SystemState() *State { 55 return p.systemState 56 } 57 58 // Close closes all State instances in the pool. 59 func (p *StatePool) Close() error { 60 p.mu.Lock() 61 defer p.mu.Unlock() 62 63 var lastErr error 64 for _, st := range p.pool { 65 err := st.Close() 66 if err != nil { 67 lastErr = err 68 } 69 } 70 p.pool = make(map[string]*State) 71 return errors.Annotate(lastErr, "at least one error closing a state") 72 }