file

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2023 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package file provides some easy to use methods for caching file information.

The contents of a file may be cached, with automatic invalidation provided with the github.com/fsnotify/fsnotify library. The actual file bytes may be used with NewFileCache or NewEagerFileCache.

Alternatively, reading the file's contents and decoding it can be combined into a single function with NewReaderCache. The Value returned will store the decoded form for easy retrieval.

If you need to perform some action in response to the file being changed, then use OnInvalidate on the Value returned from any of these functions.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewEagerFileCache

func NewEagerFileCache(ctx context.Context, filename string, log NotifyLog) (*cache.Value[[]byte], error)

NewEagerFileCache is the same as NewFileCache, except that it will proactively read the file's contents into memory.

func NewFileCache

func NewFileCache(ctx context.Context, filename string, log NotifyLog) (*cache.Value[[]byte], error)

NewFileCache creates a new cache.Value that reads the given file in its loader.

func NewReaderCache

func NewReaderCache[T any](ctx context.Context, filename string, readFunc func(io.Reader) (T, error), log NotifyLog) (*cache.Value[T], error)

NewReaderCache returns a cache of a type extracted from the watched file. Whatever type is produced from readFunc will be the type of the cache.Value, which makes this useful for unmarshalling a file's contents into a user defined type.

Example
dir, cleanup := _mkTmp()
defer cleanup()
dataFile := filepath.Join(dir, "test.json")

type myData struct {
	A string `json:"a"`
	B string `json:"b"`
}
err := os.WriteFile(dataFile, []byte(`{"a":"a","b":"b"}`), 0644)
if err != nil {
	panic(err)
}

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
val, err := NewReaderCache[myData](ctx, dataFile, func(reader io.Reader) (myData, error) {
	var data myData
	err := json.NewDecoder(reader).Decode(&data)
	return data, err
}, StdLog())
val.OnInvalidate(func() {
	fmt.Println("data invalidated")
	cancel()
})

data, err := val.Get()
if err != nil {
	panic(err)
}
fmt.Printf("A:%s,B:%s\n", data.A, data.B)
val.Invalidate()
<-ctx.Done()
if !errors.Is(ctx.Err(), context.Canceled) {
	panic("Context should have been cancelled")
}
Output:

A:a,B:b
data invalidated

Types

type NotifyLog

type NotifyLog interface {
	Event(event fsnotify.Event)
	UnrelatedEvent(event fsnotify.Event)
	Error(err error)
}

NotifyLog provides a way for filesystem changes to be logged. This allows for easily plugging in your logger of choice.

func StdLog

func StdLog() NotifyLog

StdLog creates an instance of NotifyLog that uses the standard log package. Unrelated events will not be logged.

Example
package main

import (
	"errors"
	"github.com/fsnotify/fsnotify"
	"testing"
)

var _ NotifyLog = (*testNotifyLog)(nil)

type testNotifyLog struct {
	t           *testing.T
	failOnError bool
}

func testingLog(t *testing.T) NotifyLog {
	return &testNotifyLog{t: t, failOnError: true}
}

func (t *testNotifyLog) Event(event fsnotify.Event) {
	t.t.Logf("Received event [%s] %s", event.Op.String(), event.Name)
}

func (t *testNotifyLog) UnrelatedEvent(event fsnotify.Event) {
	t.t.Logf("Received unrelated event [%s] %s", event.Op.String(), event.Name)
}

func (t *testNotifyLog) Error(err error) {
	var log func(msg string, args ...any)
	if t.failOnError {
		log = t.t.Errorf
	} else {
		log = t.t.Logf
	}
	log("Error: %v", err)
}

func main() {
	log := StdLog()

	// Called by the fsnotify goroutine when a filesystem event is dispatched.
	log.Event(fsnotify.Event{
		Name: "some-file.txt",
		Op:   fsnotify.Write,
	})

	// Called by the fsnotify goroutine.
	log.Error(errors.New("something bad happened"))

}
Output:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL