Pregunta

En mod_wsgi envío los encabezados ejecutando la función start_response(), pero todo el contenido de la página se pasa mediante rendimiento/retorno.¿Hay alguna forma de pasar el contenido de la página de forma similar a start_response()?El uso de la declaración return.yield es muy restrictivo cuando se trata de trabajar con datos fragmentados.

P.ej.

def Application():

    b = buffer()

    [... page code ...]

    while True:
        out = b.flush()    
        if out:
            yield out

class buffer:

    def __init__(self):        
        b = ['']
        l = 0

    def add(self, s):
        s = str(s)
        l += len(s)
        b.append(s)

    def flush(self):

        if self.l > 1000:
            out = ''.join(b)
            self.__init__()
            return out

Quiero que el búfer genere el contenido a medida que se carga la página, pero solo genere el contenido una vez que se haya acumulado una cantidad suficiente (en este ejemplo,1000 bytes).

¿Fue útil?

Solución

No; Pero no creo que es restrictiva. Tal vez usted quiere pegar un código de ejemplo en el que describe su restricción y nos puede ayudar.

Para trabajar con datos trozo que acaba de yield los trozos:

def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    for chunk in chunk_data_generator():
        yield chunk

def chunk_data_generator()
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'

Editar : Basado en los comentarios que diste, un ejemplo de acumular datos hasta una cierta longitud antes de enviar hacia adelante:

BUFFER_SIZE = 10 # 10 bytes for testing. Use something bigger
def application(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')]
    buffer = []
    size = 0
    for chunk in chunk_generator():
        buffer.append(chunk)
        size += len(chunk)
        if size > BUFFER_SIZE:
            for buf in buffer:
                yield buf
            buffer = []
            size = 0

def chunk_data_generator()
    yield 'Chunk 1\n'    
    yield 'Chunk 2\n'    
    yield 'Chunk 3\n'
    yield 'Chunk 4\n'
    yield 'Chunk 5\n'

Otros consejos

Es posible para que su aplicación "envíe" datos al servidor WSGI:

Algunas API del marco de aplicaciones existentes admiten salida sin búfer de una manera diferente a WSGI.Específicamente, proporcionan una función o método de "escritura" de algún tipo para escribir un bloque de datos sin búfer, o bien proporcionan una función de "escritura" en búfer y un mecanismo de "vaciado" para vaciar el búfer.

Desafortunadamente, dichas API no se pueden implementar en términos del valor de retorno de la aplicación "iterable" de WSGI, a menos que se utilicen subprocesos u otros mecanismos especiales.

Por lo tanto, para permitir que estos marcos continúen usando una API imperativa, WSGI incluye una write() invocable, devuelto por el start_response invocable.

Nuevas aplicaciones y marcos WSGI no debe utilizar el write() invocable si es posible evitarlo.

http://www.python.org/dev/peps/pep-0333/#the-write-callable

Pero no es recomendable.

En términos generales, las aplicaciones lograrán el mejor rendimiento almacenando en un buffer su salida (de tamaño modesto) y enviándola toda a la vez.Este es un enfoque común en marcos existentes como Zope:la salida se almacena en un StringIO o un objeto similar y luego se transmite toda a la vez, junto con los encabezados de respuesta.

El enfoque correspondiente en WSGI es que la aplicación simplemente devuelva un iterable de un solo elemento (como una lista) que contenga el cuerpo de la respuesta como una sola cadena.Este es el enfoque recomendado para la gran mayoría de funciones de aplicaciones, que representan páginas HTML cuyo texto cabe fácilmente en la memoria.

http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming

Si no desea cambiar su aplicación WSGI sí para amortiguar parcialmente los datos de respuesta antes de enviarlo, a continuación, aplicar un middleware WSGI que envuelve su aplicación WSGI y que lleva a cabo esa tarea.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top