Pergunta

Estou trabalhando em uma biblioteca Python que faz interface com uma API de serviço da web.Como muitos serviços da web que encontrei, este solicita a limitação da taxa de solicitações.Eu gostaria de fornecer um parâmetro opcional, limit, para a instanciação da classe que, se fornecida, reterá as solicitações de saída até que o número de segundos especificado passe.

Entendo que o cenário geral é o seguinte:uma instância da classe faz uma solicitação por meio de um método.Quando isso acontece, o método emite algum sinal que define uma variável de bloqueio em algum lugar e inicia uma contagem regressiva para o número de segundos em limit.(Com toda a probabilidade, o bloqueio é o próprio cronômetro de contagem regressiva.) Se outra solicitação for feita dentro desse período, ela deverá ser colocada na fila até que o cronômetro de contagem regressiva chegue a zero e o bloqueio seja desativado;neste ponto, a solicitação mais antiga na fila é enviada, o cronômetro de contagem regressiva é redefinido e o bloqueio é reativado.

Este é um caso para threading?Existe outra abordagem que não estou vendo?

O cronômetro de contagem regressiva e o bloqueio devem ser variáveis ​​de instância ou devem pertencer à classe, de modo que todas as instâncias da classe contenham solicitações?

Além disso, geralmente é uma má ideia fornecer funcionalidade de limitação de taxa em uma biblioteca?Eu raciocino, já que, por padrão, a contagem regressiva é de zero segundos, a biblioteca ainda permite que os desenvolvedores usem a biblioteca e forneçam seus próprios esquemas de limitação de taxa.Dado que qualquer desenvolvedor que use o serviço precisará limitar as solicitações de qualquer maneira, imagino que seria uma conveniência para a biblioteca fornecer um meio de limitação de taxa.

Independentemente de colocar ou não um esquema de limitação de taxa na biblioteca, vou querer escrever um aplicativo usando a biblioteca, portanto, as técnicas sugeridas serão úteis.

Muito obrigado por suas sugestões!

Chris

Foi útil?

Solução

Isso funciona melhor com uma fila e um despachante.

Você divide seu processamento em dois lados: fonte e Despacho.Podem ser threads separados (ou processos separados, se for mais fácil).

O Fonte lado cria e enfileira solicitações na proporção que os deixa satisfeitos.

O Despacho lado faz isso.

  1. Obtenha a hora de início da solicitação, é.

  2. Remove uma solicitação da fila e processa a solicitação por meio do serviço remoto.

  3. Obtenha a hora atual, t.Durma por avaliar - (t - é) segundos.

Se você quiser executar o Fonte lado conectado diretamente ao serviço remoto, você pode fazer isso e ignorar a limitação de taxa.Isso é bom para testes internos com uma versão simulada do serviço remoto.

A parte difícil disso é criar alguma representação para cada solicitação que você pode enfileirar.Desde o Python Fila vai lidar com quase tudo, você não precisa fazer muito.

Se você estiver usando multiprocessamento, você terá que salmoura seus objetos para colocá-los em um cano.

Outras dicas

A fila pode ser excessivamente complicada.Uma solução mais simples é fornecer à sua classe uma variável referente ao horário em que o serviço foi chamado pela última vez.Sempre que o serviço for chamado (!1), defina waitTime como delay - Now + lastcalltime. delay deve ser igual ao tempo mínimo permitido entre as solicitações.Se esse número for positivo, durma um pouco antes de fazer a ligação (!2).A desvantagem/vantagem desta abordagem é que ela trata as solicitações de serviços da web como sendo síncronas.A vantagem é que é absurdamente simples e fácil de implementar.

  • (!1):Deve acontecer logo após receber uma resposta do serviço, dentro do wrapper (provavelmente na parte inferior do wrapper).
  • (!2):Deve acontecer quando o wrapper python em torno do serviço da web for chamado, na parte superior do wrapper.

A solução da S.Lott é mais elegante, claro.

Seu esquema de limitação de taxa deve ser fortemente influenciado pelas convenções de chamada do código subjacente (síncrono ou assíncrono), bem como em qual escopo (thread, processo, máquina, cluster?) Essa limitação de taxa irá operar.

Eu sugeriria manter todas as variáveis ​​dentro da instância, para que você possa implementar facilmente vários períodos/taxas de controle.

Por último, parece que você deseja ser um componente de middleware.Não tente ser um aplicativo e introduzir tópicos por conta própria.Apenas bloqueie/hiberne se você for síncrono e use a estrutura de despacho assíncrono se estiver sendo chamado por um deles.

Se sua biblioteca for projetada para ser síncrona, recomendo deixar de fora a aplicação de limites (embora você possa acompanhar as taxas e pelo menos ajudar o chamador a decidir como respeitar os limites).

eu uso torcido para interagir com praticamente tudo hoje em dia.Isso torna mais fácil fazer esse tipo de coisa por ter um modelo que separa o envio de solicitações do tratamento de respostas.Se você não deseja que os usuários da API usem distorções, seria melhor pelo menos entender a API deles para execução adiada.

Por exemplo, tenho uma interface no Twitter que envia um número absurdo de solicitações em nome de usuários xmpp.Não avalio limite, mas tive que trabalhar um pouco para evitar que todas as solicitações acontecessem ao mesmo tempo.

Não reinvente a roda, a menos que seja necessário.Verifique a incrível biblioteca taxa limite.Perfeito se você deseja apenas limitar a taxa de suas chamadas para uma API de descanso por qualquer motivo e seguir com sua vida.

Então, estou assumindo que algo simples como o tempo de importação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top