Immediately recalculate summary when folder state changes syncing->idle
This commit is contained in:
parent
454e688c3d
commit
e4dba99cc0
@ -21,6 +21,7 @@ type folderSummarySvc struct {
|
|||||||
model *model.Model
|
model *model.Model
|
||||||
srv suture.Service
|
srv suture.Service
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
|
immediate chan string
|
||||||
|
|
||||||
// For keeping track of folders to recalculate for
|
// For keeping track of folders to recalculate for
|
||||||
foldersMut sync.Mutex
|
foldersMut sync.Mutex
|
||||||
@ -32,6 +33,7 @@ func (c *folderSummarySvc) Serve() {
|
|||||||
srv.Add(serviceFunc(c.listenForUpdates))
|
srv.Add(serviceFunc(c.listenForUpdates))
|
||||||
srv.Add(serviceFunc(c.calculateSummaries))
|
srv.Add(serviceFunc(c.calculateSummaries))
|
||||||
|
|
||||||
|
c.immediate = make(chan string)
|
||||||
c.stop = make(chan struct{})
|
c.stop = make(chan struct{})
|
||||||
c.folders = make(map[string]struct{})
|
c.folders = make(map[string]struct{})
|
||||||
c.srv = srv
|
c.srv = srv
|
||||||
@ -50,7 +52,7 @@ func (c *folderSummarySvc) Stop() {
|
|||||||
// listenForUpdates subscribes to the event bus and makes note of folders that
|
// listenForUpdates subscribes to the event bus and makes note of folders that
|
||||||
// need their data recalculated.
|
// need their data recalculated.
|
||||||
func (c *folderSummarySvc) listenForUpdates() {
|
func (c *folderSummarySvc) listenForUpdates() {
|
||||||
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated)
|
sub := events.Default.Subscribe(events.LocalIndexUpdated | events.RemoteIndexUpdated | events.StateChanged)
|
||||||
defer events.Default.Unsubscribe(sub)
|
defer events.Default.Unsubscribe(sub)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -63,9 +65,29 @@ func (c *folderSummarySvc) listenForUpdates() {
|
|||||||
|
|
||||||
data := ev.Data.(map[string]interface{})
|
data := ev.Data.(map[string]interface{})
|
||||||
folder := data["folder"].(string)
|
folder := data["folder"].(string)
|
||||||
|
|
||||||
|
if ev.Type == events.StateChanged && data["to"].(string) == "idle" && data["from"].(string) == "syncing" {
|
||||||
|
// The folder changed to idle from syncing. We should do an
|
||||||
|
// immediate refresh to update the GUI. The send to
|
||||||
|
// c.immediate must be nonblocking so that we can continue
|
||||||
|
// handling events.
|
||||||
|
|
||||||
|
select {
|
||||||
|
case c.immediate <- folder:
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
delete(c.folders, folder)
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This folder needs to be refreshed whenever we do the next
|
||||||
|
// refresh.
|
||||||
|
|
||||||
c.foldersMut.Lock()
|
c.foldersMut.Lock()
|
||||||
c.folders[folder] = struct{}{}
|
c.folders[folder] = struct{}{}
|
||||||
c.foldersMut.Unlock()
|
c.foldersMut.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
case <-c.stop:
|
case <-c.stop:
|
||||||
return
|
return
|
||||||
@ -82,6 +104,29 @@ func (c *folderSummarySvc) calculateSummaries() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-pump.C:
|
case <-pump.C:
|
||||||
|
t0 := time.Now()
|
||||||
|
for _, folder := range c.foldersToHandle() {
|
||||||
|
c.sendSummary(folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to spend all our time calculating summaries. Lets
|
||||||
|
// set an arbitrary limit at not spending more than about 30% of
|
||||||
|
// our time here...
|
||||||
|
wait := 2*time.Since(t0) + pumpInterval
|
||||||
|
pump.Reset(wait)
|
||||||
|
|
||||||
|
case folder := <-c.immediate:
|
||||||
|
c.sendSummary(folder)
|
||||||
|
|
||||||
|
case <-c.stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// foldersToHandle returns the list of folders needing a summary update, and
|
||||||
|
// clears the list.
|
||||||
|
func (c *folderSummarySvc) foldersToHandle() []string {
|
||||||
// We only recalculate sumamries if someone is listening to events
|
// We only recalculate sumamries if someone is listening to events
|
||||||
// (a request to /rest/events has been made within the last
|
// (a request to /rest/events has been made within the last
|
||||||
// pingEventInterval).
|
// pingEventInterval).
|
||||||
@ -92,10 +137,22 @@ func (c *folderSummarySvc) calculateSummaries() {
|
|||||||
// we can query about this kind of thing?
|
// we can query about this kind of thing?
|
||||||
last := lastEventRequest
|
last := lastEventRequest
|
||||||
lastEventRequestMut.Unlock()
|
lastEventRequestMut.Unlock()
|
||||||
|
|
||||||
t0 := time.Now()
|
|
||||||
if time.Since(last) < pingEventInterval {
|
if time.Since(last) < pingEventInterval {
|
||||||
for _, folder := range c.foldersToHandle() {
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c.foldersMut.Lock()
|
||||||
|
res := make([]string, 0, len(c.folders))
|
||||||
|
for folder := range c.folders {
|
||||||
|
res = append(res, folder)
|
||||||
|
delete(c.folders, folder)
|
||||||
|
}
|
||||||
|
c.foldersMut.Unlock()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendSummary send the summary events for a single folder
|
||||||
|
func (c *folderSummarySvc) sendSummary(folder string) {
|
||||||
// The folder summary contains how many bytes, files etc
|
// The folder summary contains how many bytes, files etc
|
||||||
// are in the folder and how in sync we are.
|
// are in the folder and how in sync we are.
|
||||||
data := folderSummary(c.model, folder)
|
data := folderSummary(c.model, folder)
|
||||||
@ -124,32 +181,6 @@ func (c *folderSummarySvc) calculateSummaries() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// We don't want to spend all our time calculating summaries. Lets
|
|
||||||
// set an arbitrary limit at not spending more than about 30% of
|
|
||||||
// our time here...
|
|
||||||
wait := 2*time.Since(t0) + pumpInterval
|
|
||||||
pump.Reset(wait)
|
|
||||||
|
|
||||||
case <-c.stop:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// foldersToHandle returns the list of folders needing a summary update, and
|
|
||||||
// clears the list.
|
|
||||||
func (c *folderSummarySvc) foldersToHandle() []string {
|
|
||||||
c.foldersMut.Lock()
|
|
||||||
res := make([]string, 0, len(c.folders))
|
|
||||||
for folder := range c.folders {
|
|
||||||
res = append(res, folder)
|
|
||||||
delete(c.folders, folder)
|
|
||||||
}
|
|
||||||
c.foldersMut.Unlock()
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// serviceFunc wraps a function to create a suture.Service without stop
|
// serviceFunc wraps a function to create a suture.Service without stop
|
||||||
// functionality.
|
// functionality.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user