buffer de saída rendimento mod_wsgi em vez de retorno
Pergunta
Agora eu tenho um script mod_wsgi que está estruturado como este ..
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Eu queria saber se alguém sabe de uma maneira de mudar isso para operar numa base yield
vez de return
, de que maneira eu posso enviar a página como está sendo gerado e não apenas uma vez que está completo, assim que o carregamento da página pode ir mais rápido para o usuário.
No entanto, sempre que eu trocar a saída para uma lista e deu-lo no aplicativo (), ele lança um erro:
TypeError: sequence of string values expected, value of type list found
Solução
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
yield output
"No entanto, sempre que eu trocar a saída para uma lista e deu-lo no aplicativo (), ele lança um erro:"
Bem, não deu a lista. Rendimento de cada elemento em vez disso:
for part in mylist:
yield part
ou se a lista é o conteúdo inteiro, apenas:
return mylist
Como a lista já é um iterador e pode produzir por si só.
Outras dicas
Note que 'rendimento' deve ser evitado, a menos que seja absolutamente necessário. Em particular 'rendimento' será ineficaz se obtendo-se lotes de pequenas cadeias. Isso ocorre porque a especificação WSGI exige que depois de cada corda concluiu que a resposta deve ser lavada. Para Apache / mod_wsgi, meios de lavagem cada cadeia a ser forçado para fora através do filtro e do sistema brigada balde saída Apache e para a tomada. Ignorando a sobrecarga do sistema Apache filtro de saída, escrevendo lotes de pequenas cordas em um soquete é simplesmente mau para começar.
Este problema também existe quando uma matriz de cadeias é retornado de uma aplicação como uma descarga também tem de ser realizada entre cada cadeia na matriz. Isto é porque a cadeia é tratada como um iterable e não uma lista. Assim, para uma lista pré-formado de cordas, é muito melhor para se juntar as cordas individuais em uma cadeia de grandes dimensões e retornar uma lista contendo apenas que uma string. Isso também permite uma implementação WSGI para gerar automaticamente um Content-Length para a resposta se não foi explicitamente previsto.
Apenas certifique-se de que, quando se juntar todas as cordas em uma lista em um, que o resultado é retornado em uma lista. Se isso não for feito e, em vez da string é devolvida, essa seqüência é tratada como uma iterable, onde cada elemento na string é uma única cadeia de caracteres. Isso resulta em um flush a ser feito depois de cada personagem, que vai ser ainda pior do que se as cordas não tinha sido unidas.
Não envie o comprimento de conteúdo e enviar a saída como você derivar dele. Você não precisa saber o tamanho da saída, se você simplesmente não fazer enviar o cabeçalho Content-Length. Dessa forma, pode enviar parte da resposta antes de ter calculado o resto.
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/html')]
start_response(status, response_headers)
yield head()
yield part1()
yield part2()
yield part3()
yield "<!-- bye now! -->"
Caso contrário, você terá nenhum benefício a partir do envio de pedaços, desde computar a saída é provavelmente a parte lenta e o protocolo de internet irá enviar a saída em pedaços de qualquer maneira.
Infelizmente, isso não funciona no caso em que, por exemplo, o cálculo
de part2 () decide que você realmente precisa mudar um cabeçalho (como um cookie)
ou necessidade de construir outras estruturas de dados da página global
- se isso nunca acontece, você precisa calcular a saída inteira antes
enviando os cabeçalhos, e poderia muito bem usar um return [output]
Por exemplo http://aaron.oirt.rutgers.edu/myapp/ docs / W1200_1200.config_template Precisa construir uma estrutura de dados global de página para os links para subseções que show no topo da página - por isso a última subseção deve ser processado antes do primeiro pedaço de saída é entregue ao cliente.