Prepare for being able to start and stop folders at any time
This commit is contained in:
parent
25345f08e7
commit
f3057c61a7
@ -64,6 +64,11 @@ const (
|
|||||||
indexBatchSize = 1000 // Either way, don't include more files than this
|
indexBatchSize = 1000 // Either way, don't include more files than this
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type service interface {
|
||||||
|
Serve()
|
||||||
|
Stop()
|
||||||
|
}
|
||||||
|
|
||||||
type Model struct {
|
type Model struct {
|
||||||
indexDir string
|
indexDir string
|
||||||
cfg *config.Configuration
|
cfg *config.Configuration
|
||||||
@ -79,6 +84,7 @@ type Model struct {
|
|||||||
deviceFolders map[protocol.DeviceID][]string // deviceID -> folders
|
deviceFolders map[protocol.DeviceID][]string // deviceID -> folders
|
||||||
deviceStatRefs map[protocol.DeviceID]*stats.DeviceStatisticsReference // deviceID -> statsRef
|
deviceStatRefs map[protocol.DeviceID]*stats.DeviceStatisticsReference // deviceID -> statsRef
|
||||||
folderIgnores map[string]ignore.Patterns // folder -> list of ignore patterns
|
folderIgnores map[string]ignore.Patterns // folder -> list of ignore patterns
|
||||||
|
folderRunners map[string]service // folder -> puller or scanner
|
||||||
fmut sync.RWMutex // protects the above
|
fmut sync.RWMutex // protects the above
|
||||||
|
|
||||||
folderState map[string]folderState // folder -> state
|
folderState map[string]folderState // folder -> state
|
||||||
@ -116,6 +122,7 @@ func NewModel(indexDir string, cfg *config.Configuration, deviceName, clientName
|
|||||||
deviceFolders: make(map[protocol.DeviceID][]string),
|
deviceFolders: make(map[protocol.DeviceID][]string),
|
||||||
deviceStatRefs: make(map[protocol.DeviceID]*stats.DeviceStatisticsReference),
|
deviceStatRefs: make(map[protocol.DeviceID]*stats.DeviceStatisticsReference),
|
||||||
folderIgnores: make(map[string]ignore.Patterns),
|
folderIgnores: make(map[string]ignore.Patterns),
|
||||||
|
folderRunners: make(map[string]service),
|
||||||
folderState: make(map[string]folderState),
|
folderState: make(map[string]folderState),
|
||||||
folderStateChanged: make(map[string]time.Time),
|
folderStateChanged: make(map[string]time.Time),
|
||||||
protoConn: make(map[protocol.DeviceID]protocol.Connection),
|
protoConn: make(map[protocol.DeviceID]protocol.Connection),
|
||||||
@ -142,18 +149,22 @@ func NewModel(indexDir string, cfg *config.Configuration, deviceName, clientName
|
|||||||
func (m *Model) StartFolderRW(folder string) {
|
func (m *Model) StartFolderRW(folder string) {
|
||||||
m.fmut.Lock()
|
m.fmut.Lock()
|
||||||
cfg, ok := m.folderCfgs[folder]
|
cfg, ok := m.folderCfgs[folder]
|
||||||
m.fmut.Unlock()
|
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("cannot start nonexistent folder " + folder)
|
panic("cannot start nonexistent folder " + folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := Puller{
|
_, ok = m.folderRunners[folder]
|
||||||
|
if ok {
|
||||||
|
panic("cannot start already running folder " + folder)
|
||||||
|
}
|
||||||
|
p := &Puller{
|
||||||
folder: folder,
|
folder: folder,
|
||||||
dir: cfg.Path,
|
dir: cfg.Path,
|
||||||
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
|
scanIntv: time.Duration(cfg.RescanIntervalS) * time.Second,
|
||||||
model: m,
|
model: m,
|
||||||
}
|
}
|
||||||
|
m.folderRunners[folder] = p
|
||||||
|
m.fmut.Unlock()
|
||||||
|
|
||||||
if len(cfg.Versioning.Type) > 0 {
|
if len(cfg.Versioning.Type) > 0 {
|
||||||
factory, ok := versioner.Factories[cfg.Versioning.Type]
|
factory, ok := versioner.Factories[cfg.Versioning.Type]
|
||||||
@ -170,27 +181,25 @@ func (m *Model) StartFolderRW(folder string) {
|
|||||||
// read only mode the model will announce files to the cluster but not
|
// read only mode the model will announce files to the cluster but not
|
||||||
// pull in any external changes.
|
// pull in any external changes.
|
||||||
func (m *Model) StartFolderRO(folder string) {
|
func (m *Model) StartFolderRO(folder string) {
|
||||||
intv := time.Duration(m.folderCfgs[folder].RescanIntervalS) * time.Second
|
m.fmut.Lock()
|
||||||
initialScanCompleted := false
|
cfg, ok := m.folderCfgs[folder]
|
||||||
go func() {
|
if !ok {
|
||||||
for {
|
panic("cannot start nonexistent folder " + folder)
|
||||||
if debug {
|
}
|
||||||
l.Debugln(m, "rescan", folder)
|
|
||||||
}
|
|
||||||
|
|
||||||
m.setState(folder, FolderScanning)
|
_, ok = m.folderRunners[folder]
|
||||||
if err := m.ScanFolder(folder); err != nil {
|
if ok {
|
||||||
invalidateFolder(m.cfg, folder, err)
|
panic("cannot start already running folder " + folder)
|
||||||
return
|
}
|
||||||
}
|
s := &Scanner{
|
||||||
m.setState(folder, FolderIdle)
|
folder: folder,
|
||||||
if !initialScanCompleted {
|
intv: time.Duration(cfg.RescanIntervalS) * time.Second,
|
||||||
l.Infoln("Completed initial scan (ro) of folder", folder)
|
model: m,
|
||||||
initialScanCompleted = true
|
}
|
||||||
}
|
m.folderRunners[folder] = s
|
||||||
time.Sleep(intv)
|
m.fmut.Unlock()
|
||||||
}
|
|
||||||
}()
|
go s.Serve()
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConnectionInfo struct {
|
type ConnectionInfo struct {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user