mirror of
https://git.sr.ht/~sircmpwn/tokidoki
synced 2025-12-12 14:17:21 +01:00
storage/filesystem: add R/W locking
This commit adds read/write locking for individual files, so that concurrent requests (e.g. to read and write the same file) cannot interfere with one another. The locking is not very fine-grained at the moment, and can probably be improved upon. But it does ensure consistency.
This commit is contained in:
parent
7969df1a38
commit
6eeea854be
3 changed files with 88 additions and 2 deletions
|
|
@ -85,6 +85,9 @@ func (b *filesystemBackend) loadAllCalendarObjects(ctx context.Context, urlPath
|
|||
return nil
|
||||
}
|
||||
|
||||
b.RLock(filename)
|
||||
defer b.RUnlock(filename)
|
||||
|
||||
cal, err := calendarFromFile(filename, propFilter)
|
||||
if err != nil {
|
||||
fmt.Printf("load calendar error for %s: %v\n", filename, err)
|
||||
|
|
@ -138,7 +141,12 @@ func (b *filesystemBackend) createDefaultCalendar(ctx context.Context) (*caldav.
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating default calendar: %s", err.Error())
|
||||
}
|
||||
err = os.WriteFile(path.Join(localPath, calendarFileName), blob, 0644)
|
||||
|
||||
filename := path.Join(localPath, calendarFileName)
|
||||
b.Lock(filename)
|
||||
defer b.Unlock(filename)
|
||||
|
||||
err = os.WriteFile(filename, blob, 0644)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error writing default calendar: %s", err.Error())
|
||||
}
|
||||
|
|
@ -167,6 +175,10 @@ func (b *filesystemBackend) ListCalendars(ctx context.Context) ([]caldav.Calenda
|
|||
}
|
||||
|
||||
calPath := path.Join(filename, calendarFileName)
|
||||
|
||||
b.RLock(calPath)
|
||||
defer b.RUnlock(calPath)
|
||||
|
||||
data, err := os.ReadFile(calPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
|
|
@ -209,6 +221,9 @@ func (b *filesystemBackend) GetCalendar(ctx context.Context, urlPath string) (*c
|
|||
|
||||
log.Debug().Str("path", localPath).Msg("loading calendar")
|
||||
|
||||
b.RLock(localPath)
|
||||
defer b.RUnlock(localPath)
|
||||
|
||||
data, err := os.ReadFile(localPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
|
|
@ -237,6 +252,9 @@ func (b *filesystemBackend) GetCalendarObject(ctx context.Context, objPath strin
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.RLock(localPath)
|
||||
defer b.RUnlock(localPath)
|
||||
|
||||
info, err := os.Stat(localPath)
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
|
|
@ -320,6 +338,9 @@ func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath strin
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.Lock(localPath)
|
||||
defer b.Unlock(localPath)
|
||||
|
||||
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
||||
// TODO handle IfNoneMatch == ETag
|
||||
if opts.IfNoneMatch.IsWildcard() {
|
||||
|
|
@ -384,6 +405,10 @@ func (b *filesystemBackend) DeleteCalendarObject(ctx context.Context, path strin
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.Lock(localPath)
|
||||
defer b.Unlock(localPath)
|
||||
|
||||
err = os.Remove(localPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue