Fixed a couple of logic bugs.
This commit is contained in:
parent
b233dd8e92
commit
8e53208882
59
cache/livereader.go
vendored
59
cache/livereader.go
vendored
@ -9,41 +9,29 @@ import (
|
|||||||
|
|
||||||
// liveReader reads a file from disk, synchronizing reads with a downloader.
|
// liveReader reads a file from disk, synchronizing reads with a downloader.
|
||||||
type liveReader struct {
|
type liveReader struct {
|
||||||
downloader *downloader
|
downloader *downloader
|
||||||
file *os.File
|
dataFilename string
|
||||||
watcher *fsnotify.Watcher
|
file *os.File
|
||||||
entry *Entry
|
entry *Entry
|
||||||
done chan error
|
done chan error
|
||||||
err error
|
err error
|
||||||
eof bool
|
eof bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// newLiveReader creates a reader from the provided downloader and data
|
// newLiveReader creates a reader from the provided downloader and data
|
||||||
// file. fsnotify is used to watch for writes to the file to avoid using a
|
// file. fsnotify is used to watch for writes to the file to avoid using a
|
||||||
// spinloop. Invoking this function assumes the existence of the data file.
|
// spinloop. Invoking this function assumes the existence of the data file.
|
||||||
func newLiveReader(d *downloader, dataFilename string) (*liveReader, error) {
|
func newLiveReader(d *downloader, dataFilename string) (*liveReader, error) {
|
||||||
f, err := os.Open(dataFilename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
w, err := fsnotify.NewWatcher()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err = w.Add(dataFilename); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
l := &liveReader{
|
l := &liveReader{
|
||||||
downloader: d,
|
downloader: d,
|
||||||
file: f,
|
dataFilename: dataFilename,
|
||||||
watcher: w,
|
done: make(chan error),
|
||||||
done: make(chan error),
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
defer close(l.done)
|
defer close(l.done)
|
||||||
l.done <- d.WaitForDone()
|
l.done <- d.WaitForDone()
|
||||||
}()
|
}()
|
||||||
return l, err
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read attempts to read as much data as possible into the provided buffer.
|
// Read attempts to read as much data as possible into the provided buffer.
|
||||||
@ -54,7 +42,25 @@ func (l *liveReader) Read(p []byte) (int, error) {
|
|||||||
if l.err != nil {
|
if l.err != nil {
|
||||||
return 0, l.err
|
return 0, l.err
|
||||||
}
|
}
|
||||||
|
if l.file == nil {
|
||||||
|
f, err := os.Open(l.dataFilename)
|
||||||
|
if err != nil {
|
||||||
|
l.err = err
|
||||||
|
return 0, l.err
|
||||||
|
}
|
||||||
|
l.file = f
|
||||||
|
}
|
||||||
bytesRead := 0
|
bytesRead := 0
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
l.err = err
|
||||||
|
return 0, l.err
|
||||||
|
}
|
||||||
|
defer watcher.Close()
|
||||||
|
if err := watcher.Add(l.dataFilename); err != nil {
|
||||||
|
l.err = err
|
||||||
|
return 0, l.err
|
||||||
|
}
|
||||||
loop:
|
loop:
|
||||||
for bytesRead < len(p) {
|
for bytesRead < len(p) {
|
||||||
n, err := l.file.Read(p[bytesRead:])
|
n, err := l.file.Read(p[bytesRead:])
|
||||||
@ -66,7 +72,7 @@ loop:
|
|||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case e := <-l.watcher.Events:
|
case e := <-watcher.Events:
|
||||||
if e.Op&fsnotify.Write != fsnotify.Write {
|
if e.Op&fsnotify.Write != fsnotify.Write {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -83,7 +89,10 @@ loop:
|
|||||||
|
|
||||||
// Close attempts to close the data file (if opened).
|
// Close attempts to close the data file (if opened).
|
||||||
func (l *liveReader) Close() error {
|
func (l *liveReader) Close() error {
|
||||||
return l.file.Close()
|
if l.file != nil {
|
||||||
|
return l.file.Close()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEntry returns the Entry associated with the file, blocking until either
|
// GetEntry returns the Entry associated with the file, blocking until either
|
||||||
|
@ -56,6 +56,7 @@ func (s *Server) writeHeaders(w http.ResponseWriter, e *cache.Entry) {
|
|||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if req.Method != "GET" {
|
if req.Method != "GET" {
|
||||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
r, err := s.cache.GetReader(rewrite(req.RequestURI))
|
r, err := s.cache.GetReader(rewrite(req.RequestURI))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user