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
--master, atexit, and threads #1609
Comments
Hi, this is the expected behaviour with threads + fork (and it is one of the main reasons why golang does not support it ;) Basically the thread is spawned in the master, but the wait happens in the worker for a thread that is not 'runnable'. --lazy-apps should fix your problem. If you need copy on write, spawn the thread in a post_fork hook |
It does, thanks for the super quick answer! I wish I hadn’t spent so much time on the SSCE. 🙈 |
I feel like I need to add for posterity, that for the atexits actually to run on SIGTERM & SIGINT, you need to set (master FIFO is not a good option in containers) |
Um so I have another question: Why on earth would uWSGI behave differently when I kill it with Ctrl-C and when I kill it with
Ctrl-C:
How does it even know that the signal is coming from my keyboard? And then if I run it with
Could you shed some light here what is going on? Is it even possible to run WSGI application with a side-car thread? |
Can you try on a Linux system ? I know it may look foolish but it is not the first time signals + pthreads result in weird behaviours on osx :( |
In the mean time i can confirm that pthread cancelation does not work as expected on OSX. So you should add the option --no-threads-wait if you plan to spawn multiple threads on darwin. Basically with this option the worker is killed without waiting for threads cooperation. |
OK Linux time! It’s an Ubuntu Trusty VM running in VMWare.
|
Does using --no-threads-wait improves the situation ? (both in Linux and OSX) |
macOS$ uwsgi --master --http-socket=127.0.0.1:8000 --module "mywsgi:make_app()" \
--lazy-apps --hook-master-start "unix_signal:2 gracefully_kill_them_all" \
--threads 2 --no-threads-wait
*** Starting uWSGI 2.0.15 (64bit) on [Tue Aug 15 08:05:20 2017] ***
compiled with version: 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42) on 21 July 2017 12:40:07
os: Darwin-16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64
nodename: alpha.local
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 8
current working directory: /Users/hynek/Projects/ssce
detected binary path: /Users/hynek/.virtualenvs/ssce/bin/uwsgi
your processes number limit is 709
your memory page size is 4096 bytes
detected max file descriptor number: 7168
lock engine: OSX spinlocks
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:8000 fd 3
Python version: 3.6.1 (default, May 4 2017, 15:25:00) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)]
Python main interpreter initialized at 0x7f80ee017600
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 166080 bytes (162 KB) for 2 cores
*** Operational MODE: threaded ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 31512)
spawned uWSGI worker 1 (pid: 31513, cores: 2)
running "unix_signal:2 gracefully_kill_them_all" (master-start)...
[<_MainThread(b'uWSGIWorker1Core0', started 140736085013440)>]
thread started
[<_MainThread(b'uWSGIWorker1Core0', started 140736085013440)>, <Thread(bg-thread, started daemon 123145463066624)>]
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x7f80ee017600 pid: 31513 (default app)
^CTue Aug 15 08:05:21 2017 - graceful shutdown triggered...
Gracefully killing worker 1 (pid: 31513)...
worker 1 buried after 1 seconds
goodbye to uWSGI. Shutdown works but Linuxuwsgi --master --http-socket=127.0.0.1:8000 --module "mywsgi:make_app()" \
--lazy-apps --hook-master-start "unix_signal:2 gracefully_kill_them_all" \
--threads 2 --no-threads-wait
*** Starting uWSGI 2.0.15 (64bit) on [Tue Aug 15 08:07:07 2017] ***
compiled with version: 4.8.4 on 15 August 2017 07:11:01
os: Linux-3.13.0-110-generic #157-Ubuntu SMP Mon Feb 20 11:54:05 UTC 2017
nodename: trusty64
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /home/vagrant/Projects/ssce
detected binary path: /home/vagrant/.virtualenvs/ssce/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
your processes number limit is 15832
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:8000 fd 3
Python version: 3.6.2 (default, Jul 29 2017, 00:00:00) [GCC 4.8.4]
Python main interpreter initialized at 0x1493890
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 166144 bytes (162 KB) for 2 cores
*** Operational MODE: threaded ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 13787)
spawned uWSGI worker 1 (pid: 13788, cores: 2)
running "unix_signal:2 gracefully_kill_them_all" (master-start)...
[<_MainThread(b'uWSGIWorker1Core0', started 140100408424256)>]
thread started
[<_MainThread(b'uWSGIWorker1Core0', started 140100408424256)>, <Thread(bg-thread, started daemon 140100356142848)>]
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x1493890 pid: 13788 (default app)
^CTue Aug 15 08:07:10 2017 - graceful shutdown triggered...
start clean up
[<_MainThread(b'uWSGIWorker1Core0', stopped 140100408424256)>, <_DummyThread(b'uWSGIWorker1Core1', started daemon 140100347750144)>]
msg sent
[<_MainThread(b'uWSGIWorker1Core0', stopped 140100408424256)>, <_DummyThread(b'uWSGIWorker1Core1', started daemon 140100347750144)>]
Tue Aug 15 08:08:11 2017 - worker 1 (pid: 13788) is taking too much time to die...NO MERCY !!!
worker 1 buried after 1 seconds
goodbye to uWSGI. Shutdown starts ( |
Oh, this is interesting, so on the mac ctrl-c has some magic behaviour that needs to be tackled :) but on Linux there is something more strange happening as it looks like the worker is blocked in the t.join() part. Does it happen when hitting ctrl-c, when sending -2 to the master or in both cases ? |
So all Linux now: Ctrl-C$ uwsgi --master --http-socket=127.0.0.1:8000 --module "mywsgi:make_app()" \
--lazy-apps --hook-master-start "unix_signal:2 gracefully_kill_them_all" \
--threads 2 --no-threads-wait
*** Starting uWSGI 2.0.15 (64bit) on [Tue Aug 15 08:25:33 2017] ***
compiled with version: 4.8.4 on 15 August 2017 07:11:01
os: Linux-3.13.0-110-generic #157-Ubuntu SMP Mon Feb 20 11:54:05 UTC 2017
nodename: trusty64
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /home/vagrant/Projects/ssce
detected binary path: /home/vagrant/.virtualenvs/ssce/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
your processes number limit is 15832
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address 127.0.0.1:8000 fd 3
Python version: 3.6.2 (default, Jul 29 2017, 00:00:00) [GCC 4.8.4]
Python main interpreter initialized at 0x2100890
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 166144 bytes (162 KB) for 2 cores
*** Operational MODE: threaded ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 13863)
spawned uWSGI worker 1 (pid: 13864, cores: 2)
running "unix_signal:2 gracefully_kill_them_all" (master-start)...
[<_MainThread(b'uWSGIWorker1Core0', started 140571148867392)>]
thread started
[<_MainThread(b'uWSGIWorker1Core0', started 140571148867392)>, <Thread(bg-thread, started daemon 140571096585984)>]
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x2100890 pid: 13864 (default app)
^CTue Aug 15 08:25:34 2017 - graceful shutdown triggered...
start clean up
[<_MainThread(b'uWSGIWorker1Core0', stopped 140571148867392)>, <_DummyThread(b'uWSGIWorker1Core1', started daemon 140571088193280)>]
msg sent
[<_MainThread(b'uWSGIWorker1Core0', stopped 140571148867392)>, <_DummyThread(b'uWSGIWorker1Core1', started daemon 140571088193280)>]
^C
worker 1 buried after 4 seconds
goodbye to uWSGI. → the thread isn’t there and it hangs
|
JFTR, I remembered why Ctrl-C and kill -2 work differently: doing a Ctrl-C fires a SIGINT to all foreground processes. That seems to confuse things. |
I recently working on a nginx+uwsgi+flask+golang web service. Before i add some golang shared library for python ,it all work fine.But if i call golang shared library in my python script,it stuck without any error, just no response from golang.(it works fine if i call golang shared library with python interpreter) |
Something odd happens if you try to join a thread in an atexit handler.
Consider the following code:
All it does is starting a thread in the background that waits for an event to be set.
If you run it with
uwsgi --enable-threads --http-socket=127.0.0.1:8000 --module "mywsgi:make_app()"
everything works as espected:However if you run it with a master process, it hangs while waiting for the thread which never does receive it:
I guess threading is disabled too soon or something? This is relevant to me because I need to clean up my background thread in prometheus_async.
The text was updated successfully, but these errors were encountered: