From 41483e67315a5861ad3fd63984ac47972d3ebafe Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 15:31:02 +0100 Subject: [PATCH 1/7] Add more exit points when synching --- resources/lib/library_sync/full_sync.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index 80973562..003452a8 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -410,7 +410,7 @@ class FullSync(common.fullsync_mixin): def _run(self): self.current_sync = timing.plex_now() # Get latest Plex libraries and build playlist and video node files - if not sections.sync_from_pms(self): + if self.isCanceled() or not sections.sync_from_pms(self): return self.successful = True try: @@ -422,10 +422,7 @@ class FullSync(common.fullsync_mixin): # Actual syncing - do only new items first LOG.info('Running full_library_sync with repair=%s', self.repair) - if not self.full_library_sync(): - self.successful = False - return - if self.isCanceled(): + if self.isCanceled() or not self.full_library_sync(): self.successful = False return if common.PLAYLIST_SYNC_ENABLED and not playlists.full_sync(): From 37bbf61a632b48ca436544ff6c31904db59d8d9b Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 15:33:42 +0100 Subject: [PATCH 2/7] Ensure that reference to threader is gone on shutdown --- resources/lib/library_sync/full_sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index 003452a8..fadd6968 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -434,6 +434,7 @@ class FullSync(common.fullsync_mixin): self.dialog.close() if self.threader: self.threader.shutdown() + self.threader = None if not self.successful and not self.isCanceled(): # "ERROR in library sync" utils.dialog('notification', From 3c70a8470422a22917f0523c0d6cbb2c53c15a35 Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 15:42:29 +0100 Subject: [PATCH 3/7] Catch all exceptions, just in case --- resources/lib/library_sync/full_sync.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index fadd6968..dfa357e0 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -283,6 +283,8 @@ class FullSync(common.fullsync_mixin): self.section_success = False else: queue.put(element) + except Exception: + utils.ERROR(notify=True) finally: queue.put(None) From ba4f1d15d67a82a8c681316f03b9b56ff4ecac7f Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 16:26:48 +0100 Subject: [PATCH 4/7] Increase logging --- resources/lib/library_sync/full_sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lib/library_sync/full_sync.py b/resources/lib/library_sync/full_sync.py index dfa357e0..218bf23d 100644 --- a/resources/lib/library_sync/full_sync.py +++ b/resources/lib/library_sync/full_sync.py @@ -258,6 +258,7 @@ class FullSync(common.fullsync_mixin): for section in (x for x in sections.SECTIONS if x.section_type == kind[1]): if self.isCanceled(): + LOG.debug('Need to exit now') return if not section.sync_to_kodi: LOG.info('User chose to not sync section %s', section) From d068c37c49af120101798624426e87c4bf5dcbba Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 16:53:13 +0100 Subject: [PATCH 5/7] Fix PKC synching playstate to wrong user on profile switch - BUT: Kodi profiles seem to be a mess! --- resources/lib/service_entry.py | 38 +++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/resources/lib/service_entry.py b/resources/lib/service_entry.py index 90e8616d..c17f8375 100644 --- a/resources/lib/service_entry.py +++ b/resources/lib/service_entry.py @@ -451,6 +451,9 @@ class Service(object): self.choose_plex_libraries() elif plex_command == 'RESET-PKC': utils.reset() + elif plex_command == 'EXIT-PKC': + LOG.info('Received command from another instance to quit') + app.APP.stop_pkc = True if task: backgroundthread.BGThreader.addTasksToFront([task]) continue @@ -506,26 +509,37 @@ class Service(object): library_sync.clear_window_vars() # Will block until threads have quit app.APP.stop_threads() - utils.window('plex_service_started', clear=True) - LOG.info("======== STOP %s ========", v.ADDON_NAME) def start(): # Safety net - Kody starts PKC twice upon first installation! if utils.window('plex_service_started') == 'true': - EXIT = True - else: - utils.window('plex_service_started', value='true') - EXIT = False - - # Delay option + LOG.info('Another service.py instance is already running - shutting ' + 'it down now') + # Telling the other Python instance of PKC to shut down now + i = 0 + while utils.window('plexkodiconnect.command'): + xbmc.sleep(20) + i += 1 + if i > 300: + LOG.error('Could not tell other PKC instance to shut down') + return + utils.window('plexkodiconnect.command', value='EXIT-PKC') + # Telling successful - now wait for actual shut-down + i = 0 + while utils.window('plex_service_started'): + xbmc.sleep(20) + i += 1 + if i > 300: + LOG.error('Could not shut down other PKC instance') + return + utils.window('plex_service_started', value='true') DELAY = int(utils.settings('startupDelay')) - LOG.info("Delaying Plex startup by: %s sec...", DELAY) - if EXIT: - LOG.error('PKC service.py already started - exiting this instance') - elif DELAY and xbmc.Monitor().waitForAbort(DELAY): + if DELAY and xbmc.Monitor().waitForAbort(DELAY): # Start the service LOG.info("Abort requested while waiting. PKC not started.") else: Service().ServiceEntryPoint() + utils.window('plex_service_started', clear=True) + LOG.info("======== STOP PlexKodiConnect service ========") From 9d07a58c50eae5197590233bc72177c5ebf19606 Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 17:28:25 +0100 Subject: [PATCH 6/7] Replace waitForAbort() with sleep() --- resources/lib/service_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/lib/service_entry.py b/resources/lib/service_entry.py index c17f8375..fa929595 100644 --- a/resources/lib/service_entry.py +++ b/resources/lib/service_entry.py @@ -459,7 +459,7 @@ class Service(object): continue if app.APP.suspend: - app.APP.monitor.waitForAbort(0.1) + xbmc.sleep(100) continue # Before proceeding, need to make sure: @@ -498,7 +498,7 @@ class Service(object): if utils.settings('enable_alexa') == 'true': self.alexa.start() - app.APP.monitor.waitForAbort(0.1) + xbmc.sleep(100) # EXITING PKC # Tell all threads to terminate (e.g. several lib sync threads) From 815cd20d3956bd4218feb41478e6c492e60f1ea5 Mon Sep 17 00:00:00 2001 From: croneter Date: Sun, 17 Mar 2019 17:36:56 +0100 Subject: [PATCH 7/7] Ensure Plex companion thread quits on time --- resources/lib/plexbmchelper/subscribers.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/resources/lib/plexbmchelper/subscribers.py b/resources/lib/plexbmchelper/subscribers.py index 597d8c14..afa47fe5 100644 --- a/resources/lib/plexbmchelper/subscribers.py +++ b/resources/lib/plexbmchelper/subscribers.py @@ -289,7 +289,9 @@ class SubscriptionMgr(object): # To avoid RuntimeError, don't use self.lastplayers for playerid in (0, 1, 2): self.last_params['state'] = 'stopped' - self._send_pms_notification(playerid, self.last_params) + self._send_pms_notification(playerid, + self.last_params, + timeout=0.0001) def _plex_stream_index(self, playerid, stream_type): """ @@ -399,7 +401,11 @@ class SubscriptionMgr(object): self.last_params = params return params - def _send_pms_notification(self, playerid, params): + def _send_pms_notification(self, playerid, params, timeout=None): + """ + Pass a really low timeout in seconds if shutting down Kodi and we don't + need the PMS' response + """ serv = self._server_by_host(self.server) playqueue = PQ.PLAYQUEUES[playerid] xargs = params_pms() @@ -416,7 +422,8 @@ class SubscriptionMgr(object): DU().downloadUrl(url, authenticate=False, parameters=xargs, - headerOverride=HEADERS_PMS) + headerOverride=HEADERS_PMS, + timeout=timeout) LOG.debug("Sent server notification with parameters: %s to %s", xargs, url)