Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
creativecreature committed Jul 8, 2024
1 parent ce5fb56 commit c503ee1
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 45 deletions.
36 changes: 5 additions & 31 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,16 @@ linters:
- asciicheck # checks that your code does not contain non-ASCII identifiers
- bidichk # checks for dangerous unicode character sequences
- bodyclose # checks whether HTTP response body is closed successfully
# - cyclop # checks function and package cyclomatic complexity
- cyclop # checks function and package cyclomatic complexity
- dupl # tool for code clone detection
- durationcheck # checks for two durations multiplied together
- errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
- errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
- execinquery # checks query string in Query function which reads your Go src files and warning it finds
- exhaustive # checks exhaustiveness of enum switch statements
- exportloopref # checks for pointers to enclosing loop variables
- forbidigo # forbids identifiers
- funlen # tool for detection of long functions
- gocheckcompilerdirectives # validates go compiler directive comments (//go:)
# - gochecknoglobals # checks that no global variables exist
- gochecknoinits # checks that no init functions are present in Go code
- gochecksumtype # checks exhaustiveness on Go "sum types"
- gocognit # computes and checks the cognitive complexity of functions
Expand Down Expand Up @@ -115,7 +113,7 @@ linters:

## disabled
# - lll # reports long lines
# - exhaustruct # [highly recommend to enable] checks if all structure fields are initialized
# - exhaustruct # [highly recommend to enable] checks if all structure fields are initializedgolangci
#- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages
#- dupword # [useless without config] checks for duplicate words in the source code
#- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted
Expand Down Expand Up @@ -163,33 +161,9 @@ linters-settings:
nlreturn:
block-size: 8

exhaustruct:
# Default: []
exclude:
- ".*_test.go$"
# std libs
- "^net/http.Client$"
- "^net/http.Cookie$"
- "^net/http.Request$"
- "^net/http.Response$"
- "^net/http.Server$"
- "^net/http.Transport$"
- "^net/url.URL$"
- "^os/exec.Cmd$"
- "^reflect.StructField$"
# public libs
- "^github.com/Shopify/sarama.Config$"
- "^github.com/Shopify/sarama.ProducerMessage$"
- "^github.com/mitchellh/mapstructure.DecoderConfig$"
- "^github.com/prometheus/client_golang/.+Opts$"
- "^github.com/spf13/cobra.Command$"
- "^github.com/spf13/cobra.CompletionOptions$"
- "^github.com/stretchr/testify/mock.Mock$"
- "^github.com/testcontainers/testcontainers-go.+Request$"
- "^github.com/testcontainers/testcontainers-go.FromDockerfile$"
- "^golang.org/x/tools/go/analysis.Analyzer$"
- "^google.golang.org/protobuf/.+Options$"
- "^gopkg.in/yaml.v3.Node$"
gosec:
excludes:
- G404 # Ignore insecure random number source.

funlen:
# Checks the number of lines in a function.
Expand Down
8 changes: 4 additions & 4 deletions distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func distributedBatchFetch[V, T any](c *Client[T], keyFn KeyFn, fetchFn BatchFet
}

return func(ctx context.Context, ids []string) (map[string]V, error) {
// We need to be able to lookup the ID of the record based on the key.
// We need to be able to look up the ID of the record based on the key.
keyIDMap := make(map[string]string, len(ids))
keys := make([]string, 0, len(ids))
for _, id := range ids {
Expand Down Expand Up @@ -193,7 +193,7 @@ func distributedBatchFetch[V, T any](c *Client[T], keyFn KeyFn, fetchFn BatchFet

// If distributedStaleStorage isn't enabled it means all records are fresh, otherwise checked the CreatedAt time.
if !c.distributedEarlyRefreshes || c.clock.Since(record.CreatedAt) < c.distributedRefreshAfterDuration {
// We never wan't to return missing records.
// We never want to return missing records.
if !record.IsMissingRecord {
fresh[id] = record.Value
} else {
Expand All @@ -205,7 +205,7 @@ func distributedBatchFetch[V, T any](c *Client[T], keyFn KeyFn, fetchFn BatchFet
idsToRefresh = append(idsToRefresh, id)
c.reportDistributedRefresh()

// We never wan't to return missing records.
// We never want to return missing records.
if !record.IsMissingRecord {
stale[id] = record.Value
} else {
Expand All @@ -218,7 +218,7 @@ func distributedBatchFetch[V, T any](c *Client[T], keyFn KeyFn, fetchFn BatchFet
}

dataSourceResponses, err := fetchFn(ctx, idsToRefresh)
// Incase of an error, we'll proceed with the ones we got from the distributed storage.
// In case of an error, we'll proceed with the ones we got from the distributed storage.
if err != nil {
for i := 0; i < len(stale); i++ {
c.reportDistributedStaleFallback()
Expand Down
4 changes: 2 additions & 2 deletions keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestTimeBasedKeys(t *testing.T) {
}
}

func TestPermutatedRelativeTimeKeys(t *testing.T) {
func TestPermutedTimeKeys(t *testing.T) {
t.Parallel()

c := sturdyc.New[any](100, 1, time.Hour, 5,
Expand Down Expand Up @@ -169,7 +169,7 @@ func TestPermutatedKeyHandlesEmptySlices(t *testing.T) {
}
}

func TestPermutatedBatchKeyFn(t *testing.T) {
func TestPermutedBatchKeyFn(t *testing.T) {
t.Parallel()

c := sturdyc.New[any](100, 1, time.Hour, 5,
Expand Down
10 changes: 5 additions & 5 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ type MetricsRecorder interface {
// Refresh is called when a get operation results in a refresh.
Refresh()
// MissingRecord is called every time the cache is asked to
// lookup a key which has been marked as missing.
// look up a key which has been marked as missing.
MissingRecord()
// ForcedEviction is called when the cache reaches its capacity, and has to
// evict keys in order to write a new one.
ForcedEviction()
// EntiresEvicted is called when the cache evicts keys from a shard.
// EntriesEvicted is called when the cache evicts keys from a shard.
EntriesEvicted(int)
// ShardIndex is called to report which shard it was that performed an operation.
ShardIndex(int)
// CacheBatchRefreshSize is called to report the size of the batch refresh.
CacheBatchRefreshSize(size int)
// ObserveCacheSize is called to report the size of the cache.metri
// ObserveCacheSize is called to report the size of the cache.
ObserveCacheSize(callback func() int)
}

type DistributedMetricsRecorder interface {
MetricsRecorder
// DistributedCacheHit is called for every key that results in a cache hit.
DistributedCacheHit()
// DistributedCacheHit is called for every key that results in a cache miss.
// DistributedCacheMiss is called for every key that results in a cache miss.
DistributedCacheMiss()
// DistributedRefresh is called when we retrieve a record from
// the distributed storage that should be refreshed.
DistributedRefresh()
// DistributetedMissingRecord is called when we retrieve a record from the
// DistributedMissingRecord is called when we retrieve a record from the
// distributed storage that has been marked as a missing record.
DistributedMissingRecord()
// DistributedFallback is called when you are using a distributed storage
Expand Down
2 changes: 1 addition & 1 deletion options.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func WithRelativeTimeKeyFormat(truncation time.Duration) Option {

// WithLog allows you to set a custom logger for the cache. The cache isn't chatty,
// and will only log warnings and errors that would be a nightmare to debug. If you
// absolutely don't want any logs, you can pass in the sturydc.NoopLogger.
// absolutely don't want any logs, you can pass in the sturdyc.NoopLogger.
func WithLog(log Logger) Option {
return func(c *Config) {
c.log = log
Expand Down
20 changes: 19 additions & 1 deletion passthrough.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,25 @@ func (c *Client[T]) PassthroughBatch(ctx context.Context, ids []string, keyFn Ke
return res, err
}

// Passthrough is a convenience function that performs type assertion on the result of client.PassthroughBatch.
// Passthrough is a convenience function that performs type assertion on the
// result of client.PassthroughBatch.
//
// Parameters:
//
// ctx - the context to be used for the request.
// c - the cache client.
// ids - the list of ids to be fetched.
// keyFn - used to generate the cache key for each id.
// fetchFn - used to retrieve the data from the underlying data source.
//
// Returns:
//
// A map of ids to their corresponding values and an error if one occurred.
//
// Type Parameters:
//
// V - The type returned by the fetchFn. Must be assignable to T.
// T - The type stored in the cache.
func PassthroughBatch[V, T any](ctx context.Context, c *Client[T], ids []string, keyFn KeyFn, fetchFn BatchFetchFn[V]) (map[string]V, error) {
res, err := c.PassthroughBatch(ctx, ids, keyFn, wrapBatch[T](fetchFn))
return unwrapBatch[V](res, err)
Expand Down
5 changes: 4 additions & 1 deletion shard.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ func (s *shard[T]) get(key string) (val T, exists, markedAsMissing, refresh bool
return item.value, true, item.isMissingRecord, false
}

// set sets a key-value pair in the shard. Returns true if it triggered an eviction.
// set writes a key-value pair to the shard and returns a
// boolean indicating whether an eviction was performed.
func (s *shard[T]) set(key string, value T, isMissingRecord bool) bool {
s.Lock()
defer s.Unlock()
Expand Down Expand Up @@ -147,12 +148,14 @@ func (s *shard[T]) set(key string, value T, isMissingRecord bool) bool {
return evict
}

// delete removes a key from the shard.
func (s *shard[T]) delete(key string) {
s.Lock()
defer s.Unlock()
delete(s.entries, key)
}

// keys returns all non-expired keys in the shard.
func (s *shard[T]) keys() []string {
s.RLock()
defer s.RUnlock()
Expand Down

0 comments on commit c503ee1

Please sign in to comment.