LINUX.ORG.RU

Проблеми с условиями для остановки тредов

 , ,


0

2

Вот код главного скрипта. Он используется как пускалка для скриптов которые пишут в базу (fillers). Часто, при непонятных обстоятельствах получаю для нескольких (от 1 до 6-8 из 26(это мой тестовый набор; потому что отрабатывает быстро)) filler`ов обрезанный лог такого типа

# Logfile created on 2012-08-08 09:54:04 +0300 by logger.rb/31641
[2012-08-08 09:54:04]  INFO: Passed queries:
[2012-08-08 09:54:04]  INFO: ----------------------------------------------------------------------
[2012-08-08 09:54:04]  INFO: INSERT INTO sources (source) VALUES (?);
[2012-08-08 09:54:04]  INFO: ----------------------------------------------------------------------
08_sources.log lines 1-5/5 (END)

вместо следующего нормального

# Logfile created on 2012-08-06 00:28:57 +0300 by logger.rb/31641
[2012-08-06 00:28:57]  INFO: Passed queries:
[2012-08-06 00:28:57]  INFO: ----------------------------------------------------------------------
[2012-08-06 00:28:57]  INFO: INSERT INTO sources (source) VALUES (?);
[2012-08-06 00:28:57]  INFO: ----------------------------------------------------------------------
[2012-08-06 00:28:59]  INFO: =================================== SUMMARY ===================================
[2012-08-06 00:28:59]  INFO: Time elapsed: 2.009950587 seconds
[2012-08-06 00:28:59]  INFO: Total amount of jobs for processing: 29
[2012-08-06 00:28:59]  INFO: Successful inserts: 29
[2012-08-06 00:28:59]  INFO: Faileddddd inserts: 0

чтобы избежать сего бага (логи мне нужны) добавил епический костыль в виде sleep`а. но так так я не уверен был где баг(и), sleep'ы я добавил в оба модули (database, строка 120 и 127; logger, строка 113), которые ждут завершения работы основных тредов (все тот же main script, строки 51-55)

В модуль работы с базой я добавил слип потому что раньше у меня всплывал следующий баг

vv@crusader ~/work/own/python/portage3/bin/db_population $ rm /dev/shm/test-20120724-221542/35_ebuild_descriptions_p3.log && ./35_ebuild_descriptions_p3.rb && cat /dev/shm/test-20120724-221542/35_ebuild_descriptions_p3.log
15837
25013
5832
# Logfile created on 2012-07-25 13:01:31 +0300 by logger.rb/31641
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3133, 14891]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3134, 17036]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3134, 17037]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3135, 10195]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3135, 10198]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3135, 10203]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3136, 3514]
[2012-07-25 13:01:36 +0300] ERROR: Message: cannot use a closed statement
[2012-07-25 13:01:36 +0300] ERROR: Values: [3137, 14993]
[2012-07-25 13:01:36 +0300] ERROR: Some ebuilds(25013 items) miss its description
vv@crusader ~/work/own/python/portage3/bin/db_population $

Сейчас его вроде как нет, но я не уверен что он не «прячется» за другим(и) багами связанными с тредами

Зато сейчас (как и раньше) «редко но метко» выскакивает следующий баг

/home/vv/work/own/python/portage3/lib/common/script.rb:110:in `join': deadlock detected (fatal)
	from /home/vv/work/own/python/portage3/lib/common/script.rb:110:in `block in run_workers'
	from /home/vv/work/own/python/portage3/lib/common/script.rb:110:in `each'
	from /home/vv/work/own/python/portage3/lib/common/script.rb:110:in `run_workers'
	from /home/vv/work/own/python/portage3/lib/common/script.rb:52:in `fill_table_X'
	from /home/vv/work/own/python/portage3/lib/common/script.rb:39:in `initialize'
	from ././db_population/14_packages.rb:21:in `new'
	from ././db_population/14_packages.rb:21:in `<main>'

Я не уверен связан ли он с моей проблемой логгирования, но «раз ж пошла такая пьянка..» (с)

Буду благодарен за дельные советы

cast Anatolik (по мотивам сего коммента)

★★★★★

От лица всего ruby-сообщества напоминаю, что 4 пробела делают нас печальными и заставляют плакать горькими слезами. Если код будет оформлен красиво, количество желающих его прочитать увеличится. Также, каждый раз из-за того, что вы ставите 4 пробела, где-то умирает котик.

Треды в Ruby могут вести себя загадочно, если инсертят в одну переменную одновременно. Поэтому я предлагаю для данной задачи их не использовать, а просто форкать системные процессы и отлавливать в них SQLITE_BUSY.

http://www.sqlite.org/faq.html#q5

Anatolik ★★
()
Ответ на: комментарий от Anatolik

спасибо за ответ

От лица всего ruby-сообщества напоминаю, что 4 пробела делают нас печальными и заставляют плакать горькими слезами. Если код будет оформлен красиво, количество желающих его прочитать увеличится. Также, каждый раз из-за того, что вы ставите 4 пробела, где-то умирает котик.

сейчас исправлю

Треды в Ruby могут вести себя загадочно, если инсертят в одну переменную одновременно.

не уверен на счет места которое вам не понравилось, но libstastral дает вариант только одного типа

  def self.add_data4insert(*item)
      @data4db << item
  end
  ..
  def self.debug(message)
      @log_tasks << [0, message]
  end  
IMHO есть одно
  @data4db = Queue.new
..
  @log_tasks = Queue.new
Да и мануал говорит что все должно быть ok

This class provides a way to synchronize communication between threads

Принимая во внимание все выше сказанное, настаиваете ли Вы все еще на вашем предложении?

Поэтому я предлагаю для данной задачи их не использовать, а просто форкать системные процессы и отлавливать в них SQLITE_BUSY

ZuBB ★★★★★
() автор топика
Ответ на: комментарий от Anatolik

От лица всего ruby-сообщества напоминаю, что 4 пробела делают нас печальными и заставляют плакать горькими слезами. Если код будет оформлен красиво, количество желающих его прочитать увеличится. Также, каждый раз из-за того, что вы ставите 4 пробела, где-то умирает котик.

сейчас исправлю

fixed. urls are same

ZuBB ★★★★★
() автор топика
Ответ на: комментарий от ZuBB

не уверен на счет места которое вам не понравилось, но libstastral дает вариант только одного типа

Честно говоря, после того, как мне не понравились отступы, я на код особо не смотрел. Сейчас, прежде чем искать баг, мне хотелось бы сперва выяснить, действительно ли треды — лучший инструмент для решения этой задачи.

Принимая во внимание все выше сказанное, настаиваете ли Вы все еще на вашем предложении?

Не то чтобы настаиваю, но мне по-прежнему кажется, что таким образом мы добьемся существенно большей производительности. Ведь треды в MRI параллельны фейковой параллельностью. Вы от них почти ничего не выигрываете в обработке данных. Они для «non-blocking I/O» — отправить мейл о подтверждении регистрации, скачать несколько файликов одновременно.

Если бы вы предоставили структуру db и примеры sql-запросов, мы могли бы бенчмаркнуть. Ожидаю, что форки будут в несколько десятков раз быстрее.

Конечно, нужно заметить, что памяти оно тоже будет кушать существенно больше. Однако нынче эта проблема решается покупкой еще одной планки оперативки.

Anatolik ★★
()
Ответ на: комментарий от Anatolik

OMFG. Надеюсь, не все рубисты, такие рубисты.

Ожидаю, что форки будут в несколько десятков раз быстрее.

Да-да, вставка в базу это cpu-bound задача.

но мне по-прежнему кажется

Перекрестись.

Конечно, нужно заметить, что памяти оно тоже будет кушать существенно больше.

Про общие страницы мы не слышали. А память меряем по top, конечно? ЛОЛ.

// ТС, я бы постремался слушать этого «специалиста».

baverman ★★★
()
Ответ на: комментарий от baverman

Да-да, вставка в базу это cpu-bound задача.

Там не только вставка в базу.

Про общие страницы мы не слышали. А память меряем по top, конечно? ЛОЛ.

Не слышали. Расскажите, пожалуйста. Или поделитесь линком.

ТС, я бы постремался слушать этого «специалиста».

Я и не позиционирую себя как «специалиста». Но все же предлагаю ТС проверить мое предположение.

Anatolik ★★
()
Ответ на: комментарий от Anatolik

Честно говоря, после того, как мне не понравились отступы, я на код особо не смотрел. Сейчас, прежде чем искать баг, мне хотелось бы сперва выяснить, действительно ли треды — лучший инструмент для решения этой задачи.

Не то чтобы настаиваю, но мне по-прежнему кажется, что таким образом мы добьемся существенно большей производительности. Ведь треды в MRI параллельны фейковой параллельностью. Вы от них почти ничего не выигрываете в обработке данных. Они для «non-blocking I/O» — отправить мейл о подтверждении регистрации, скачать несколько файликов одновременно.

Изначально у меня все хорошо работало без тредов. Но потом оказалось что для некоторых filler`ов есть проблема со сбором данных (у filler'а есть 3 обязательные фазы: собрать данные, обработать их (в тредах), добавить в очередь на запись). Проблема заключалась в следующем: мой парсер для сбора данных не всегда работал правильно, ибо был очень простенький. Дописать его до состояния «все фурычит» не придставлялось вожможным по ряду причин (опустим их). Но нашлась возможность заюзать третью тулзу для сего. Она как оказалось работает ну очень медленно и ее основная проблема как раз IO (даже не зная ее внуренностей, но видя время работы я бы вполне сказал что очень даже blocking I/O :) ). Но тогда я то не знал что треды как раз не для сего предназначены..

Вообщем когда я был на разпутье, человек-лазер из кваки tailgunner высказал очень здравую мысль. Которую я взялся тихонечко воплощать. Итого, из основных time consuming проблем осталась только та, где юзается та злосщастная тулза. У меня есть пара вариантов, которые возможно помогут (а возможно и нет) побороть эту проблему.

Если один из них поможет, то вы возможно спросите «нужны ли треды тогда вообще?». Ну я бы не очень хотел «возвращаться назад». тем более теперешний код мне нравится во всех отношениях. окромя сабжевой проблеммы :(

Если же ни один из них не поможет, то остается multirocessing. Но у меня не будет времени на это до окончания прототипа. А что будет после представления прототипа я не знаю.

Если бы вы предоставили структуру db

https://github.com/zvasyl/portage3/blob/master/sql/portage.sqlite.sql

..и примеры sql-запросов

В конце каждого скрипта (осторожно, табуляция 4(!) пробела) есть параметр sql_query. Там очень простые insert`ы.

..мы могли бы бенчмаркнуть. Ожидаю, что форки будут в несколько десятков раз быстрее.

IMHO больше 2-3 раз. Но повторяю проблема не в базе или вставке. проблема в обработке, когда начинает работать та тулза. см примеры

все ок

vv@crusader /dev/shm/portage-cache-20120808-221310-UTC $ cat 31_ebuilds.log 
# Logfile created on 2012-08-09 01:13:56 +0300 by logger.rb/31641
[2012-08-09 01:13:56]  INFO: Passed queries:
[2012-08-09 01:13:56]  INFO: ----------------------------------------------------------------------
[2012-08-09 01:13:56]  INFO:         INSERT INTO ebuilds
        (package_id, version, repository_id)
        VALUES (?, ?, ?);

[2012-08-09 01:13:56]  INFO: ----------------------------------------------------------------------
[2012-08-09 01:14:17]  INFO: =================================== SUMMARY ===================================
[2012-08-09 01:14:17]  INFO: Time elapsed: 21.488316091 seconds
[2012-08-09 01:14:17]  INFO: Total amount of jobs for processing: 31907
[2012-08-09 01:14:17]  INFO: Successful inserts: 31907
[2012-08-09 01:14:17]  INFO: Faileddddd inserts: 0
vv@crusader /dev/shm/portage-cache-20120808-221310-UTC $ 

начинается

# Logfile created on 2012-08-09 01:14:24 +0300 by logger.rb/31641
[2012-08-09 01:14:24]  INFO: Passed queries:
[2012-08-09 01:14:25]  INFO: ----------------------------------------------------------------------
[2012-08-09 01:14:25]  INFO:         INSERT INTO ebuild_keywords
        (ebuild_id, keyword_id, arch_id, source_id)
        VALUES (
            ?,
            (SELECT id FROM keywords WHERE name=?),
            (SELECT id FROM arches WHERE name=?),
            ?
        );

[2012-08-09 01:14:25]  INFO: ----------------------------------------------------------------------
[2012-08-09 01:14:25]  INFO: Ebuild: app-accessibility-sphinx3-0.8
[2012-08-09 01:14:25]  INFO: Ebuild: app-accessibility-sphinxbase-0.7
...
skipped
...
[2012-08-09 01:20:08]  INFO: =================================== SUMMARY ===================================
[2012-08-09 01:20:08]  INFO: Time elapsed: 343.333800634 seconds
[2012-08-09 01:20:08]  INFO: Total amount of jobs for processing: 31907
[2012-08-09 01:20:08]  INFO: Successful inserts: 202918
[2012-08-09 01:20:08]  INFO: Faileddddd inserts: 29758

а все вот из за этого

vv@crusader /dev/shm/portage-cache-20120808-221310-UTC $ grep -m 1 WARN 33_ebuild_keywords.log 
[2012-08-09 01:14:26]  WARN: Running portageq to get a KEYWORDS for app-accessibility/emacspeak-9999
vv@crusader /dev/shm/portage-cache-20120808-221310-UTC $ grep -c WARN 33_ebuild_keywords.log 
448
vv@crusader /dev/shm/portage-cache-20120808-221310-UTC $ 

offtop

09.08.2012 7:02:31

рано подымаетесь, респект

ZuBB ★★★★★
() автор топика
Ответ на: комментарий от baverman

По большей части вы правы, но это человек подсказал мне в ситуации, когда никто не смог (хотя, не отрицаю, что и вы мне помогали хорошым советом не раз). так что слушать я буду всех, а делать то что кажется мне разумнее всего.

лучше не ссорьтесь, а тоже подумайте над решением сабжевой задачи (дело ведь не в рубях, а в логике). ниже я дал некоторые обьяснения

ZuBB ★★★★★
() автор топика

baverman, Anatolik

весь фокус происходит в методе fill_table_X (строки 42-69). но код который работает с тредами есть только в строках 51 - 68. его и нужно смотреть

ZuBB ★★★★★
() автор топика
Последнее исправление: ZuBB (всего исправлений: 1)
Ответ на: комментарий от Anatolik

треды таки работают :)

[2012-08-10 08:45:10]  INFO: =================================== SUMMARY ===================================
[2012-08-10 08:45:10]  INFO: Time elapsed: 612.886612647 seconds
[2012-08-10 08:45:10]  INFO: Total amount of jobs for processing: 31931
[2012-08-10 08:45:10]  INFO: Successful inserts: 227539
[2012-08-10 08:45:10]  INFO: Faileddddd inserts: 0
[2012-08-10 08:45:10]  INFO: Thread 'worker #0' processed 31931 items
[2012-08-10 09:01:01]  INFO: =================================== SUMMARY ===================================
[2012-08-10 09:01:01]  INFO: Time elapsed: 346.034721533 seconds
[2012-08-10 09:01:01]  INFO: Total amount of jobs for processing: 31931
[2012-08-10 09:01:01]  INFO: Successful inserts: 227539
[2012-08-10 09:01:01]  INFO: Faileddddd inserts: 0
[2012-08-10 09:01:01]  INFO: Thread 'worker #0' processed 7024 items
[2012-08-10 09:01:01]  INFO: Thread 'worker #1' processed 6451 items
[2012-08-10 09:01:01]  INFO: Thread 'worker #2' processed 10019 items
[2012-08-10 09:01:01]  INFO: Thread 'worker #3' processed 8437 items

но все равно это медленно :(

ZuBB ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.