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