Skip to main content

Local Leaves Cache Documentation

This code implements a local in-memory cache for leave-related data (leaves, leave requests, and user leaves), aiming to improve performance by reducing database access.

LocalLeaves Struct

type LocalLeaves struct {
wg sync.WaitGroup
mtx sync.Mutex
dao *daos.Dao

Leaves []entity.LeavesTable
IndexedLeaves map[string]*entity.LeavesTable
LeavesRead bool

LeaveRequests []entity.LeaveRequestTable
IndexedLeaveRequests map[string]*entity.LeaveRequestTable
MapLeaveRequestsByUserID map[string][]*entity.LeaveRequestTable
LeaveRequestsRead bool

UserLeaves []entity.UserLeavesTable
IndexedUserLeaves map[string]*entity.UserLeavesTable
MapUserLeavesByUserID map[string][]*entity.UserLeavesTable
UserLeavesRead bool

Year int
StartDate time.Time
EndDate time.Time
CompanyID string
}
  • wg sync.WaitGroup: Manages asynchronous database operations.
    • mtx sync.Mutex: Ensures thread-safe cache access.
    • dao *daos.Dao: The PocketBase DAO for database interactions.
    • Leaves []entity.LeavesTable: Slice of leave types.
    • IndexedLeaves map[string]*entity.LeavesTable: Leave types indexed by ID.
    • LeavesRead bool: Indicates if leave types have been read.
    • LeaveRequests []entity.LeaveRequestTable: Slice of leave requests.
    • IndexedLeaveRequests map[string]*entity.LeaveRequestTable: Leave requests indexed by ID.
    • MapLeaveRequestsByUserID map[string][]*entity.LeaveRequestTable: Leave requests mapped by user ID.
    • LeaveRequestsRead bool: Indicates if leave requests have been read.
    • UserLeaves []entity.UserLeavesTable: Slice of user leaves.
    • IndexedUserLeaves map[string]*entity.UserLeavesTable: User leaves indexed by ID.
    • MapUserLeavesByUserID map[string][]*entity.UserLeavesTable: User leaves mapped by user ID.
    • UserLeavesRead bool: Indicates if user leaves have been read.
    • Year int: The year for which leaves are cached.
    • StartDate time.Time: Start date of the cached year.
    • EndDate time.Time: End date of the cached year.
    • CompanyID string: The company ID.

globalLocalLeaves Variable

var globalLocalLeaves = LocalLeaves{}

A global LocalLeaves instance (singleton pattern).

Functions

NewLeavesCache(dao *daos.Dao, companyID string, year int, read bool) *LocalLeaves

Creates a new LocalLeaves instance.

  • dao: The PocketBase DAO.
    • companyID: The company ID.
    • year: The year for which to cache leaves.
    • read: If true, reads data from the database immediately.

GetGlobalLocalLeaves() *LocalLeaves

Returns the global LocalLeaves instance.

SetDao(dao *daos.Dao) *LocalLeaves

Sets the DAO for the instance.

GetDao() *daos.Dao

Gets the DAO for the instance.

WaitFinishReadDB()

Waits for asynchronous database operations to finish.

ResetMaps(leaves, request, userleave bool)

Resets the specified cache maps (leaves, leave requests, and/or user leaves).

IsCompanyDateInCache(companyID, date string) bool

Checks if the provided company ID and date (year) match the cached data.

ReadAgain(companyID, date string, force bool) *LocalLeaves

Reloads leave data if force is true or if the company ID or year doesn't match the cached data.

ReadAllLeaves(companyID string, year int)

Reads all leave-related data (leaves, leave requests, user leaves) for the specified company and year from the database, populating the cache. It handles the case where year is not provided (defaults to the current year).

FindLeaveByUserIDAndDate(userID, date string) *entity.LeaveRequestTable

Finds a leave request by user ID and date. Returns nil if not found.

Example Usage

dao := // ... obtain your PocketBase DAO
companyID := "your_company_id"
year := 2024


// Create a LeavesCache and read data immediately
leavesCache := caching.NewLeavesCache(dao, companyID, year, true)

// Find a leave request
leaveRequest := leavesCache.FindLeaveByUserIDAndDate("user_id_123", "2024-07-15")

// Force a cache refresh
leavesCache.ReadAgain(companyID, "2025-01-01", true) // force=true refreshes even if the year is already cached


Improvements and Considerations

  • Error Handling: In ReadAllLeaves, return errors instead of just logging them for better error management in calling functions.
    • Cache Invalidation: Implement a suitable cache invalidation strategy (time-based or event-driven).
    • Singleton Pattern: Evaluate the singleton pattern (globalLocalLeaves). Dependency injection is generally preferred for testability and flexibility.
    • Date Handling: FindLeaveByUserIDAndDate only works with dates in "yyyy-mm-dd" format. Consider making it more flexible or documenting this limitation clearly.
    • Locking Granularity: Consider using finer-grained locking (e.g., separate mutexes for different data types) to improve concurrency.

This improved documentation provides a more comprehensive understanding of the LocalLeaves cache. By addressing the suggested improvements, you can create a more robust and efficient caching solution.# leavescacing