PYTHON-525 Try to halt monitors before exiting.
This commit is contained in:
parent
cfcc601922
commit
fea501f314
@ -67,6 +67,7 @@ class Monitor(object):
|
||||
thread = threading.Thread(target=self.run)
|
||||
thread.daemon = True
|
||||
self._thread = weakref.proxy(thread)
|
||||
register_monitor(self)
|
||||
thread.start()
|
||||
|
||||
def close(self):
|
||||
@ -171,6 +172,11 @@ class Monitor(object):
|
||||
return IsMaster(result['data'][0]), time.time() - start
|
||||
|
||||
|
||||
# MONITORS has a weakref to each running Monitor. A Monitor is kept alive by
|
||||
# a strong reference from its Server and its Thread. Once both are destroyed
|
||||
# the Monitor is garbage-collected and removed from MONITORS. If, however,
|
||||
# any threads are still running when the interpreter begins to shut down,
|
||||
# we attempt to halt and join them to avoid spurious errors.
|
||||
MONITORS = set()
|
||||
|
||||
|
||||
@ -192,6 +198,6 @@ def shutdown_monitors():
|
||||
monitor = ref()
|
||||
if monitor:
|
||||
monitor.close()
|
||||
monitor.join()
|
||||
monitor.join(10)
|
||||
|
||||
atexit.register(shutdown_monitors)
|
||||
|
||||
42
test/test_monitor.py
Normal file
42
test/test_monitor.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright 2014 MongoDB, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Test the monitor module."""
|
||||
|
||||
import gc
|
||||
import sys
|
||||
|
||||
sys.path[0:0] = [""]
|
||||
|
||||
from pymongo.monitor import MONITORS
|
||||
from test import unittest, port, host, IntegrationTest
|
||||
from test.utils import get_client, wait_until
|
||||
|
||||
|
||||
class TestMonitor(IntegrationTest):
|
||||
def test_atexit_hook(self):
|
||||
n_monitors = len(MONITORS)
|
||||
client = get_client(host, port)
|
||||
wait_until(lambda: len(MONITORS) == n_monitors + 1,
|
||||
'register new monitor')
|
||||
|
||||
del client
|
||||
gc.collect()
|
||||
|
||||
wait_until(lambda: len(MONITORS) == n_monitors,
|
||||
'unregister monitor')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Reference in New Issue
Block a user