Local Setting Cache Documentation
This code implements a local in-memory cache for rounding settings and company settings to improve performance by reducing database reads.
LocalSetting struct
type LocalSetting struct {
wg sync.WaitGroup
mtx sync.Mutex
dao *daos.Dao
IndexedRoundingSetting map[string]*entity.RoundingSettingTable
CompanySettings *entity.CompanyTable
AutoShifRule string
}
wg sync.WaitGroup: Used to wait for asynchronous database read operations to complete.mtx sync.Mutex: Used to protect shared data during concurrent access (prevents race conditions).dao *daos.Dao: A PocketBase DAO (Data Access Object) used to interact with the database.IndexedRoundingSetting map[string]*entity.RoundingSettingTable: Stores rounding settings, indexed by a string key (likely the setting ID or a relevant identifier).CompanySettings *entity.CompanyTable: Stores the settings for a specific company.AutoShifRule string: Stores the autoshift rule for the company.
globalLocalSetting variable
var globalLocalSetting = LocalSetting{}
A global instance of the LocalSetting struct. This suggests a singleton pattern where this single instance is used throughout the application.
ReadAllSettings(companyId string) method
func (l *LocalSetting) ReadAllSettings(companyId string)
Reads all necessary settings from the database and populates the cache.
- Takes the
companyIdas a parameter to retrieve company-specific settings. - Uses a mutex (
l.mtx) to prevent race conditions during concurrent access. - Uses a wait group (
l.wg) to ensure the asynchronous database reads complete before continuing. - Logs errors and informational messages using
slog. - Reads rounding settings using
queries.GetMappedRoundSetting. - Reads company settings using
queries.GetCompanyById. - Caches the
AutoshiftRulefrom the company settings, defaulting to "formula" if not set.
GetGlobalLocalSetting() function
func GetGlobalLocalSetting() *LocalSetting {
return &globalLocalSetting
}
Returns a pointer to the global LocalSetting instance.
SetDao(dao *daos.Dao) *LocalSetting method
func (l *LocalSetting) SetDao(dao *daos.Dao) *LocalSetting {
l.dao = dao
return l
}
Sets the DAO for the LocalSetting instance. This is crucial as it provides the means to interact with the database.
WaitFinishReadDB() method
func (l *LocalSetting) WaitFinishReadDB() {
l.wg.Wait()
}
Waits for all database read operations initiated by ReadAllSettings to complete.
NewRoundingSettingCache(dao *daos.Dao, read bool, companyId string) *LocalSetting function
func NewRoundingSettingCache(dao *daos.Dao, read bool, companyId string) *LocalSetting
Creates a new LocalSetting instance.
dao: The DAO to use for database interaction.read: A boolean flag indicating whether to immediately read settings from the database.companyId: The ID of the company for which to load settings.- If
readis true, callsReadAllSettingsandWaitFinishReadDBto populate the cache synchronously.
Usage Example
dao := // ... get your PocketBase DAO
cache := caching.NewRoundingSettingCache(dao, true, "your_company_id")
// ... use cache.IndexedRoundingSetting, cache.CompanySettings, etc.
Improvements & Considerations
- Error Handling: While errors are logged, they are not explicitly returned. Consider returning errors to allow calling functions to handle them appropriately.
- Cache Invalidation: The current implementation doesn't have a mechanism for cache invalidation. If data changes in the database, the cache will become stale. Consider adding logic to refresh the cache periodically or on specific events.
- Configuration: Hardcoding "formula" as the default
AutoShifRulemight be inflexible. Consider making this configurable. - Singleton vs. Instantiation: Evaluate if the singleton pattern (
globalLocalSetting) is the best approach. Dependency injection might offer more flexibility and testability.
This documentation provides a comprehensive overview of the local setting cache implementation. By understanding its components and usage, you can effectively leverage it to optimize your application's performance. Remember to address the suggested improvements for a more robust and maintainable solution.