linux - Python application becomes non-responsive due to subprocess -


i have written python application, using flask, serves simple website can use start playback of streaming video on raspberry pi (microcomputer). essentially, application allows use phone or tablet remote control.

i tested application on mac os, , works fine. after deploying raspberry pi (with raspbian variant of debian installed), serves website fine, , starting playback works expected. but, stopping playback fails.

relevant code hosted here: https://github.com/lcvisser/mlbviewer-remote/blob/master/remote/mlbviewer-remote.py

the subprocess started this:

cmd = 'python2.7 mlbplay.py v=%s j=%s/%s/%s i=t1' % (team, mm, dd, yy) player = subprocess.popen(cmd, shell=true, bufsize=-1, cwd=sys.argv[1]) 

this works fine.

the subprocess supposed stop after this:

player.send_signal(signal.sigint) player.communicate() 

this does work on mac os, not work on raspberry pi: application hangs until subprocess (started cmd) finished itself. seems sigint not sent or not received subprocess.

any ideas?


(i have posted question here: https://unix.stackexchange.com/questions/133946/application-becomes-non-responsive-to-requests-on-raspberry-pi don't know if os problem or if python/flask-related problem.)

update: trying use player.communicate() suggested jan vlcinsky below (and after seeing warning here) did not help.

i'm thinking using proposed solution jan vlcinsky, if flask not receive request, don't think receive issue.

update 2: yesterday night fortunate have situation in able pinpoint issue. updated question relevant code.

i feel solution of jan vlcinsky move problem different application, keep flask application responsive, let new application hang.

update 3: edited original part of question remove know not relevant.

update 4: after comments of @shavenwarthog, following information might relevant:

on mac, mlbplay.py starts this:

rmtpdump <some_options_and_url> | mplayer - 

when sending sigint mlbplay.py, terminates process group created piped command (if understood correctly).

on raspberry pi, i'm using omxplayer, avoid having change code of mlbplay.py (which not mine), made script called mplayer, following content:

#!/bin/bash  mlbtv_pipe=mlbpipe  if [ ! -p $mlbtv_pipe ]     mkfifo $mlbtv_pipe fi  cat <&0 > $mlbtv_pipe | omxplayer -o hdmi $mlbtv_pipe 

i'm guessing last line starts new process group, not terminated sigint signal , making app hang. if so, should somehow process group id of group able terminate properly. can confirm this?

update 5: omxplayer handle sigint:

https://github.com/popcornmix/omxplayer/blob/master/omxplayer.cpp#l131

update 6: turns out somehow sigint transforms sigterm somewhere along chain of commands. sigterm not handled omxplayer, appears problem why things keep hanging. solved implementing shell script manages signals , translates them proper omxplayer commands (sort-of lame version of jan suggested).

solution: problem in player.send_signal(). signal not handled along chain of commands, caused parent app hang. solution implement wrappers commands don't handle signals well.

in addition: used popen(cmd.split()) rather using shell=true. works lot better when sending signals!

the problem marked in following snippet:

@app.route('/watch/<year>/<month>/<day>/<home>/<away>/') def watch(year, month, day, home, away):     global session     global watching     global player      # select video stream     fav = config.get('favorite')     if fav:         fav = fav[0] # todo: handle multiple favorites         if fav in (home, away):             # favorite team playing             team = fav         else:             # use stream of home team             team = home     else:         # use stream of home team         team = home      # end session     session = none      # start mlbplay     mm = '%02i' % int(month)     dd = '%02i' % int(day)     yy = str(year)[-2:]     cmd = 'python2.7 mlbplay.py v=%s j=%s/%s/%s' % (team, mm, dd, yy)     # problem here ----->     player = subprocess.popen(cmd, shell=true, cwd=sys.argv[1])     # < ------problem here      # render template     game = {}     game['away_code'] = away     game['away_name'] = teamcodes[away][1]     game['home_code'] = home     game['home_name'] = teamcodes[home][1]     watching = game     return flask.render_template('watching.html', game=game) 

you starting new process executing shell command, not wait until completes. seem rely on fact, command line process single one, frontend not taking care of , can start one.

another problem be, not call player.communicate() , process block if stdout or stderr filled output.

proposed solution - split process controller web app

you trying create ui controlling player. purpose, practical splitting solution frontend , backend. backend serve player controller , offer methods

  • start
  • stop
  • nowplaying

to integrate front , backend, multiple options available, 1 of them being zerorpc shown here: https://stackoverflow.com/a/23944303/346478

advantage be, create other frontends (like command line one, remote one).


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -