On Tue, Jan 24, 2012 at 12:06 AM, Roberto De Ioris <[email protected]> wrote:
>> On Mon, Jan 23, 2012 at 3:09 AM, Roberto De Ioris <[email protected]>
>> wrote:
>>
>> when stepping the code, Py_IsInitialized() does return true, but deep
>> within python routines threadstate_getframe receives (and tries to
>> dereference) a null pointer.
>>
>> it's like python is using threads anyway? once i comment out the check
>> for `uwsgi.has_threads` in `uwsgi_python_atexit`, and thus
>> unconditionally call `PyGILState_Ensure()`, everything works fine, but
>> i don't know enough to understand why completely.
>
> This is pretty strange, it looks like the python interactive shell
> (--pyshell) is not fully releasing python, but freeing resources in some
> way.
> Maybe it would be easier to remove "atexit" handler if the worker has been
> hijacked.

i think this is by design.  SIGINT does not cause interpreter
shutdown, but rather a KeyboardInterrupt (when interactive at least),
followed by a new prompt, eg:

# python
Python 3.2.2 (default, Nov 21 2011, 16:50:59)
[GCC 4.6.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>>
KeyboardInterrupt
>>> sys
<module 'sys' (built-in)>
>>>

... the "interactive session" is not destroyed, else calling `sys`
would raise NameError.

rather than skip the exit hooks (per your message, which does work as
intended), why not just remove uWSGI signal handlers altogether?  or
at least for --pyshell children?  this would allow the python
interpreter to do it's own thing, and only exit on EOF like a normal
interactive session.  IMO, the stack should only be killed if the
*master* receives a SIGINT.

however, on EOF with `--master`, uWSGI respawns the dead child in a
similar fashion as a KeyboardInterrupt (SIGINT), but without
`--master` it of course just dies on either event ... this poses a
problem because as-is, if the signal handler is removed completely as
i suggested, there would be no [clean] way to terminate uWSGI from the
same shell it was started -- you'd have to manually send a SIGINT to
the master process from another shell.

possible solution:  --pyshell and possibly similar children are
"oneshot" only, ie. they only get one life ... after that they revert
to normal workers.  this would let you spawn uWSGI with --pyshell, do
something useful, and leave.  it would also prevent this from
occurring:

# ./uwsgi --master --pyshell -s@null <<<''
*** Starting uWSGI 1.1-dev-1862 (64bit) on [Tue Jan 24 20:28:50 2012] ***
[...]
*** Operational MODE: single process ***
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 5486)
spawned uWSGI worker 1 (pid: 5487, cores: 1)
>>> >>>
DAMN ! worker 1 (pid: 5487) died :( trying respawn ...
Respawned uWSGI worker 1 (new pid: 5488)
>>>
DAMN ! worker 1 (pid: 5488) died :( trying respawn ...
Respawned uWSGI worker 1 (new pid: 5489)
>>>
DAMN [... repeat forever ...]

... which loops forever until killed.  if --pyshell was "oneshot", you
could pipe an initialization script into uWSGI, execute it, let the
hijacked worker die, then respawn as a regular worker ... this might
be useful for other scenarios too.

so ... removing uWSGI handlers and only giving the hijacked worker one
life == no unbound looping, a neat way to pipe commands into uWSGI,
and clean shutdown in all cases i can think of.

thoughts?

-- 

C Anthony
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi

Reply via email to