github.com/Jeffail/benthos/v3@v3.65.0/lib/cache/file.go (about)

     1  package cache
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"time"
     8  
     9  	"github.com/Jeffail/benthos/v3/internal/component/cache"
    10  	"github.com/Jeffail/benthos/v3/internal/docs"
    11  	"github.com/Jeffail/benthos/v3/lib/log"
    12  	"github.com/Jeffail/benthos/v3/lib/metrics"
    13  	"github.com/Jeffail/benthos/v3/lib/types"
    14  )
    15  
    16  //------------------------------------------------------------------------------
    17  
    18  func init() {
    19  	Constructors[TypeFile] = TypeSpec{
    20  		constructor: NewFile,
    21  		Summary: `
    22  Stores each item in a directory as a file, where an item ID is the path relative
    23  to the configured directory.`,
    24  		Description: `
    25  This type currently offers no form of item expiry or garbage collection, and is
    26  intended to be used for development and debugging purposes only.`,
    27  		FieldSpecs: docs.FieldSpecs{
    28  			docs.FieldCommon("directory", "The directory within which to store items."),
    29  		},
    30  	}
    31  }
    32  
    33  //------------------------------------------------------------------------------
    34  
    35  // FileConfig contains config fields for the File cache type.
    36  type FileConfig struct {
    37  	Directory string `json:"directory" yaml:"directory"`
    38  }
    39  
    40  // NewFileConfig creates a FileConfig populated with default values.
    41  func NewFileConfig() FileConfig {
    42  	return FileConfig{
    43  		Directory: "",
    44  	}
    45  }
    46  
    47  //------------------------------------------------------------------------------
    48  
    49  // NewFile creates a new File cache type.
    50  func NewFile(conf Config, mgr types.Manager, log log.Modular, stats metrics.Type) (types.Cache, error) {
    51  	return cache.NewV2ToV1Cache(&fileV2{dir: conf.File.Directory}, stats), nil
    52  }
    53  
    54  type fileV2 struct {
    55  	dir string
    56  }
    57  
    58  func (f *fileV2) Get(_ context.Context, key string) ([]byte, error) {
    59  	b, err := os.ReadFile(filepath.Join(f.dir, key))
    60  	if os.IsNotExist(err) {
    61  		return nil, types.ErrKeyNotFound
    62  	}
    63  	return b, err
    64  }
    65  
    66  func (f *fileV2) Set(_ context.Context, key string, value []byte, _ *time.Duration) error {
    67  	return os.WriteFile(filepath.Join(f.dir, key), value, 0o644)
    68  }
    69  
    70  func (f *fileV2) SetMulti(ctx context.Context, keyValues map[string]types.CacheTTLItem) error {
    71  	for k, v := range keyValues {
    72  		if err := f.Set(ctx, k, v.Value, v.TTL); err != nil {
    73  			return err
    74  		}
    75  	}
    76  	return nil
    77  }
    78  
    79  func (f *fileV2) Add(_ context.Context, key string, value []byte, _ *time.Duration) error {
    80  	file, err := os.OpenFile(filepath.Join(f.dir, key), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o644)
    81  	if err != nil {
    82  		if os.IsExist(err) {
    83  			return types.ErrKeyAlreadyExists
    84  		}
    85  		return err
    86  	}
    87  	if _, err = file.Write(value); err != nil {
    88  		file.Close()
    89  		return err
    90  	}
    91  	return file.Close()
    92  }
    93  
    94  func (f *fileV2) Delete(_ context.Context, key string) error {
    95  	return os.Remove(filepath.Join(f.dir, key))
    96  }
    97  
    98  func (f *fileV2) Close(context.Context) error {
    99  	return nil
   100  }
   101  
   102  //------------------------------------------------------------------------------
   103  
   104  // File is a file system based cache implementation.
   105  //
   106  // TODO: V4 remove this
   107  //
   108  // Deprecated: This implementation is no longer used.
   109  type File struct {
   110  	dir string
   111  }
   112  
   113  // Get attempts to locate and return a cached value by its key, returns an error
   114  // if the key does not exist.
   115  //
   116  // Deprecated: This implementation is no longer used.
   117  func (f *File) Get(key string) ([]byte, error) {
   118  	b, err := os.ReadFile(filepath.Join(f.dir, key))
   119  	if os.IsNotExist(err) {
   120  		return nil, types.ErrKeyNotFound
   121  	}
   122  	return b, err
   123  }
   124  
   125  // Set attempts to set the value of a key.
   126  //
   127  // Deprecated: This implementation is no longer used.
   128  func (f *File) Set(key string, value []byte) error {
   129  	return os.WriteFile(filepath.Join(f.dir, key), value, 0o644)
   130  }
   131  
   132  // SetMulti attempts to set the value of multiple keys, returns an error if any
   133  // keys fail.
   134  //
   135  // Deprecated: This implementation is no longer used.
   136  func (f *File) SetMulti(items map[string][]byte) error {
   137  	for k, v := range items {
   138  		if err := f.Set(k, v); err != nil {
   139  			return err
   140  		}
   141  	}
   142  	return nil
   143  }
   144  
   145  // Add attempts to set the value of a key only if the key does not already exist
   146  // and returns an error if the key already exists.
   147  //
   148  // Deprecated: This implementation is no longer used.
   149  func (f *File) Add(key string, value []byte) error {
   150  	file, err := os.OpenFile(filepath.Join(f.dir, key), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o644)
   151  	if err != nil {
   152  		if os.IsExist(err) {
   153  			return types.ErrKeyAlreadyExists
   154  		}
   155  		return err
   156  	}
   157  	if _, err = file.Write(value); err != nil {
   158  		file.Close()
   159  		return err
   160  	}
   161  	return file.Close()
   162  }
   163  
   164  // Delete attempts to remove a key.
   165  //
   166  // Deprecated: This implementation is no longer used.
   167  func (f *File) Delete(key string) error {
   168  	return os.Remove(filepath.Join(f.dir, key))
   169  }
   170  
   171  // CloseAsync shuts down the cache.
   172  //
   173  // Deprecated: This implementation is no longer used.
   174  func (f *File) CloseAsync() {
   175  }
   176  
   177  // WaitForClose blocks until the cache has closed down.
   178  //
   179  // Deprecated: This implementation is no longer used.
   180  func (f *File) WaitForClose(timeout time.Duration) error {
   181  	return nil
   182  }