Я разработал базовый прокси-тестер на Python. IP-адреса и порты прокси, а также их date_of_last_test
(например, 31.12.2011 10:10:10) и result_of_last_test
(OK или KO) хранятся в одной таблице SQLite. (Я понимаю, что могу хранить намного больше деталей о результатах тестов и вести историю / статистику, но эта простая модель удовлетворяет моим потребностям).
Вот упрощенный код основного цикла тестера, где я зацикливаюсь на прокси и обновляю их статус:
while True:
# STEP 1: select
myCursor.execute("SELECT * from proxy ORDER BY date_of_last_test ASC;")
row = myCursor.fetchone()
# STEP 2: update
if isProxyWorking(row['ip'], row['port']): # this test can last a few seconds
updateRow(row['ip'], row['port'], 'OK')
else:
updateRow(row['ip'], row['port'], 'KO')
Мой код работает нормально, когда выполняется как один процесс. Теперь я хотел бы иметь возможность запускать многие процессы программы, , используя один и тот же файл базы данных SQLite .
Проблема с текущим кодом заключается в отсутствии механизма блокировки, который не позволял бы нескольким процессам тестировать один и тот же прокси.
Каким был бы самый простой способ установить блокировку строки в STEP 1 / время SELECT , чтобы следующий процесс, выполняющий SELECT, получил следующую строку?
Другими словами, я бы хотел избежать следующей ситуации:
Допустим, сейчас 10 вечера, а в БД есть 2 прокси:
Прокси A
, протестированный в последний раз в 20:00, и прокси B
, протестированный в 21:00.
Я запускаю два процесса тестера, чтобы обновить их статусы:
- 10: 00 - Процесс 1 получает «самый старый» прокси для его проверки:
A
- 10: 01 -
Процесс 2 получает «самый старый» прокси для его проверки: !!!
A
!!! (здесь я бы
как Процесс 2, чтобы получить прокси B
, потому что A
уже тестируется -
хотя еще не обновлен в БД)
- 10: 10 - Тестирование
A
по процессу 1
статус обновлен в БД
- 10: 11 - Тестирование
A
по процессу 2
более того, его статус обновляется (!!! СНОВА !!!) в БД
В этом случае нет фактической ошибки / исключения, но я хочу избежать пустой траты.