flask in werkzeug Local, LocalStack and LocalProxy technology

What is Local

  1. wsgi each request, the process proceeds detached stateless will then process the data stored in the global variable in this request, used to Local. Local as a global command space for each request, each request is privately owned
  2. Local LocalStack and similar, used to operate in the stack mode Local basis, management
  3. LocalProxy proxy class, or Local Agent Examples LocalStack

Why Local

  Why Custom Local, rather than threading.local. This is determined by the kernel

    1. web after starting the application, is a single line + HS, then start the process, contaminate the global variables can not be distinguished,

    2. HS + multithreading can not be guaranteed, the request distribution coroutine work, while the work can not be guaranteed and are respectively located in a plurality of threads, independent from other

So: werkzeug gives his own solution: Local and LocalStack

Why LocalProxy

  So the question is: context of private variables to store the requested Local and LocalStack in that when multi-tasking, each call from flask import request, g, session, how to ensure get the correct context, and not chaos?

In  flask.globals.py  in

def _lookup_req_object(name):  
    top = _request_ctx_stack.top  
    if top is None:  
        raise RuntimeError('working outside of request context')  
    return getattr(top, name)  

_request_ctx_stack = LocalStack()  
request = LocalProxy(partial(_lookup_req_object, 'request'))  
session = LocalProxy(partial(_lookup_req_object, 'session'))

 

In  werkzeug.local.py  in, LocalProxy is an agent of a Local or LocalStack

@implements_bool
class LocalProxy(object):
 """"""
  __slots__ = ("__local", "__dict__", "__name__", "__wrapped__")

  def __init__(self, local, name=None):
     object.__setattr__(self, "_LocalProxy__local", local)
      object.__setattr__(self, "__name__", name)
      if callable(local) and not hasattr(local, "__release_local__"):
        # "local" is a callable that is not an instance of Local or
         # LocalManager: mark it as a wrapped function.
         object.__setattr__(self, "__wrapped__", local)

   def _get_current_object(self):
      """Return the current object.  This is useful if you want the real
      object behind the proxy at a time for performance reasons or because
      you want to pass the object into a different context.
      """
      if not hasattr(self.__local, "__release_local__"):
          return self.__local()
      try:
          return getattr(self.__local, self.__name__)
      except AttributeError:
          raise RuntimeError("no object bound to %s" % self.__name__)

  def __getattr__(self, name):
      if name == "__members__":
          return dir(self._get_current_object())
      return getattr(self._get_current_object(), name)

Call reqeust: Dynamic request <= dynamic _request_ctx_stack.top <= LocalStack () each time a new call instance be produced using methods and binding (request) <= LoaclStack.call?

Yes, each call request, it will generate a new proxy instance, every pop, push, top are for Local operation, and Local property assignment and acquisition are acquired for get_ident!

Such as: werkzeug.local.Local.py

class Local(object):
    __slots__ = ("__storage__", "__ident_func__")

    def __init__(self):
        object.__setattr__(self, "__storage__", {})
        object.__setattr__(self, "__ident_func__", get_ident)
    """"""
    def __getattr__(self, name):
        try:
            return self.__storage__[self.__ident_func__()][name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        ident = self.__ident_func__()
        storage = self.__storage__
        try:
            storage[ident][name] = value
        except KeyError:
            storage[ident] = {name: value}

perfect! Every time a new request comes, will Flask werkzeug Local context stored in the thread obtained according to the use or id coroutine

What are the benefits of such use

  1. Supported by the underlying operating coroutine, improve the efficiency of concurrent expansion
  2. Management and avoid the application of the entire transfer request context
  3. Extended Compatibility perfect, to achieve a plug-in expansion of third-party applications
  4. Readability strong, simple operation, approachable

Guess you like

Origin www.cnblogs.com/spaceapp/p/12157940.html