Я читаю много данных из ldap, которые необходимо сравнить с соответствующими записями в базе данных. Чтобы свести к минимуму количество запросов SQL, я хочу объединить несколько записей ldap в один запрос.
Все это довольно просто: поток для получения результатов ldap и поток для использования этих результатов и запуска SQL-запроса.
ldap_results = Queue.Queue(10)
def producer():
for result in ldap_results():
ldap_results.put(result)
def consumer():
buffer = []
buffer_size = 5
while True:
record = ldap_results.get()
buffer.append(record)
if len(buffer) >= buffer_size:
do_sql(buffer)
buffer = []
Проблема в том, что если ldap вернет, скажем, 3 результата, а buffer_size
равен 5, то блокировка будет продолжаться вечно. Я понимаю, что могу поместить в буфер какой-то специальный токен, например None
или "EOF"
, но это выглядит как плохой дизайн: «повторяйте, пока не закончите, о, если вы не видите это специальное значение, это означает сделано тоже ".
Я предложил две альтернативные идеи. Первый - иметь общую переменную eof
, но я не знаю, как правильно ее синхронизировать.
def producer():
while data:
buffer.put()
eof = True
def consumer():
while not eof:
buffer.get()
Второй - иметь метод ProduceChunks(chunk_size)
для производителя, и он будет обрабатывать пакетирование результатов, но мне это не нравится, потому что предполагается, что производитель будет знать, как лучше всего буферизовать результаты, когда действительно, я думаю, что это ответственность потребителя.
У кого-нибудь есть руководство?