dde2cbafd3
This is a sync of processutils and lockutils from oslo-incubator along with their dependencies. The main target for the sync is to pick up the get_worker_count() method in commit 85f178489a128a04a7ee3ed44018403caa109ef0 so that we can set glance-api workers equal to the number of CPUs on the host. lockutils is also copied over due to the nature running multiple workers and how the glance functional tests are setup, it'd be prudent to have the latest lockutils code since it hasn't been updated in over six months. The change to require posix_ipc is due to commit edce46cf5efd6d738d379205f9bf526a498845e3 in lockutils. Changes: processutils ------------ 85f1784 Move nova.utils.cpu_count() to processutils module cdcc19c Mask passwords that are included in commands 8a0f567 Remove str() from LOG.* and exceptions 51778f9 Allow passing environment variables to execute() fcf517d Update oslo log messages with translation domains af41592 Catch OSError in processutils f773ea2 Fix i18n problem in processutils module 8b2b0b7 Use hacking import_exceptions for gettextutils._ 3b71f46 Fixed misspellings of common words 12bcdb7 Remove vim header a4dab73 Correct execute() to check 0 in check_exit_code d6a963e Fix processutils.execute errors on windows aa5b658 Allow passing a logging level to processutils.execute 1a2df89 Enable H302 hacking check 7119e29 Enable hacking H404 test. 2f01388 Use Python 3.x compatible except construct lockutils --------- de4adbc pep8: fixed multiple violations 9e88af1 fixed typos found by RETF rules fe3389e Improve help strings f3f14c9 Fixed several typos 0f495ee Emit a log statement when releasing internal lock f0dd798 Remove rendundant parentheses of cfg help strings 006d9a2 Allow external locks to work with threads 9b73c19 Re-enable file-based locking behavior edce46c Use Posix IPC in lockutils ac84a40 Update log translation domains fcf517d Update oslo log messages with translation domains 37a1de8 Move the released file lock to the successful path b0d0c33 Add remove external lock files API in lockutils 4f6190a Use threading.ThreadError instead of reraising IOError 195f0b1 Have the interprocess lock follow lock conventions 15cca4b lockutils: move directory creation in lock class 81fe39e lockutils: remove lock_path parameter 14d3669 lockutils: expand add_prefix dc06d55 lockutils: do not grab the lock in creators a0948cb lockutils: remove local usage df8e051 lockutils: split code handling internal/external lock log --- 109e325 Use oslo.messaging to publish log errors de4adbc pep8: fixed multiple violations eac71f5 Fix common.log.ContextFormatter for Python 3 d78b633 Fixes a simple spelling mistake 621d831 always log a traceback in the sys.excepthook 90ae24b Remove redundant default=None for config options af36c2a Fix logging setup for Python 3.4 cdcc19c Mask passwords that are included in commands excutils -------- 33a2cee save_and_reraise_exception: make logging respect the reraise parameter fcf517d Update oslo log messages with translation domains fileutils --------- 9c88dc3 file_open: fixed docstring to refer to open() instead of file() 6c7407b fileutils: port to Python 3 fcf517d Update oslo log messages with translation domains Partial-Bug: #1333325 Change-Id: I6c9d8961af2bd3bbe4d149f21cd6d4fad676ba14
114 lines
4.2 KiB
Python
114 lines
4.2 KiB
Python
# Copyright 2011 OpenStack Foundation.
|
|
# Copyright 2012, Red Hat, 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.
|
|
|
|
"""
|
|
Exception related utilities.
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
import time
|
|
import traceback
|
|
|
|
import six
|
|
|
|
from glance.openstack.common.gettextutils import _LE
|
|
|
|
|
|
class save_and_reraise_exception(object):
|
|
"""Save current exception, run some code and then re-raise.
|
|
|
|
In some cases the exception context can be cleared, resulting in None
|
|
being attempted to be re-raised after an exception handler is run. This
|
|
can happen when eventlet switches greenthreads or when running an
|
|
exception handler, code raises and catches an exception. In both
|
|
cases the exception context will be cleared.
|
|
|
|
To work around this, we save the exception state, run handler code, and
|
|
then re-raise the original exception. If another exception occurs, the
|
|
saved exception is logged and the new exception is re-raised.
|
|
|
|
In some cases the caller may not want to re-raise the exception, and
|
|
for those circumstances this context provides a reraise flag that
|
|
can be used to suppress the exception. For example::
|
|
|
|
except Exception:
|
|
with save_and_reraise_exception() as ctxt:
|
|
decide_if_need_reraise()
|
|
if not should_be_reraised:
|
|
ctxt.reraise = False
|
|
|
|
If another exception occurs and reraise flag is False,
|
|
the saved exception will not be logged.
|
|
|
|
If the caller wants to raise new exception during exception handling
|
|
he/she sets reraise to False initially with an ability to set it back to
|
|
True if needed::
|
|
|
|
except Exception:
|
|
with save_and_reraise_exception(reraise=False) as ctxt:
|
|
[if statements to determine whether to raise a new exception]
|
|
# Not raising a new exception, so reraise
|
|
ctxt.reraise = True
|
|
"""
|
|
def __init__(self, reraise=True):
|
|
self.reraise = reraise
|
|
|
|
def __enter__(self):
|
|
self.type_, self.value, self.tb, = sys.exc_info()
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
if exc_type is not None:
|
|
if self.reraise:
|
|
logging.error(_LE('Original exception being dropped: %s'),
|
|
traceback.format_exception(self.type_,
|
|
self.value,
|
|
self.tb))
|
|
return False
|
|
if self.reraise:
|
|
six.reraise(self.type_, self.value, self.tb)
|
|
|
|
|
|
def forever_retry_uncaught_exceptions(infunc):
|
|
def inner_func(*args, **kwargs):
|
|
last_log_time = 0
|
|
last_exc_message = None
|
|
exc_count = 0
|
|
while True:
|
|
try:
|
|
return infunc(*args, **kwargs)
|
|
except Exception as exc:
|
|
this_exc_message = six.u(str(exc))
|
|
if this_exc_message == last_exc_message:
|
|
exc_count += 1
|
|
else:
|
|
exc_count = 1
|
|
# Do not log any more frequently than once a minute unless
|
|
# the exception message changes
|
|
cur_time = int(time.time())
|
|
if (cur_time - last_log_time > 60 or
|
|
this_exc_message != last_exc_message):
|
|
logging.exception(
|
|
_LE('Unexpected exception occurred %d time(s)... '
|
|
'retrying.') % exc_count)
|
|
last_log_time = cur_time
|
|
last_exc_message = this_exc_message
|
|
exc_count = 0
|
|
# This should be a very rare event. In case it isn't, do
|
|
# a sleep.
|
|
time.sleep(1)
|
|
return inner_func
|