...

Source file src/github.com/LINBIT/golinstor/cache/resource.go

Documentation: github.com/LINBIT/golinstor/cache

     1  package cache
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/LINBIT/golinstor/client"
     8  )
     9  
    10  // ResourceCache caches responses from a client.ResourceProvider.
    11  type ResourceCache struct {
    12  	// Timeout for the cached responses.
    13  	Timeout time.Duration
    14  
    15  	resourceCache cache
    16  	snapshotCache cache
    17  }
    18  
    19  func (r *ResourceCache) apply(c *client.Client) {
    20  	c.Resources = &resourceCacheProvider{
    21  		cl:    c.Resources,
    22  		cache: r,
    23  	}
    24  }
    25  
    26  type resourceCacheProvider struct {
    27  	cl    client.ResourceProvider
    28  	cache *ResourceCache
    29  }
    30  
    31  var _ client.ResourceProvider = &resourceCacheProvider{}
    32  
    33  func (r *resourceCacheProvider) GetResourceView(ctx context.Context, opts ...*client.ListOpts) ([]client.ResourceWithVolumes, error) {
    34  	result, err := r.cache.resourceCache.Get(r.cache.Timeout, func() (any, error) {
    35  		return r.cl.GetResourceView(ctx, cacheOpt)
    36  	})
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	return filterNodeAndPoolOpts(result.([]client.ResourceWithVolumes), func(c *client.ResourceWithVolumes) ([]string, []string) {
    42  		return []string{c.NodeName}, nil
    43  	}, opts...), nil
    44  }
    45  
    46  func (r *resourceCacheProvider) GetAll(ctx context.Context, resName string, opts ...*client.ListOpts) ([]client.Resource, error) {
    47  	ress, err := r.GetResourceView(ctx, opts...)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	var result []client.Resource
    53  
    54  	for i := range ress {
    55  		if ress[i].Name == resName {
    56  			result = append(result, ress[i].Resource)
    57  		}
    58  	}
    59  
    60  	return result, nil
    61  }
    62  
    63  func (r *resourceCacheProvider) Get(ctx context.Context, resName, nodeName string, opts ...*client.ListOpts) (client.Resource, error) {
    64  	ress, err := r.GetAll(ctx, resName, opts...)
    65  	if err != nil {
    66  		return client.Resource{}, err
    67  	}
    68  
    69  	for i := range ress {
    70  		if ress[i].NodeName == nodeName {
    71  			return ress[i], nil
    72  		}
    73  	}
    74  	return client.Resource{}, client.NotFoundError
    75  }
    76  
    77  func (r *resourceCacheProvider) GetVolumes(ctx context.Context, resName, nodeName string, opts ...*client.ListOpts) ([]client.Volume, error) {
    78  	ress, err := r.GetResourceView(ctx, opts...)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	var result []client.Volume
    84  	for i := range ress {
    85  		if ress[i].NodeName != nodeName || ress[i].Name != resName {
    86  			continue
    87  		}
    88  
    89  		for j := range ress[i].Volumes {
    90  			result = append(result, ress[i].Volumes[j])
    91  		}
    92  	}
    93  
    94  	return result, nil
    95  }
    96  
    97  func (r *resourceCacheProvider) GetVolume(ctx context.Context, resName, nodeName string, volNr int, opts ...*client.ListOpts) (client.Volume, error) {
    98  	volumes, err := r.GetVolumes(ctx, resName, nodeName, opts...)
    99  	if err != nil {
   100  		return client.Volume{}, err
   101  	}
   102  
   103  	for i := range volumes {
   104  		if int(volumes[i].VolumeNumber) == volNr {
   105  			return volumes[i], nil
   106  		}
   107  	}
   108  
   109  	return client.Volume{}, client.NotFoundError
   110  }
   111  
   112  func (r *resourceCacheProvider) Create(ctx context.Context, res client.ResourceCreate) error {
   113  	r.cache.resourceCache.Invalidate()
   114  	return r.cl.Create(ctx, res)
   115  }
   116  
   117  func (r *resourceCacheProvider) Modify(ctx context.Context, resName, nodeName string, props client.GenericPropsModify) error {
   118  	r.cache.resourceCache.Invalidate()
   119  	return r.cl.Modify(ctx, resName, nodeName, props)
   120  }
   121  
   122  func (r *resourceCacheProvider) Delete(ctx context.Context, resName, nodeName string) error {
   123  	r.cache.resourceCache.Invalidate()
   124  	return r.cl.Delete(ctx, resName, nodeName)
   125  }
   126  
   127  func (r *resourceCacheProvider) ModifyVolume(ctx context.Context, resName, nodeName string, volNr int, props client.GenericPropsModify) error {
   128  	r.cache.resourceCache.Invalidate()
   129  	return r.cl.ModifyVolume(ctx, resName, nodeName, volNr, props)
   130  }
   131  
   132  func (r *resourceCacheProvider) Diskless(ctx context.Context, resName, nodeName, disklessPoolName string) error {
   133  	r.cache.resourceCache.Invalidate()
   134  	return r.cl.Diskless(ctx, resName, nodeName, disklessPoolName)
   135  }
   136  
   137  func (r *resourceCacheProvider) Diskful(ctx context.Context, resName, nodeName, storagePoolName string, props *client.ToggleDiskDiskfulProps) error {
   138  	r.cache.resourceCache.Invalidate()
   139  	return r.cl.Diskful(ctx, resName, nodeName, storagePoolName, props)
   140  }
   141  
   142  func (r *resourceCacheProvider) Migrate(ctx context.Context, resName, fromNodeName, toNodeName, storagePoolName string) error {
   143  	r.cache.resourceCache.Invalidate()
   144  	return r.cl.Migrate(ctx, resName, fromNodeName, toNodeName, storagePoolName)
   145  }
   146  
   147  func (r *resourceCacheProvider) Autoplace(ctx context.Context, resName string, apr client.AutoPlaceRequest) error {
   148  	r.cache.resourceCache.Invalidate()
   149  	return r.cl.Autoplace(ctx, resName, apr)
   150  }
   151  
   152  func (r *resourceCacheProvider) Activate(ctx context.Context, resName string, nodeName string) error {
   153  	r.cache.resourceCache.Invalidate()
   154  	return r.cl.Activate(ctx, resName, nodeName)
   155  }
   156  
   157  func (r *resourceCacheProvider) Deactivate(ctx context.Context, resName string, nodeName string) error {
   158  	r.cache.resourceCache.Invalidate()
   159  	return r.cl.Deactivate(ctx, resName, nodeName)
   160  }
   161  
   162  func (r *resourceCacheProvider) MakeAvailable(ctx context.Context, resName, nodeName string, makeAvailable client.ResourceMakeAvailable) error {
   163  	r.cache.resourceCache.Invalidate()
   164  	return r.cl.MakeAvailable(ctx, resName, nodeName, makeAvailable)
   165  }
   166  
   167  func (r *resourceCacheProvider) GetSnapshotView(ctx context.Context, opts ...*client.ListOpts) ([]client.Snapshot, error) {
   168  	result, err := r.cache.snapshotCache.Get(r.cache.Timeout, func() (any, error) {
   169  		return r.cl.GetSnapshotView(ctx, cacheOpt)
   170  	})
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  
   175  	return filterNodeAndPoolOpts(result.([]client.Snapshot), func(c *client.Snapshot) ([]string, []string) {
   176  		return c.Nodes, nil
   177  	}, opts...), nil
   178  }
   179  
   180  func (r *resourceCacheProvider) GetSnapshots(ctx context.Context, resName string, opts ...*client.ListOpts) ([]client.Snapshot, error) {
   181  	snaps, err := r.GetSnapshotView(ctx, opts...)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  
   186  	var result []client.Snapshot
   187  	for i := range snaps {
   188  		if snaps[i].ResourceName == resName {
   189  			result = append(result, snaps[i])
   190  		}
   191  	}
   192  
   193  	return result, nil
   194  }
   195  
   196  func (r *resourceCacheProvider) GetSnapshot(ctx context.Context, resName, snapName string, opts ...*client.ListOpts) (client.Snapshot, error) {
   197  	snaps, err := r.GetSnapshots(ctx, resName, opts...)
   198  	if err != nil {
   199  		return client.Snapshot{}, err
   200  	}
   201  
   202  	for i := range snaps {
   203  		if snaps[i].Name == snapName {
   204  			return snaps[i], nil
   205  		}
   206  	}
   207  
   208  	return client.Snapshot{}, client.NotFoundError
   209  }
   210  
   211  func (r *resourceCacheProvider) CreateSnapshot(ctx context.Context, snapshot client.Snapshot) error {
   212  	r.cache.snapshotCache.Invalidate()
   213  	return r.cl.CreateSnapshot(ctx, snapshot)
   214  }
   215  
   216  func (r *resourceCacheProvider) DeleteSnapshot(ctx context.Context, resName, snapName string, nodes ...string) error {
   217  	r.cache.snapshotCache.Invalidate()
   218  	return r.cl.DeleteSnapshot(ctx, resName, snapName, nodes...)
   219  }
   220  
   221  func (r *resourceCacheProvider) RestoreSnapshot(ctx context.Context, origResName, snapName string, snapRestoreConf client.SnapshotRestore) error {
   222  	// This will create new resources, not touch snapshots
   223  	r.cache.resourceCache.Invalidate()
   224  	return r.cl.RestoreSnapshot(ctx, origResName, snapName, snapRestoreConf)
   225  }
   226  
   227  func (r *resourceCacheProvider) RestoreVolumeDefinitionSnapshot(ctx context.Context, origResName, snapName string, snapRestoreConf client.SnapshotRestore) error {
   228  	// This will create new resources, not touch snapshots
   229  	r.cache.resourceCache.Invalidate()
   230  	return r.cl.RestoreVolumeDefinitionSnapshot(ctx, origResName, snapName, snapRestoreConf)
   231  }
   232  
   233  func (r *resourceCacheProvider) RollbackSnapshot(ctx context.Context, resName, snapName string) error {
   234  	return r.cl.RollbackSnapshot(ctx, resName, snapName)
   235  }
   236  
   237  func (r *resourceCacheProvider) GetConnections(ctx context.Context, resName, nodeAName, nodeBName string, opts ...*client.ListOpts) ([]client.ResourceConnection, error) {
   238  	return r.cl.GetConnections(ctx, resName, nodeAName, nodeBName, opts...)
   239  }
   240  
   241  func (r *resourceCacheProvider) ModifyConnection(ctx context.Context, resName, nodeAName, nodeBName string, props client.GenericPropsModify) error {
   242  	return r.cl.ModifyConnection(ctx, resName, nodeAName, nodeBName, props)
   243  }
   244  
   245  func (r *resourceCacheProvider) EnableSnapshotShipping(ctx context.Context, resName string, ship client.SnapshotShipping) error {
   246  	return r.cl.EnableSnapshotShipping(ctx, resName, ship)
   247  }
   248  
   249  func (r *resourceCacheProvider) ModifyDRBDProxy(ctx context.Context, resName string, props client.DrbdProxyModify) error {
   250  	return r.cl.ModifyDRBDProxy(ctx, resName, props)
   251  }
   252  
   253  func (r *resourceCacheProvider) EnableDRBDProxy(ctx context.Context, resName, nodeAName, nodeBName string) error {
   254  	return r.cl.EnableDRBDProxy(ctx, resName, nodeAName, nodeBName)
   255  }
   256  
   257  func (r *resourceCacheProvider) DisableDRBDProxy(ctx context.Context, resName, nodeAName, nodeBName string) error {
   258  	return r.cl.DisableDRBDProxy(ctx, resName, nodeAName, nodeBName)
   259  }
   260  
   261  func (r *resourceCacheProvider) QueryMaxVolumeSize(ctx context.Context, filter client.AutoSelectFilter) (client.MaxVolumeSizes, error) {
   262  	return r.cl.QueryMaxVolumeSize(ctx, filter)
   263  }
   264  
   265  func (r *resourceCacheProvider) GetSnapshotShippings(ctx context.Context, opts ...*client.ListOpts) ([]client.SnapshotShippingStatus, error) {
   266  	return r.cl.GetSnapshotShippings(ctx, opts...)
   267  }
   268  
   269  func (r *resourceCacheProvider) GetPropsInfos(ctx context.Context, resName string, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
   270  	return r.cl.GetPropsInfos(ctx, resName, opts...)
   271  }
   272  
   273  func (r *resourceCacheProvider) GetVolumeDefinitionPropsInfos(ctx context.Context, resName string, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
   274  	return r.cl.GetVolumeDefinitionPropsInfos(ctx, resName, opts...)
   275  }
   276  
   277  func (r *resourceCacheProvider) GetVolumePropsInfos(ctx context.Context, resName, nodeName string, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
   278  	return r.cl.GetVolumePropsInfos(ctx, resName, nodeName, opts...)
   279  }
   280  
   281  func (r *resourceCacheProvider) GetConnectionPropsInfos(ctx context.Context, resName string, opts ...*client.ListOpts) ([]client.PropsInfo, error) {
   282  	return r.cl.GetConnectionPropsInfos(ctx, resName, opts...)
   283  }
   284  

View as plain text