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  }