github.com/bigcommerce/nomad@v0.9.3-bc/client/state/memdb.go (about) 1 package state 2 3 import ( 4 "sync" 5 6 hclog "github.com/hashicorp/go-hclog" 7 "github.com/hashicorp/nomad/client/allocrunner/taskrunner/state" 8 dmstate "github.com/hashicorp/nomad/client/devicemanager/state" 9 driverstate "github.com/hashicorp/nomad/client/pluginmanager/drivermanager/state" 10 "github.com/hashicorp/nomad/nomad/structs" 11 ) 12 13 // MemDB implements a StateDB that stores data in memory and should only be 14 // used for testing. All methods are safe for concurrent use. 15 type MemDB struct { 16 // alloc_id -> value 17 allocs map[string]*structs.Allocation 18 19 // alloc_id -> value 20 deployStatus map[string]*structs.AllocDeploymentStatus 21 22 // alloc_id -> task_name -> value 23 localTaskState map[string]map[string]*state.LocalState 24 taskState map[string]map[string]*structs.TaskState 25 26 // devicemanager -> plugin-state 27 devManagerPs *dmstate.PluginState 28 29 // drivermanager -> plugin-state 30 driverManagerPs *driverstate.PluginState 31 32 logger hclog.Logger 33 34 mu sync.RWMutex 35 } 36 37 func NewMemDB(logger hclog.Logger) *MemDB { 38 logger = logger.Named("memdb") 39 return &MemDB{ 40 allocs: make(map[string]*structs.Allocation), 41 deployStatus: make(map[string]*structs.AllocDeploymentStatus), 42 localTaskState: make(map[string]map[string]*state.LocalState), 43 taskState: make(map[string]map[string]*structs.TaskState), 44 logger: logger, 45 } 46 } 47 48 func (m *MemDB) Name() string { 49 return "memdb" 50 } 51 52 func (m *MemDB) Upgrade() error { 53 return nil 54 } 55 56 func (m *MemDB) GetAllAllocations() ([]*structs.Allocation, map[string]error, error) { 57 m.mu.RLock() 58 defer m.mu.RUnlock() 59 60 allocs := make([]*structs.Allocation, 0, len(m.allocs)) 61 for _, v := range m.allocs { 62 allocs = append(allocs, v) 63 } 64 65 return allocs, map[string]error{}, nil 66 } 67 68 func (m *MemDB) PutAllocation(alloc *structs.Allocation) error { 69 m.mu.Lock() 70 defer m.mu.Unlock() 71 m.allocs[alloc.ID] = alloc 72 return nil 73 } 74 75 func (m *MemDB) GetDeploymentStatus(allocID string) (*structs.AllocDeploymentStatus, error) { 76 m.mu.Lock() 77 defer m.mu.Unlock() 78 return m.deployStatus[allocID], nil 79 } 80 81 func (m *MemDB) PutDeploymentStatus(allocID string, ds *structs.AllocDeploymentStatus) error { 82 m.mu.Lock() 83 m.deployStatus[allocID] = ds 84 defer m.mu.Unlock() 85 return nil 86 } 87 88 func (m *MemDB) GetTaskRunnerState(allocID string, taskName string) (*state.LocalState, *structs.TaskState, error) { 89 m.mu.RLock() 90 defer m.mu.RUnlock() 91 92 var ls *state.LocalState 93 var ts *structs.TaskState 94 95 // Local Task State 96 allocLocalTS := m.localTaskState[allocID] 97 if len(allocLocalTS) != 0 { 98 ls = allocLocalTS[taskName] 99 } 100 101 // Task State 102 allocTS := m.taskState[allocID] 103 if len(allocTS) != 0 { 104 ts = allocTS[taskName] 105 } 106 107 return ls, ts, nil 108 } 109 110 func (m *MemDB) PutTaskRunnerLocalState(allocID string, taskName string, val *state.LocalState) error { 111 m.mu.Lock() 112 defer m.mu.Unlock() 113 114 if alts, ok := m.localTaskState[allocID]; ok { 115 alts[taskName] = val.Copy() 116 return nil 117 } 118 119 m.localTaskState[allocID] = map[string]*state.LocalState{ 120 taskName: val.Copy(), 121 } 122 123 return nil 124 } 125 126 func (m *MemDB) PutTaskState(allocID string, taskName string, state *structs.TaskState) error { 127 m.mu.Lock() 128 defer m.mu.Unlock() 129 130 if ats, ok := m.taskState[allocID]; ok { 131 ats[taskName] = state.Copy() 132 return nil 133 } 134 135 m.taskState[allocID] = map[string]*structs.TaskState{ 136 taskName: state.Copy(), 137 } 138 139 return nil 140 } 141 142 func (m *MemDB) DeleteTaskBucket(allocID, taskName string) error { 143 m.mu.Lock() 144 defer m.mu.Unlock() 145 146 if ats, ok := m.taskState[allocID]; ok { 147 delete(ats, taskName) 148 } 149 150 if alts, ok := m.localTaskState[allocID]; ok { 151 delete(alts, taskName) 152 } 153 154 return nil 155 } 156 157 func (m *MemDB) DeleteAllocationBucket(allocID string) error { 158 m.mu.Lock() 159 defer m.mu.Unlock() 160 161 delete(m.allocs, allocID) 162 delete(m.taskState, allocID) 163 delete(m.localTaskState, allocID) 164 165 return nil 166 } 167 168 func (m *MemDB) PutDevicePluginState(ps *dmstate.PluginState) error { 169 m.mu.Lock() 170 defer m.mu.Unlock() 171 m.devManagerPs = ps 172 return nil 173 } 174 175 // GetDevicePluginState stores the device manager's plugin state or returns an 176 // error. 177 func (m *MemDB) GetDevicePluginState() (*dmstate.PluginState, error) { 178 m.mu.Lock() 179 defer m.mu.Unlock() 180 return m.devManagerPs, nil 181 } 182 183 func (m *MemDB) GetDriverPluginState() (*driverstate.PluginState, error) { 184 m.mu.Lock() 185 defer m.mu.Unlock() 186 return m.driverManagerPs, nil 187 } 188 189 func (m *MemDB) PutDriverPluginState(ps *driverstate.PluginState) error { 190 m.mu.Lock() 191 defer m.mu.Unlock() 192 m.driverManagerPs = ps 193 return nil 194 } 195 196 func (m *MemDB) Close() error { 197 m.mu.Lock() 198 defer m.mu.Unlock() 199 200 // Set everything to nil to blow up on further use 201 m.allocs = nil 202 m.taskState = nil 203 m.localTaskState = nil 204 205 return nil 206 }