From 0d52b048c0c0731caa800bea67e4ddd6f1653471 Mon Sep 17 00:00:00 2001 From: Roman Bazalevsky Date: Tue, 3 Nov 2015 19:29:07 +0300 Subject: [PATCH 1/1] =?utf8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?utf8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?utf8?q?=D0=BA=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?utf8?q?=D1=8F=20VLC.=20=D0=98=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD?= =?utf8?q?=D0=B0=20=D0=BF=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B0=20=D0=BF?= =?utf8?q?=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE?= =?utf8?q?=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F=20=D1=83=D0=B6=D0=B5?= =?utf8?q?=20=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE=20?= =?utf8?q?=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- vlcclient/vlcclient.py | 7 ++++++ vphttp.py | 55 +++++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/vlcclient/vlcclient.py b/vlcclient/vlcclient.py index 1fa5e43..f1e5733 100644 --- a/vlcclient/vlcclient.py +++ b/vlcclient/vlcclient.py @@ -186,6 +186,13 @@ class VlcClient(object): self.stopBroadcast(stream) self._resultlock.release() + def check_stream(self,stream_name): + if stream_name in self.streams: + self.streams[stream_name]=time.time() + return True + else: + return False + def pauseBroadcast(self, stream_name): return self._write(VlcMessage.request.pauseBroadcast(stream_name)) diff --git a/vphttp.py b/vphttp.py index 040e94c..33da300 100644 --- a/vphttp.py +++ b/vphttp.py @@ -234,15 +234,21 @@ class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler): # then somebody is waiting in the videodestroydelay state # Check if we are first client - if VPStuff.clientcounter.get(self.reqtype+'/'+self.path_unquoted)==1: - logger.debug("First client, should create VLC session") - shouldcreatevp = True - else: - logger.debug("Can reuse existing session") - shouldcreatevp = False self.vlcid = hashlib.md5(self.reqtype+'/'+self.path_unquoted).hexdigest() + try: + if not VPStuff.vlcclient.check_stream(self.vlcid): + logger.debug("First client, should create VLC session") + shouldcreatevp = True + else: + logger.debug("Can reuse existing session") + shouldcreatevp = False + except Exception as e: + logger.error('Plugin exception: ' + repr(e)) + logger.error(traceback.format_exc()) + self.dieWithError() + # Send fake headers if this User-Agent is in fakeheaderuas tuple if fakeua: logger.debug( @@ -329,7 +335,12 @@ class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler): # Waiting until hangDetector is joined self.hanggreenlet.join() logger.debug("Request handler finished") - + except (vlcclient.VlcException) as e: + logger.error("Exception: " + repr(e)) + VPStuff.vlcerrors = VPStuff.vlcerrors + 1 + logger.error("%s error(s) communicating VLC") + self.errorhappened = True + self.dieWithError() except (vpclient.VPException, vlcclient.VlcException, urllib2.URLError) as e: logger.error("Exception: " + repr(e)) self.errorhappened = True @@ -360,6 +371,7 @@ class VPStuff(object): Inter-class interaction class ''' vlcclient=None + vlcerrors=0 # taken from http://stackoverflow.com/questions/2699907/dropping-root-permissions-in-python def drop_privileges(uid_name, gid_name='nogroup'): @@ -442,6 +454,7 @@ DEVNULL = open(os.devnull, 'wb') def spawnVLC(cmd, delay = 0): try: VPStuff.vlc = psutil.Popen(cmd) #, stdout=DEVNULL, stderr=DEVNULL) + VPStuff.vlcerrors = 0 gevent.sleep(delay) return True except: @@ -487,7 +500,18 @@ def clean_proc(): gevent.sleep(1) if isRunning(VPStuff.vlc): # or not :) - VPStuff.vlc.kill() + VPStuff.vlc.terminate() + gevent.sleep(1) + if isRunning(VPStuff.vlc): + VPStuff.vlc.kill() + del VPStuff.vlc + +def restartVLC(cmd, delay = 0): + clean_proc() + if spawnVLC(cmd, delay): + if connectVLC(): + return True + return False # This is what we call to stop the server completely def shutdown(signum = 0, frame = 0): @@ -520,7 +544,8 @@ sched = BackgroundScheduler() sched.start() def clean_streams(): - VPStuff.vlcclient.clean_streams(VPConfig.videodestroydelay) + if VPStuff.vlcclient: + VPStuff.vlcclient.clean_streams(VPConfig.videodestroydelay) job = sched.add_job(clean_streams, 'interval', seconds=15) @@ -546,7 +571,9 @@ try: logger.info("Using VLC %s" % VPStuff.vlcclient._vlcver) logger.info("Server started.") while True: + if not isRunning(VPStuff.vlc): + del VPStuff.vlc if spawnVLC(VPStuff.vlcProc, VPConfig.vlcspawntimeout) and connectVLC(): logger.info("VLC died, respawned it with pid " + str(VPStuff.vlc.pid)) @@ -554,8 +581,18 @@ try: logger.error("Cannot spawn VLC!") clean_proc() sys.exit(1) + # Return to our server tasks server.handle_request() + + if VPStuff.vlcerrors>5: + if restartVLC(VPStuff.vlcProc, VPConfig.vlcspawntimeout): + logger.info("VLC hung, respawned it with pid " + str(VPStuff.vlc.pid)) + else: + logger.error("Cannot spawn VLC!") + clean_proc() + sys.exit(1) + except (KeyboardInterrupt, SystemExit): sched.shutdown() shutdown() -- 2.34.1