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