Local Scan Request Cache Documentation
This code implements a local in-memory cache for attendance scan requests and their approvals, aiming to optimize performance by reducing database reads.
LocalScanRequest struct
type LocalScanRequest struct {
wg sync.WaitGroup
mtx sync.Mutex
dao *daos.Dao
ScanRequest []entity.AttendanceRequestTable
IndexedScanRequest map[string]*entity.AttendanceRequestTable
ScanRequestRead bool
ScanRequestApproval []entity.AttendanceRequestApprovalTable
MapScanRequestApproval map[string][]*entity.AttendanceRequestApprovalTable // key = ScanRequest.ID
ScanRequestApprovalRead bool
StartDate time.Time // for read again
EndDate time.Time // for read again
CompanyID string // for read again
}
wg sync.WaitGroup: Manages asynchronous database operations.mtx sync.Mutex: Ensures thread-safe access to the cache.dao *daos.Dao: The PocketBase DAO.ScanRequest []entity.AttendanceRequestTable: Slice of scan requests.IndexedScanRequest map[string]*entity.AttendanceRequestTable: Scan requests indexed by ID.ScanRequestRead bool: Indicates if scan requests have been read from the database.ScanRequestApproval []entity.AttendanceRequestApprovalTable: Slice of scan request approvals.MapScanRequestApproval map[string][]*entity.AttendanceRequestApprovalTable: Approvals mapped by scan request ID.ScanRequestApprovalRead bool: Indicates if scan request approvals have been read.StartDate time.Time: The start date of the cached range.EndDate time.Time: The end date of the cached range.CompanyID string: The company ID for which data is cached.
globalLocalScanRequest Variable
var globalLocalScanRequest = LocalScanRequest{}
A global instance of LocalScanRequest (singleton pattern).
Functions
NewScanRequestCache(dao *daos.Dao, companyID, calcDate string, read bool) *LocalScanRequest
Creates a new LocalScanRequest instance.
dao: The PocketBase DAO.companyID: The company ID.calcDate: The calculation date.read: If true, reads data from the database immediately.
GetGlobalScanRequest() *LocalScanRequest
Returns the global LocalScanRequest instance.
SetDao(dao *daos.Dao) *LocalScanRequest
Sets the DAO for the instance.
GetDao() *daos.Dao
Gets the DAO for the instance.
WaitFinishReadDB()
Waits for asynchronous database operations to complete.
ResetMaps(request, approval bool)
Clears the specified cache maps (requests and/or approvals) to avoid memory leaks.
IsCompanyDateInCache(companyID, calcDate string) bool
Checks if the specified company ID and date are within the cached range.
ReadAgain(companyID, calcDate string, force bool) *LocalScanRequest
Reloads data from the database if force is true, if the date is outside the cached range, or if data hasn't been read yet.
ReadAllScanRequests(companyID string, calcDate string)
Reads all scan requests and their approvals for the specified company and date range from the database, populating the cache.
FindScanRequestByUserIDAndDate(userID, calcDate string) []*entity.AttendanceRequestTable
Finds scan requests by user ID and date.
Example Usage
dao := // ... obtain your PocketBase DAO
companyID := "your_company_id"
calcDate := "2024-05-01"
// Create a new ScanRequestCache and immediately read data
scanRequestCache := caching.NewScanRequestCache(dao, companyID, calcDate, true)
// Find scan requests by user ID and date
userScanRequests := scanRequestCache.FindScanRequestByUserIDAndDate("user_id_123", "2024-05-10")
// Force a cache refresh
scanRequestCache.ReadAgain(companyID, calcDate, true)
Improvements and Considerations
- Error Handling: Improve error handling in functions like
ReadAllScanRequestsby returning errors instead of just logging them. - Cache Invalidation: Implement a proper cache invalidation strategy (time-based or event-driven) to ensure data consistency.
- Singleton Pattern: Evaluate the use of the singleton pattern (
globalLocalScanRequest). Dependency injection offers better testability and flexibility. - Code Clarity and Comments: Improve code comments to explain complex logic more clearly.
- Locking Granularity: Finer-grained locking (e.g., separate mutexes for requests and approvals) could improve concurrency.
This comprehensive documentation provides a detailed understanding of the LocalScanRequest cache and its functionalities. By addressing the suggested improvements, you can create a more robust and maintainable caching solution.