X-Git-Url: https://code.grnet.gr/git/pithos/blobdiff_plain/7efc9f8670f263196536ed6be5db2caa12bb36f1..d63a5938a02b34db073b2bfeb1e1fd18c5464b02:/snf-pithos-app/pithos/api/util.py diff --git a/snf-pithos-app/pithos/api/util.py b/snf-pithos-app/pithos/api/util.py index 0055d9a..710ee30 100644 --- a/snf-pithos-app/pithos/api/util.py +++ b/snf-pithos-app/pithos/api/util.py @@ -56,12 +56,12 @@ from pithos.api.faults import (Fault, NotModified, BadRequest, Unauthorized, For RangeNotSatisfiable, InternalServerError, NotImplemented) from pithos.api.short_url import encode_url from pithos.api.settings import (BACKEND_DB_MODULE, BACKEND_DB_CONNECTION, - BACKEND_BLOCK_MODULE, BACKEND_BLOCK_PATH, - BACKEND_BLOCK_UMASK, - BACKEND_QUEUE_MODULE, BACKEND_QUEUE_CONNECTION, - BACKEND_QUOTA, BACKEND_VERSIONING, - AUTHENTICATION_URL, AUTHENTICATION_USERS, - SERVICE_TOKEN, COOKIE_NAME) + BACKEND_BLOCK_MODULE, BACKEND_BLOCK_PATH, + BACKEND_BLOCK_UMASK, + BACKEND_QUEUE_MODULE, BACKEND_QUEUE_CONNECTION, + BACKEND_QUOTA, BACKEND_VERSIONING, + AUTHENTICATION_URL, AUTHENTICATION_USERS, + SERVICE_TOKEN, COOKIE_NAME) from pithos.backends import connect_backend from pithos.backends.base import NotAllowedError, QuotaError, ItemNotExists, VersionNotExists @@ -326,8 +326,6 @@ def copy_or_move_object(request, src_account, src_container, src_name, dest_acco if 'ignore_content_type' in request.GET and 'CONTENT_TYPE' in request.META: del(request.META['CONTENT_TYPE']) content_type, meta, permissions, public = get_object_headers(request) - if delimiter: - public = False # ignore public in that case src_version = request.META.get('HTTP_X_SOURCE_VERSION') try: if move: @@ -790,7 +788,8 @@ def simple_list_response(request, l): if request.serialization == 'json': return json.dumps(l) -def get_backend(): + +def _get_backend(): backend = connect_backend(db_module=BACKEND_DB_MODULE, db_connection=BACKEND_DB_CONNECTION, block_module=BACKEND_BLOCK_MODULE, @@ -802,6 +801,76 @@ def get_backend(): backend.default_policy['versioning'] = BACKEND_VERSIONING return backend + +def _pooled_backend_close(backend): + backend._pool.pool_put(backend) + + +from synnefo.lib.pool import ObjectPool +from new import instancemethod +from select import select +from traceback import print_exc + +USAGE_LIMIT = 500 +POOL_SIZE = 5 + +class PithosBackendPool(ObjectPool): + def _pool_create(self): + backend = _get_backend() + backend._real_close = backend.close + backend.close = instancemethod(_pooled_backend_close, backend, + type(backend)) + backend._pool = self + backend._use_count = USAGE_LIMIT + return backend + + def _pool_verify(self, backend): + wrapper = backend.wrapper + conn = wrapper.conn + if conn.closed: + return False + + if conn.in_transaction(): + conn.close() + return False + + try: + fd = conn.connection.connection.fileno() + r, w, x = select([fd], (), (), 0) + if r: + conn.close() + return False + except: + print_exc() + return False + + return True + + def _pool_cleanup(self, backend): + c = backend._use_count - 1 + if c < 0: + backend._real_close() + return True + + backend._use_count = c + wrapper = backend.wrapper + if wrapper.trans is not None: + conn = wrapper.conn + if conn.closed: + wrapper.trans = None + else: + wrapper.rollback() + if backend.messages: + backend.messages = [] + return False + +_pithos_backend_pool = PithosBackendPool(size=POOL_SIZE) + + +def get_backend(): + return _pithos_backend_pool.pool_get() + + def update_request_headers(request): # Handle URL-encoded keys and values. meta = dict([(k, v) for k, v in request.META.iteritems() if k.startswith('HTTP_')]) @@ -872,6 +941,7 @@ def request_serialization(request, format_allowed=False): return 'text' + def api_method(http_method=None, format_allowed=False, user_required=True): """Decorator function for views that implement an API method."""