DEV Community

Bikash Mishra
Bikash Mishra

Posted on • Edited on

Introducing encache: A Powerful Caching Library for Go

In the world of software development, performance is king. One effective way to boost your application's performance is by caching expensive function calls. This is where the encache package comes into play. encache is a Go library that provides a caching mechanism for function calls, allowing you to cache the results of computationally intensive or I/O-bound operations, and retrieve them from the cache instead of recomputing them.

Features Galore

The encache package is packed with features that make caching a breeze:

  • Support for in-memory and Redis caching: Choose between caching in memory or using Redis, depending on your project's requirements.
  • Automatic cache expiration and periodic expiration of stale entries: Never worry about stale data clogging up your cache.
  • Locking mechanisms for thread-safety: Ensures your cached data remains consistent, even in concurrent scenarios.
  • Customizable cache key generation: Fine-tune how your cache keys are generated to suit your needs.
  • Option to cache function results even when errors occur: Errors won't halt the caching process, ensuring you always have data available.

Getting Started

Installing encache is a breeze, thanks to Go's built-in package management system:

go get github.com/forkbikash/encache
Enter fullscreen mode Exit fullscreen mode

Once installed, using encache is incredibly straightforward. Here's a simple example:

package main

import (
    "fmt"
    "time"
    "github.com/forkbikash/encache"
)

func expensiveOperation(a, b int) (int, error) {
    // Simulate an expensive operation
    time.Sleep(2 * time.Second)
    return a + b, nil
}

func main() {
    // Create a new in-memory cache implementation
    mapCache := encache.NewMapCacheImpl()
    cacheKeyImpl := encache.NewDefaultCacheKeyImpl()
    lockImpl := encache.NewMuLockImpl()

    // Create a new encache instance
    encache := encache.NewEncache(lockImpl, mapCache, cacheKeyImpl, false, time.Minute)

    // Wrap the expensive function with caching
    cachedExpensiveOperation := encache.CachedFunc(expensiveOperation, encache, time.Minute)

    // Call the cached function
    result, err := cachedExpensiveOperation(2, 3)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Result:", result)

    // Subsequent calls will retrieve the result from the cache
    result, err = cachedExpensiveOperation(2, 3)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Result (cached):", result)
}
Enter fullscreen mode Exit fullscreen mode

In this example, we create a new encache instance with an in-memory cache implementation (MapCacheImpl), a default cache key implementation (DefaultCacheKeyImpl), and a mutex-based lock implementation (MuLockImpl). We then wrap the expensiveOperation function with the CachedFunc function, which returns a new function that will cache the results of expensiveOperation.

Contributing

Contributions are what keep the open-source community vibrant and growing. If you have any improvements, bug fixes, or new features to propose, please open an issue or submit a pull request. We welcome all contributions!

Future Developments

The encache package is constantly evolving, and we have exciting plans for future developments:

  • Cache invalidation strategies: Aside from the simple expiration-based cache invalidation, we plan to add support for other strategies like manual invalidation, LRU (Least Recently Used) eviction, or event-based invalidation (e.g., invalidating the cache when the underlying data changes).
  • Monitoring and metrics: We aim to provide metrics and monitoring capabilities to help users understand the cache's performance, hit/miss rates, and other relevant statistics.
  • Adaptive caching: Implement an adaptive caching mechanism that can automatically adjust the cache size, eviction policy, or other parameters based on the workload and usage patterns.
  • Asynchronous cache updates: Provide an asynchronous cache update mechanism to allow for non-blocking cache population and update operations.
  • Change package structure: Reorganize the package structure to improve maintainability and extensibility.

Stay tuned for more updates and enhancements to the encache package!

I hope this article helps someone out there.

If you liked the post, you can find more by:

Tweet this post
Follow me on Twitter @forkbikash

Top comments (2)

Collapse
 
ccoveille profile image
Christophe Colombier

Interesting project, I will have a look and might review it if you are down for it

Collapse
 
forkbikash profile image
Bikash Mishra

Thank you Christophe. It would be nice if you can review the project.