Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1896] fix play daemon stacktrace on [re]start-stop #1158

Merged
merged 1 commit into from
Jul 11, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 48 additions & 32 deletions framework/pym/play/commands/daemon.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import os, os.path
import os
import os.path
import subprocess
from play.utils import *
import time

from play.utils import *

if os.name == 'nt':
import win32pdh, string, win32api
import win32pdh, win32pdhutil

COMMANDS = ['start', 'stop', 'restart', 'pid', 'out']

Expand All @@ -15,6 +18,7 @@
'out': 'Follow logs/system.out file'
}


def execute(**kargs):
command = kargs.get("command")
app = kargs.get("app")
Expand All @@ -32,20 +36,22 @@ def execute(**kargs):
if command == 'out':
out(app)


def start(app, args):
app.check()
if os.path.exists(app.pid_path()):
pid = open(app.pid_path()).readline().strip()
if process_running(pid):
print "~ Oops. %s is already started (pid:%s)! (or delete %s)" % (os.path.normpath(app.path), pid, os.path.normpath(app.pid_path()))
print "~ Oops. %s is already started (pid:%s)! (or delete %s)" % (
os.path.normpath(app.path), pid, os.path.normpath(app.pid_path()))
print "~"
sys.exit(1)
else:
print "~ removing pid file %s for not running pid %s" % (os.path.normpath(app.pid_path()), pid)
os.remove(app.pid_path())

sysout = app.readConf('application.log.system.out')
sysout = sysout!='false' and sysout!='off'
sysout = sysout != 'false' and sysout != 'off'
if not sysout:
sout = None
else:
Expand All @@ -57,12 +63,13 @@ def start(app, args):
sys.exit(-1)
print "~ OK, %s is started" % os.path.normpath(app.path)
if sysout:
print "~ output is redirected to %s" % os.path.normpath(os.path.join(app.log_path(), 'system.out'))
print "~ output is redirected to %s" % os.path.normpath(os.path.join(app.log_path(), 'system.out'))
pid_file = open(app.pid_path(), 'w')
pid_file.write(str(pid))
print "~ pid is %s" % pid
print "~"


def stop(app):
app.check()
if not os.path.exists(app.pid_path()):
Expand All @@ -87,20 +94,20 @@ def restart(app, args):
kill(pid)

sysout = app.readConf('application.log.system.out')
sysout = sysout!='false' and sysout!='off'
sysout = sysout != 'false' and sysout != 'off'
java_cmd = app.java_cmd(args)
if not sysout:
sout = None
sout = None
else:
sout = open(os.path.join(app.log_path(), 'system.out'), 'w')
sout = open(os.path.join(app.log_path(), 'system.out'), 'w')
try:
pid = subprocess.Popen(java_cmd, stdout=sout, env=os.environ).pid
except OSError:
print "Could not execute the java executable, please make sure the JAVA_HOME environment variable is set properly (the java executable should reside at JAVA_HOME/bin/java). "
sys.exit(-1)
print "~ OK, %s is restarted" % os.path.normpath(app.path)
if sysout:
print "~ output is redirected to %s" % os.path.normpath(os.path.join(app.log_path(), 'system.out'))
print "~ output is redirected to %s" % os.path.normpath(os.path.join(app.log_path(), 'system.out'))
pid_file = open(app.pid_path(), 'w')
pid_file.write(str(pid))
print "~ New pid is %s" % pid
Expand All @@ -118,6 +125,7 @@ def pid(app):
print "~ PID of the running applications is %s" % pid
print "~ "


def out(app):
app.check()
if not os.path.exists(os.path.join(app.log_path(), 'system.out')):
Expand All @@ -138,14 +146,18 @@ def out(app):
else:
print line


def kill(pid):
if os.name == 'nt':
import ctypes
handle = ctypes.windll.kernel32.OpenProcess(1, False, int(pid))
if not ctypes.windll.kernel32.TerminateProcess(handle, 0):
process = ctypes.windll.kernel32.TerminateProcess(handle, 0)
ctypes.windll.kernel32.CloseHandle(handle)
if not process:
print "~ Cannot kill the process with pid %s (ERROR %s)" % (pid, ctypes.windll.kernel32.GetLastError())
print "~ "
sys.exit(-1)
print "~ Process with PID %s terminated" % pid
else:
try:
os.kill(int(pid), 15)
Expand All @@ -154,42 +166,46 @@ def kill(pid):
print "~"
sys.exit(-1)


def process_running(pid):
if os.name == 'nt':
return process_running_nt(pid)
else:
try:
os.kill(int(pid), 0)
return True
except OSError:
return False
if os.name == 'nt':
return process_running_nt(pid)
else:
try:
os.kill(int(pid), 0)
return True
except OSError:
return False


# loosely based on http://code.activestate.com/recipes/303339/
def process_list_nt():
#each instance is a process, you can have multiple processes w/same name
junk, instances = win32pdh.EnumObjectItems(None,None,'process', win32pdh.PERF_DETAIL_WIZARD)
proc_ids={}
proc_dict={}
# each instance is a process, you can have multiple processes w/same name
processLocalizedName = win32pdhutil.find_pdh_counter_localized_name("Process")
junk, instances = win32pdh.EnumObjectItems(None, None, processLocalizedName, win32pdh.PERF_DETAIL_WIZARD)
proc_ids = {}
proc_dict = {}
for instance in instances:
if instance in proc_dict:
proc_dict[instance] = proc_dict[instance] + 1
else:
proc_dict[instance]=0
proc_dict[instance] = 0
idProcessLocalizedName = win32pdhutil.find_pdh_counter_localized_name("ID Process")
for instance, max_instances in proc_dict.items():
for inum in xrange(max_instances+1):
hq = win32pdh.OpenQuery() # initializes the query handle
path = win32pdh.MakeCounterPath( (None,'process',instance, None, inum,'ID Process') )
counter_handle=win32pdh.AddCounter(hq, path)
win32pdh.CollectQueryData(hq) #collects data for the counter
for inum in xrange(max_instances + 1):
hq = win32pdh.OpenQuery() # initializes the query handle
path = win32pdh.MakeCounterPath((None, processLocalizedName, instance, None, inum, idProcessLocalizedName))
counter_handle = win32pdh.AddCounter(hq, path)
win32pdh.CollectQueryData(hq) # collects data for the counter
type, val = win32pdh.GetFormattedCounterValue(counter_handle, win32pdh.PDH_FMT_LONG)
proc_ids[str(val)]=instance;
win32pdh.CloseQuery(hq)
proc_ids[str(val)] = instance;
win32pdh.CloseQuery(hq)

return proc_ids


def process_running_nt(pid):
if process_list_nt().get(pid,"") != "":
if process_list_nt().get(pid, "") != "":
return True
else:
return False