2011-09-20 12 views
8

Después de leer acerca de la seguridad this document hilo, me dio la sensación de que hay algo que falta en la documentación, o la lectura de la misma, o de mi razonamiento.hilo de seguridad con plantilla Etiquetas

Vamos a dar un ejemplo sencillo:

class HelloWorldNode(template.Node): 
    def render(self, context): 
     return "O HAI LOL" 

@register.tag(name="hello_world") 
def hello_world(parser, tokens): 
    """ 
    Greets the world with wide-eyed awe. 
    """ 
    return HelloWorldNode() 

entendí este código para construir una nueva instancia de la clase HelloWorldNode cada vez que se utiliza la etiqueta de hello_world. Otros ejemplos implican el paso de argumentos al constructor, así:

class HelloWorldNode(template.Node): 
    def __init__(self, message): 
     self.message = message 

    def render(self, context): 
     return "O HAI LOL " + message 

@register.tag(name="hello_world") 
def hello_world(parser, tokens): 
    """ 
    Greets the world with wide-eyed awe. 
    """ 

    message = tokens.split_contents()[1] 

    return HelloWorldNode(message) 

Por lo tanto, cuando se ejecuta hello_world, se crea una nueva instancia de HelloWorldNode, y el diccionario ejemplo, tiene un atributo message. Esta instancia seguramente se debe usar solo para la representación de solo la instancia dada de la etiqueta, ya que usarla para otras representaciones significaría que los datos vinculados a ella serían incorrectos. Si este no fuera el caso, los argumentos se mezclarían entre los diferentes usos de la etiqueta.

En cuanto a otros ejemplos de la documentación, aquí hay un ejemplo simplificado de here:

def do_current_time(parser, token): 
    tag_name, format_string = token.split_contents() 
    return CurrentTimeNode(format_string[1:-1]) 

Como esta toma los datos de las fichas pasan a la función, la única manera de que CurrentTimeNode puede funcionar es que uno nuevo se crea una instancia cada vez que se invoca do_current_time.

Volver a la página de documentación, donde la disonancia fija. Esto es 'malo'.

class CycleNode(Node): 
    def __init__(self, cyclevars): 
     self.cycle_iter = itertools.cycle(cyclevars) 
    def render(self, context): 
     return self.cycle_iter.next() 

El documento dice que dos páginas con la misma etiqueta pueden experimentar condiciones de carrera si ambas usan el mismo nodo. No entiendo cómo la representación dos plantillas podría terminar compartiendo la misma instancia si ambos ejemplifican de forma independiente su propia cuenta.

La manera de resolver esto, dice la documentación es la siguiente:

class CycleNode(Node): 
    def __init__(self, cyclevars): 
     self.cyclevars = cyclevars 
    def render(self, context): 
     if self not in context.render_context: 
      context.render_context[self] = itertools.cycle(self.cyclevars) 
     cycle_iter = context.render_context[self] 
     return cycle_iter.next() 

Esto parece índice context.render_context con self. La implicación de que debe ser que self se utiliza para identificar la instancia de una de dos maneras:

  1. self referencias una instancia específica de la clase en todo el sistema
  2. self referencias esa clase única, y con el fin para hacer referencia a la instancia, se requiere un contexto de representación

Si 1 es verdadero, ¿por qué no asociar datos con self?

Si 2 es verdadero y el contexto de representación está "asociado con el contexto de la plantilla que se está representando actualmente", ¿cómo es posible distinguir entre dos instancias de la etiqueta de plantilla en la misma página?

es el nodo de instancia individualmente cada vez que se invoca la etiqueta? Si es así, ¿por qué los problemas de concurrencia? ¿Si no, porque no?

Respuesta

0

¡Gracias con la lectura más cerca de this.

La plantilla se compila cuando se carga. Cualquier argumento pasado a la función de etiqueta es 'estático'. Son cadenas literales, o son cadenas que se utilizan como identificadores para buscar variables vinculadas en el contexto de representación.

Por lo tanto, el objeto Node se instancia para cada etiqueta y se cuelga listo para usar siempre que se use la plantilla (y, naturalmente, la plantilla se puede usar en cualquier cantidad de subprocesos).

Por lo tanto, el self en mi pregunta es la identidad del Nodo específico dentro de la plantilla. Combinado con el contexto de procesamiento, esto le da una identidad única sobre la cual colgar variables de instancia.

Cuestiones relacionadas