Skip to main content

Local Schedules Cache Documentation

This code implements a local in-memory cache for schedules and their details, aiming to improve performance by reducing database interactions.

LocalSchedule Struct

type LocalSchedule struct {
wg sync.WaitGroup
mtx SafeMutex
dao *daos.Dao

SchedulesUpdated []string
ScheduleDetailsUpdated []string

Schedules map[string]entity.ScheduleTable // key = schedule_id
SchedulesRead bool
SchedulesMapByShortLabel map[string]*entity.ScheduleTable
SchedulesMappedByShort bool

DetailsRead bool
DetailsMapped bool
ScheduleDetails map[string]entity.ScheduleDetail
ScheduleDetailsMapped map[string][]*entity.ScheduleDetail // key = schedule_id
CompanyID string
}
  • wg sync.WaitGroup: Used to wait for asynchronous database operations.
  • mtx SafeMutex: A mutex for thread-safe access. (Likely adds extra safety checks compared to a standard mutex).
  • dao *daos.Dao: The PocketBase DAO.
  • SchedulesUpdated []string: Slice of schedule IDs that have been updated and need to be saved to the database.
  • ScheduleDetailsUpdated []string: Slice of schedule detail IDs that have been updated.
  • Schedules map[string]entity.ScheduleTable: Stores schedules, keyed by schedule_id.
  • SchedulesRead bool: A flag indicating whether schedules have been read from the database.
  • SchedulesMapByShortLabel map[string]*entity.ScheduleTable: Schedules indexed by short label.
  • SchedulesMappedByShort bool: Flag indicating whether the short label map has been populated.
  • DetailsRead bool: Flag for schedule details read status.
  • DetailsMapped bool: Flag for schedule details mapped status.
  • ScheduleDetails map[string]entity.ScheduleDetail: Stores schedule details, keyed by schedule_detail_id.
  • ScheduleDetailsMapped map[string][]*entity.ScheduleDetail: Schedule details mapped by schedule_id.
  • CompanyID string: The company ID.

globalLocalSchedules Variable

var globalLocalSchedules = LocalSchedule{}

A global instance of LocalSchedule (singleton pattern).

Functions

NewSchedulesCache(dao *daos.Dao, companyID string, read bool) *LocalSchedule

Creates a new LocalSchedule instance.

  • dao: The PocketBase DAO.
  • companyID: The company ID.
  • read: If true, reads data from the database immediately.

GetGlobalLocalSchedules() *LocalSchedule

Returns the global LocalSchedule instance.

SetDao(dao *daos.Dao) *LocalSchedule

Sets the DAO for the instance.

GetDao() *daos.Dao

Returns the DAO of the instance.

WaitFinishReadDB()

Waits for asynchronous database read operations to finish.

UpdateDB(details bool) error

Updates the database with changes made to schedules and their details (if details is true). Handles partial update failures by keeping track of unsaved changes.

ResetMaps(schedule, detail bool)

Resets the internal maps, clearing the cached data. schedule and detail flags control which maps are reset.

ReadAgain(companyID string, force bool) *LocalSchedule

Reads schedules and details from the database again if force is true or data hasn't been read yet, or if the companyID has changed.

ReadAllSchedulesWithDetails(companyID string)

Reads all schedules and their details for the given companyID and populates the cache. Performs database operations asynchronously.

ReadAllScheduleDetailsFromScheduleDays()

Reads and maps schedule details based on schedule days information from the database. Runs asynchronously and updates the Schedules map with the new ScheduleDetails.

FindScheduleDetailsByDate(calcDate time.Time, activeScheduleID string) []*entity.ScheduleDetail

Finds schedule details for a given date and schedule ID. Supports daily and weekly cycle types.

FindDailyCycleScheduleDetailsByCycle(calcDate time.Time, activeSchedule entity.ScheduleTable) []*entity.ScheduleDetail

Finds schedule details for daily cycles based on the calculated cycle index.

FindWeeklyScheduleDetailsByCycleAndDay(calcDate time.Time, activeSchedule entity.ScheduleTable) []*entity.ScheduleDetail

Finds schedule details for weekly cycles based on the week number within the month and the day of the week.

DebugPrint(id string)

Prints debug information about the cached schedules and details. If an id is provided, it filters the output to show only the schedule with that ID.

FindScheduleIDByShortLabel(short string) string

Finds a schedule ID by its short label. Returns an empty string if not found.

NeedToSaveSchedules() bool

Checks if any schedules need to be saved to the database.

NumberSchedulesNeedUpdated() int

Returns the number of schedules that need updating.

NeedToSaveScheduleDetails() bool

Checks if any schedule details need saving.

NumberScheduleDetailsNeedUpdated() int

Returns the number of schedule details that need updating.

AddScheduleIDToUpdateLater(id string)

Adds a schedule ID to the list of schedules that need to be updated later.

DebugChange() / DebugChangeRevert()

Debug functions to simulate changes to a schedule.

PrintCache()

Prints the cached schedule details as a JSON string.

MapSchedulesByShortLabel()

Maps schedules by their short labels, if not already mapped.

FindScheduleByShortLabel(shortLabel string) *entity.ScheduleTable

Finds a schedule by its short label. Returns nil if not found.

Example Usage

dao := // ... obtain your PocketBase DAO
companyID := "your_company_id"
scheduleCache := caching.NewSchedulesCache(dao, companyID, true)


// Find schedule details for a specific date and schedule
details := scheduleCache.FindScheduleDetailsByDate(time.Now(), "schedule_id_abc")

// ... use the details

// Find a schedule by short label
schedule := scheduleCache.FindScheduleByShortLabel("weekly_schedule")

if schedule != nil {
fmt.Printf("Found schedule: %+v\n", *schedule)
}

// Refresh the cache
scheduleCache.ReadAgain(companyID, true)


Improvements and Considerations

  • Error Handling: Improve error handling in functions like ReadAllSchedulesWithDetails by returning errors instead of just logging them.
  • Cache Invalidation: Implement a proper cache invalidation strategy (time-based or event-driven).
  • Singleton Pattern: Evaluate the singleton pattern (globalLocalSchedules). Dependency injection is often a more flexible and testable approach.
  • SafeMutex: Document the specific safety features provided by SafeMutex.
  • Code Clarity: Remove commented-out code blocks and unused variables for better readability.
  • Locking Granularity: Consider using separate mutexes for schedules and details to improve concurrency.

This revised documentation provides a comprehensive explanation of the LocalSchedule cache and its functionalities. By understanding its components, developers can effectively leverage this cache to improve their application's performance. Be sure to address the suggested improvements for a more robust and maintainable solution.