cache: delay Plex connection to the first read handle - fixes #1903

This commit is contained in:
remusb 2017-12-12 00:46:08 +02:00
parent 829dd1ad25
commit 84701e376a
3 changed files with 45 additions and 31 deletions

15
cache/cache.go vendored
View file

@ -301,14 +301,11 @@ func NewFs(name, rpath string) (fs.Fs, error) {
f.plexConnector = &plexConnector{}
if plexURL != "" {
usingPlex := false
if plexToken != "" {
f.plexConnector, err = newPlexConnectorWithToken(f, plexURL, plexToken)
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to the Plex API %v", plexURL)
}
usingPlex = true
} else {
plexUsername := fs.ConfigFileGet(name, "plex_username")
plexPassword := fs.ConfigFileGet(name, "plex_password")
@ -321,20 +318,8 @@ func NewFs(name, rpath string) (fs.Fs, error) {
if err != nil {
return nil, errors.Wrapf(err, "failed to connect to the Plex API %v", plexURL)
}
if f.plexConnector.token != "" {
fs.ConfigFileSet(name, "plex_token", f.plexConnector.token)
fs.SaveConfig()
}
usingPlex = true
}
}
if usingPlex {
fs.Infof(name, "Connected to Plex server: %v", plexURL)
// when connected to a Plex server we default to 1 worker (Plex scans all the time)
// and leave max workers as a setting to scale out the workers on demand during playback
f.totalWorkers = 1
}
}
dbPath := *cacheDbPath

16
cache/handle.go vendored
View file

@ -70,7 +70,21 @@ func (r *Handle) startReadWorkers() {
if r.hasAtLeastOneWorker() {
return
}
r.scaleWorkers(r.cacheFs().totalWorkers)
totalWorkers := r.cacheFs().totalWorkers
if r.cacheFs().plexConnector.isConfigured() {
if !r.cacheFs().plexConnector.isConnected() {
err := r.cacheFs().plexConnector.authenticate()
if err != nil {
fs.Infof(r, "failed to authenticate to Plex: %v", err)
}
}
if r.cacheFs().plexConnector.isConnected() {
totalWorkers = 1
}
}
r.scaleWorkers(totalWorkers)
}
// scaleOutWorkers will increase the worker pool count by the provided amount

45
cache/plex.go vendored
View file

@ -10,6 +10,8 @@ import (
"strings"
"time"
"sync"
"github.com/ncw/rclone/fs"
)
@ -20,9 +22,12 @@ const (
// plexConnector is managing the cache integration with Plex
type plexConnector struct {
url *url.URL
token string
f *Fs
url *url.URL
username string
password string
token string
f *Fs
mu sync.Mutex
}
// newPlexConnector connects to a Plex server and generates a token
@ -33,14 +38,11 @@ func newPlexConnector(f *Fs, plexURL, username, password string) (*plexConnector
}
pc := &plexConnector{
f: f,
url: u,
token: "",
}
err = pc.authenticate(username, password)
if err != nil {
return nil, err
f: f,
url: u,
username: username,
password: password,
token: "",
}
return pc, nil
@ -74,10 +76,13 @@ func (p *plexConnector) fillDefaultHeaders(req *http.Request) {
}
// authenticate will generate a token based on a username/password
func (p *plexConnector) authenticate(username, password string) error {
func (p *plexConnector) authenticate() error {
p.mu.Lock()
defer p.mu.Unlock()
form := url.Values{}
form.Set("user[login]", username)
form.Add("user[password]", password)
form.Set("user[login]", p.username)
form.Add("user[password]", p.password)
req, err := http.NewRequest("POST", defPlexLoginURL, strings.NewReader(form.Encode()))
if err != nil {
return err
@ -101,15 +106,25 @@ func (p *plexConnector) authenticate(username, password string) error {
return fmt.Errorf("failed to obtain token: %v", data)
}
p.token = token
if p.token != "" {
fs.ConfigFileSet(p.f.Name(), "plex_token", p.token)
fs.SaveConfig()
fs.Infof(p.f.Name(), "Connected to Plex server: %v", p.url.String())
}
return nil
}
// isConnected checks if this Plex
// isConnected checks if this rclone is authenticated to Plex
func (p *plexConnector) isConnected() bool {
return p.token != ""
}
// isConfigured checks if this rclone is configured to use a Plex server
func (p *plexConnector) isConfigured() bool {
return p.url != nil
}
func (p *plexConnector) isPlaying(co *Object) bool {
isPlaying := false
req, err := http.NewRequest("GET", fmt.Sprintf("%s/status/sessions", p.url.String()), nil)