go-aptproxy/storage.go

58 lines
1.4 KiB
Go
Raw Normal View History

2016-04-24 09:32:32 +02:00
package main
import (
"crypto/md5"
"fmt"
"os"
"path"
"sync"
)
// Storage provides read and write access to items in the cache. In order to
// avoid race conditions, adding and testing for entries in the cache are
// protected by a mutex.
type Storage struct {
2016-04-25 10:01:01 +02:00
directory string
writers map[string]*Writer
writerDone chan *Writer
mutex sync.Mutex
2016-04-24 09:32:32 +02:00
}
2016-04-25 10:01:01 +02:00
// NewStorage creates a new storage manager.
func NewStorage(directory string) *Storage {
return &Storage{
directory: directory,
writers: make(map[string]*Writer),
writerDone: make(chan *Writer),
}
}
// GetReader returns a *Reader for the specified URL. If the file does not
2016-04-24 09:32:32 +02:00
// exist, both a writer (for downloading the file) and a reader are created.
2016-04-25 10:01:01 +02:00
func (s *Storage) GetReader(url string) (*Reader, error) {
2016-04-24 09:32:32 +02:00
var (
hash = string(md5.Sum([]byte(url)))
2016-04-25 10:01:01 +02:00
jsonFilename = path.Join(s.directory, fmt.Sprintf("%s.json", hash))
dataFilename = path.Join(s.directory, fmt.Sprintf("%s.data", hash))
2016-04-24 09:32:32 +02:00
)
s.mutex.Lock()
defer s.mutex.Unlock()
2016-04-25 10:01:01 +02:00
w, ok := s.writers[hash]
if ok {
return NewReader(w, jsonFilename, dataFilename), nil
} else {
_, err := os.Stat(jsonFilename)
if err != nil {
if os.IsNotExist(err) {
w = NewWriter(url, jsonFilename, dataFilename, s.writerDone)
s.writers[hash] = w
return NewReader(w, jsonFilename, dataFilename), nil
} else {
return nil, err
}
2016-04-24 09:32:32 +02:00
} else {
2016-04-25 10:01:01 +02:00
return NewReader(nil, jsonFilename, dataFilename), nil
2016-04-24 09:32:32 +02:00
}
}
}