vfs: add vfs/poll-interval rc command
This command can be used to query the current status of the poll-interval option and also update the value.
This commit is contained in:
parent
1eec59e091
commit
d9a3b26e47
1 changed files with 123 additions and 0 deletions
123
vfs/rc.go
123
vfs/rc.go
|
@ -3,6 +3,7 @@ package vfs
|
|||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ncw/rclone/fs"
|
||||
"github.com/ncw/rclone/fs/rc"
|
||||
|
@ -166,6 +167,128 @@ starting with dir will refresh that directory, eg
|
|||
If the parameter recursive=true is given the whole directory tree
|
||||
will get refreshed. This refresh will use --fast-list if enabled.
|
||||
|
||||
`,
|
||||
})
|
||||
rc.Add(rc.Call{
|
||||
Path: "vfs/poll-interval",
|
||||
Fn: rcPollFunc(vfs),
|
||||
Title: "Get the status or update the value of the poll-interval option.",
|
||||
Help: `
|
||||
Without any parameter given this returns the current status of the
|
||||
poll-interval setting.
|
||||
|
||||
When the interval=duration parameter is set, the poll-interval value
|
||||
is updated and the polling function is notified.
|
||||
Setting interval=0 disables poll-interval.
|
||||
|
||||
rclone rc vfs/poll-interval interval=5m
|
||||
|
||||
The timeout=duration parameter can be used to specify a time to wait
|
||||
for the current poll function to apply the new value.
|
||||
If timeout is less or equal 0, which is the default, wait indefinitely.
|
||||
|
||||
The new poll-interval value will only be active when the timeout is
|
||||
not reached.
|
||||
|
||||
If poll-interval is updated or disabled temporarily, some changes
|
||||
might not get picked up by the polling function, depending on the
|
||||
used remote.
|
||||
`,
|
||||
})
|
||||
}
|
||||
|
||||
func rcPollFunc(vfs *VFS) (rcPollFunc rc.Func) {
|
||||
getDuration := func(k string, v interface{}) (time.Duration, error) {
|
||||
s, ok := v.(string)
|
||||
if !ok {
|
||||
return 0, errors.Errorf("value must be string %q=%v", k, v)
|
||||
}
|
||||
interval, err := fs.ParseDuration(s)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "parse duration")
|
||||
}
|
||||
return interval, nil
|
||||
}
|
||||
getInterval := func(in rc.Params) (time.Duration, bool, error) {
|
||||
k := "interval"
|
||||
v, ok := in[k]
|
||||
if !ok {
|
||||
return 0, false, nil
|
||||
}
|
||||
interval, err := getDuration(k, v)
|
||||
if err != nil {
|
||||
return 0, true, err
|
||||
}
|
||||
if interval < 0 {
|
||||
return 0, true, errors.New("interval must be >= 0")
|
||||
}
|
||||
delete(in, k)
|
||||
return interval, true, nil
|
||||
}
|
||||
getTimeout := func(in rc.Params) (time.Duration, error) {
|
||||
k := "timeout"
|
||||
v, ok := in[k]
|
||||
if !ok {
|
||||
return 10 * time.Second, nil
|
||||
}
|
||||
timeout, err := getDuration(k, v)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
delete(in, k)
|
||||
return timeout, nil
|
||||
}
|
||||
|
||||
_status := func(in rc.Params) (out rc.Params, err error) {
|
||||
for k, v := range in {
|
||||
return nil, errors.Errorf("invalid parameter: %s=%s", k, v)
|
||||
}
|
||||
return rc.Params{
|
||||
"enabled": vfs.Opt.PollInterval != 0,
|
||||
"supported": vfs.pollChan != nil,
|
||||
"interval": map[string]interface{}{
|
||||
"raw": vfs.Opt.PollInterval,
|
||||
"seconds": vfs.Opt.PollInterval / time.Second,
|
||||
"string": vfs.Opt.PollInterval.String(),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
return func(in rc.Params) (out rc.Params, err error) {
|
||||
interval, intervalPresent, err := getInterval(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
timeout, err := getTimeout(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range in {
|
||||
return nil, errors.Errorf("invalid parameter: %s=%s", k, v)
|
||||
}
|
||||
if vfs.pollChan == nil {
|
||||
return nil, errors.New("poll-interval is not supported by this remote")
|
||||
}
|
||||
|
||||
if !intervalPresent {
|
||||
return _status(in)
|
||||
}
|
||||
var timeoutHit bool
|
||||
var timeoutChan <-chan time.Time
|
||||
if timeout > 0 {
|
||||
timer := time.NewTimer(timeout)
|
||||
defer timer.Stop()
|
||||
timeoutChan = timer.C
|
||||
}
|
||||
select {
|
||||
case vfs.pollChan <- interval:
|
||||
vfs.Opt.PollInterval = interval
|
||||
case <-timeoutChan:
|
||||
timeoutHit = true
|
||||
}
|
||||
out, err = _status(in)
|
||||
if out != nil {
|
||||
out["timeout"] = timeoutHit
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue