Skip to content
This repository has been archived by the owner on Jul 6, 2023. It is now read-only.

Commit

Permalink
perf(cache): cache plex clients and servers
Browse files Browse the repository at this point in the history
  • Loading branch information
ttshivers committed Aug 30, 2020
1 parent 889f800 commit b798e4e
Show file tree
Hide file tree
Showing 20 changed files with 122 additions and 71 deletions.
8 changes: 3 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@
fluid
>
<v-container
v-if="!GET_CONFIG
|| !IS_DONE_FETCHING_DEVICES && $route.matched.some((record) => record.meta.protected)"
v-if="!GET_CONFIG"
fill-height
>
<v-row
Expand Down Expand Up @@ -152,13 +151,13 @@
</template>

<script>
// Custom css
import './assets/css/style.css';
import {
mapActions, mapGetters, mapMutations, mapState,
} from 'vuex';
import redirection from '@/mixins/redirection';
import { slPlayerClientId } from '@/player/constants';
export default {
components: {
Expand Down Expand Up @@ -205,7 +204,6 @@ export default {
...mapGetters('plex', [
'GET_PLEX_AUTH_TOKEN',
'IS_DONE_FETCHING_DEVICES',
]),
...mapGetters('plexclients', [
Expand Down Expand Up @@ -289,7 +287,7 @@ export default {
GET_ACTIVE_MEDIA_METADATA(metadata) {
// This handles regular plex clients (nonslplayer) playback changes
if (this.IS_IN_ROOM && this.GET_CHOSEN_CLIENT_ID !== 'PTPLAYER9PLUS10') {
if (this.IS_IN_ROOM && this.GET_CHOSEN_CLIENT_ID !== slPlayerClientId) {
if (metadata) {
this.redirectToMediaPage();
} else if (this.$route.fullPath.indexOf('/nowplaying') > -1) {
Expand Down
5 changes: 0 additions & 5 deletions src/components/plex/clientpicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,12 @@ export default {
},
},
async created() {
await this.FETCH_PLEX_DEVICES_IF_NEEDED();
},
beforeDestroy() {
this.cancelRequests();
},
methods: {
...mapActions('plex', [
'FETCH_PLEX_DEVICES_IF_NEEDED',
'FETCH_PLEX_DEVICES',
]),
Expand Down
33 changes: 15 additions & 18 deletions src/components/sidebars/leftsidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,23 @@
</v-list-item-content>
</v-list-item>

<template v-if="IS_DONE_FETCHING_DEVICES">
<v-list-item
@click.stop="plexsettingstoggle = !plexsettingstoggle"
>
<v-list-item-icon>
<v-icon color="white">
settings
</v-icon>
</v-list-item-icon>
<v-list-item
@click.stop="plexsettingstoggle = !plexsettingstoggle"
>
<v-list-item-icon>
<v-icon color="white">
settings
</v-icon>
</v-list-item-icon>

<v-list-item-content>
<v-list-item-title>Plex Settings</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item-content>
<v-list-item-title>Plex Settings</v-list-item-title>
</v-list-item-content>
</v-list-item>

<v-subheader>
Account
</v-subheader>
</template>
<v-subheader>
Account
</v-subheader>

<v-list-item
:router="true"
Expand Down Expand Up @@ -209,7 +207,6 @@ export default {
...mapState(['isLeftSidebarOpen']),
...mapGetters('plex', [
'IS_DONE_FETCHING_DEVICES',
'GET_PLEX_USER',
]),
Expand Down
3 changes: 2 additions & 1 deletion src/components/sidebars/rightsidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import contentTitle from '@/mixins/contentTitle';
import { slPlayerClientId } from '@/player/constants';
export default {
components: {
Expand Down Expand Up @@ -299,7 +300,7 @@ export default {
]),
usingPlexClient() {
return this.GET_CHOSEN_CLIENT_ID !== 'PTPLAYER9PLUS10';
return this.GET_CHOSEN_CLIENT_ID !== slPlayerClientId;
},
},
Expand Down
9 changes: 2 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ router.beforeEach(async (to, from, next) => {
await store.dispatch('FETCH_CONFIG');
}

if (store.getters['plex/GET_PLEX_AUTH_TOKEN']
&& !store.getters['plex/IS_DONE_FETCHING_DEVICES']) {
await store.dispatch('plex/FETCH_PLEX_DEVICES_IF_NEEDED');
}

if ((!store.getters['plex/IS_AUTHENTICATED']
if ((store.getters['plex/IS_UNAUTHORIZED']
&& to.matched.some((record) => record.meta.requiresAuth))
|| (!store.getters['plex/GET_PLEX_AUTH_TOKEN']
&& to.matched.some((record) => record.meta.requiresPlexToken))) {
Expand All @@ -37,7 +32,7 @@ router.beforeEach(async (to, from, next) => {
next({ name: 'Signin' });
}
} else if (to.matched.some((record) => record.meta.requiresNoAuth)
&& store.getters['plex/IS_AUTHENTICATED']) {
&& store.getters['plex/GET_PLEX_AUTH_TOKEN']) {
next({ name: 'CreateRoom' });
} else if (!store.getters['synclounge/IS_IN_ROOM']
&& to.matched.some((record) => record.meta.protected)) {
Expand Down
2 changes: 2 additions & 0 deletions src/player/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// eslint-disable-next-line import/prefer-default-export
export const slPlayerClientId = 'PTPLAYER9PLUS10';
4 changes: 4 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ const persistedState = createPersistedState({
'plex.user',
'plex.plexAuthToken',
'plex.clientIdentifier',
'plex.areDevicesCached',

'plexclients.clients',

'plexservers.servers',
'plexservers.lastServerId',
'plexservers.blockedServerIds',

Expand Down
39 changes: 35 additions & 4 deletions src/store/modules/plex/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import promiseutils from '@/utils/promiseutils';
import { fetchJson, queryFetch } from '@/utils/fetchutils';
import { difference } from '@/utils/lightlodash';
import { slPlayerClientId } from '@/player/constants';

export default {
FETCH_PLEX_INIT_AUTH: async ({ getters }, signal) => fetchJson(
Expand Down Expand Up @@ -44,7 +46,15 @@ export default {
},

// Private function, please use FETCH_PLEX_DEVICES instead
_FETCH_PLEX_DEVICES: async ({ commit, dispatch, getters }) => {
_FETCH_PLEX_DEVICES: async ({
commit, dispatch, getters, rootGetters,
}) => {
// Store old list of server/client ids, to be able to take difference after the update and
// find devices that weren't updated and remove them
const oldClientIds = rootGetters['plexclients/GET_PLEX_CLIENT_IDS']
.filter((clientId) => clientId !== slPlayerClientId);
const oldServersIds = rootGetters['plexservers/GET_PLEX_SERVER_IDS'];

const devices = await fetchJson('https://plex.tv/api/v2/resources', {
...getters.GET_PLEX_BASE_PARAMS(),
includeHttps: 1,
Expand All @@ -70,8 +80,29 @@ export default {
}
}));

if (!getters.IS_DONE_FETCHING_DEVICES) {
commit('SET_DONE_FETCHING_DEVICES', true);
// Find devices that weren't updated
const staleClientIds = difference([
oldClientIds,
rootGetters['plexclients/GET_PLEX_CLIENT_IDS'],
]);

staleClientIds.forEach((clientId) => {
commit('plexclients/DELETE_PLEX_CLIENT', clientId, { root: true });
});

const staleServerIds = difference([
oldServersIds,
rootGetters['plexservers/GET_PLEX_SERVER_IDS'],
]);

staleServerIds.forEach((serverId) => {
commit('plexservers/DELETE_PLEX_SERVER', serverId, { root: true });
});

commit('plexclients/UPDATE_SLPLAYER_LAST_SEEN_TO_NOW', null, { root: true });

if (!getters.ARE_DEVICES_CACHED) {
commit('SET_ARE_DEVICES_CACHED', true);
}
},

Expand All @@ -89,7 +120,7 @@ export default {

// Use this to trigger a fetch if you don't need the devices refreshed
FETCH_PLEX_DEVICES_IF_NEEDED: async ({ getters, dispatch }) => {
if (!getters.IS_DONE_FETCHING_DEVICES) {
if (!getters.ARE_DEVICES_CACHED && getters.GET_DEVICE_FETCH_PROMISE == null) {
await dispatch('FETCH_PLEX_DEVICES');
}
},
Expand Down
6 changes: 3 additions & 3 deletions src/store/modules/plex/getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { makeUrl } from '@/utils/fetchutils';
const capitalizeFirstLetter = (string) => string[0].toUpperCase() + string.slice(1);

export default {
IS_AUTHENTICATED: (state, getters) => !!getters.GET_PLEX_AUTH_TOKEN
&& getters.IS_USER_AUTHORIZED,
IS_UNAUTHORIZED: (state, getters) => !getters.GET_PLEX_AUTH_TOKEN
|| (getters.ARE_DEVICES_CACHED && !getters.IS_USER_AUTHORIZED),

GET_PLEX_DEVICE_NAME: (state, getters, rootState, rootGetters) => {
switch (rootGetters.GET_BROWSER.name) {
Expand Down Expand Up @@ -70,7 +70,7 @@ export default {
return makeUrl('https://app.plex.tv/auth#', urlParams);
},

IS_DONE_FETCHING_DEVICES: (state) => state.doneFetchingDevices,
ARE_DEVICES_CACHED: (state) => state.areDevicesCached,
GET_DEVICE_FETCH_PROMISE: (state) => state.deviceFetchPromise,
GET_PLEX_USER: (state) => state.user,

Expand Down
4 changes: 2 additions & 2 deletions src/store/modules/plex/mutations.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export default {
Object.assign(state, stateFactory());
},

SET_DONE_FETCHING_DEVICES: (state, done) => {
state.doneFetchingDevices = done;
SET_ARE_DEVICES_CACHED: (state, cached) => {
state.areDevicesCached = cached;
},

SET_DEVICE_FETCH_PROMISE: (state, promise) => {
Expand Down
2 changes: 1 addition & 1 deletion src/store/modules/plex/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';

const state = () => ({
user: null,
doneFetchingDevices: false,
areDevicesCached: false,
deviceFetchPromise: null,
plexAuthToken: null,
clientIdentifier: uuidv4(),
Expand Down
27 changes: 14 additions & 13 deletions src/store/modules/plexclients/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import CAF from 'caf';
import promiseutils from '@/utils/promiseutils';
import contentTitleUtils from '@/utils/contenttitleutils';
import { fetchXmlAndTransform } from '@/utils/fetchutils';
import { slPlayerClientId } from '@/player/constants';

export default {
FIND_AND_SET_CONNECTION: async ({ dispatch, commit }, { clientIdentifier, signal }) => {
Expand All @@ -15,7 +16,7 @@ export default {
// if any of them return a valid response we'll set that connection
// as the chosen connection for future use.

if (clientIdentifier === 'PTPLAYER9PLUS10') {
if (clientIdentifier === slPlayerClientId) {
return true;
}

Expand Down Expand Up @@ -80,7 +81,7 @@ export default {

commit('SET_ACTIVE_PLAY_QUEUE_MACHINE_IDENTIFIER', machineIdentifier);

if (getters.GET_CHOSEN_CLIENT_ID === 'PTPLAYER9PLUS10') {
if (getters.GET_CHOSEN_CLIENT_ID === slPlayerClientId) {
commit('SET_ACTIVE_MEDIA_METADATA', metadata);
commit('SET_ACTIVE_SERVER_ID', machineIdentifier);
commit('plexservers/SET_LAST_SERVER_ID', machineIdentifier, { root: true });
Expand Down Expand Up @@ -288,7 +289,7 @@ export default {
// or asks slplayer since it can do that with no delay
FETCH_TIMELINE_POLL_DATA_CACHE: ({ getters, dispatch }) => {
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/FETCH_TIMELINE_POLL_DATA', null, { root: true });
}

Expand All @@ -300,7 +301,7 @@ export default {

FETCH_TIMELINE_POLL_DATA: async ({ getters, dispatch }) => {
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/FETCH_TIMELINE_POLL_DATA', null, { root: true });
}

Expand All @@ -321,7 +322,7 @@ export default {
// TODO: make sure all them hit here and fix the id lol
// todo: also store the command id above because it might have changed during the awaits
// TODO: also update this when pausing or playign so we don't have werid stuff
if (getters.GET_CHOSEN_CLIENT_ID !== 'PTPLAYER9PLUS10') {
if (getters.GET_CHOSEN_CLIENT_ID !== slPlayerClientId) {
commit('SET_PREVIOUS_SYNC_TIMELINE_COMMAND_ID', getters.GET_PLEX_CLIENT_TIMELINE_COMMAND_ID);
}
},
Expand All @@ -345,7 +346,7 @@ export default {
// Decide what seeking method we want to use

// Adjust seek time by the time it takes to send a request to the client
const offset = getters.GET_CHOSEN_CLIENT_ID !== 'PTPLAYER9PLUS10'
const offset = getters.GET_CHOSEN_CLIENT_ID !== slPlayerClientId
&& rootGetters['synclounge/GET_HOST_USER'].state === 'playing'
? adjustedHostTime + getters.GET_LATENCY
: adjustedHostTime;
Expand All @@ -359,7 +360,7 @@ export default {
}

// TODO: make difference config value
if (getters.GET_CHOSEN_CLIENT_ID === 'PTPLAYER9PLUS10'
if (getters.GET_CHOSEN_CLIENT_ID === slPlayerClientId
&& absDifference > rootGetters.GET_CONFIG.slplayer_soft_seek_threshold) {
return dispatch('slplayer/SOFT_SEEK', adjustedHostTime, { root: true });
}
Expand All @@ -369,7 +370,7 @@ export default {

PRESS_PLAY: async ({ getters, dispatch }, cancelSignal) => {
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/PRESS_PLAY', null, { root: true });
}

Expand All @@ -388,7 +389,7 @@ export default {

PRESS_PAUSE: ({ getters, dispatch }, cancelSignal) => {
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/PRESS_PAUSE', null, { root: true });
}

Expand All @@ -406,7 +407,7 @@ export default {

PRESS_STOP: async ({ getters, dispatch }) => {
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/PRESS_STOP', null, { root: true });
}

Expand All @@ -426,7 +427,7 @@ export default {
SEEK_TO: async ({ getters, dispatch }, { cancelSignal, offset }) => {
console.debug('SEEK_TO', offset);
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
return dispatch('slplayer/SPEED_OR_NORMAL_SEEK', { cancelSignal, seekToMs: offset },
{ root: true });
}
Expand Down Expand Up @@ -504,7 +505,7 @@ export default {
PLAY_NEXT: ({ getters, rootGetters, dispatch }, metadata) => {
console.debug('plexclients/PLAY_NEXT');
switch (getters.GET_CHOSEN_CLIENT_ID) {
case 'PTPLAYER9PLUS10': {
case slPlayerClientId: {
if (rootGetters['slplayer/IS_PLAYER_INITIALIZED']) {
return dispatch('slplayer/PLAY_NEXT', null, { root: true });
}
Expand Down Expand Up @@ -533,7 +534,7 @@ export default {
START_CLIENT_POLLER_IF_NEEDED: async ({
getters, commit, dispatch, rootGetters,
}) => {
if (getters.GET_CHOSEN_CLIENT_ID !== 'PTPLAYER9PLUS10'
if (getters.GET_CHOSEN_CLIENT_ID !== slPlayerClientId
&& !getters.GET_CLIENT_POLLER_CANCEL_TOKEN) {
// eslint-disable-next-line new-cap
const cancelToken = new CAF.cancelToken();
Expand Down
Loading

0 comments on commit b798e4e

Please sign in to comment.