@basuser123 thank you
Ошибка при работе в многопотоке
-
Всем привет. Есть скрипт, который цепляется к значению потока и для каждого потока выполняются свои действия (почти идентичны, сделано так, потому что для каждого потока разные данные идут). И вот столкнулся с проблемой: Первая часть работы скрипт успешна у обоих потоков, после 1-й поток переходит, ко второй, теперь к проблеме: Первый поток делает свои действия и как я заметил когда второй поток переходит на вторую часть скрипта, первый поток перепрыгивает на скрипт второго потока, искал искал не нашёл проблемы, почему так происходит. Приложу скрины, скрипта и ошибки.

В ошибке выводит как раз таки "ReferenceError: Can't find variable: VAR_SHOWING_LIST_HOTEL2 во время выполнения действия", но эта переменная с таким значением, только в функции для второго потока есть.
-
И ещё что очень странно, данная ошибка "ReferenceError: Can't find variable: VAR_SHOWING_LIST_HOTEL2 во время выполнения действия" в скрипте 2-го потока лежит, довольно таки далеко и она никак не может выводиться моментально после проработки парса у первого потока, получается он перепрыгивает на второй поток + перепрыгивает на конец скрипта 2-го, где идёт сохранение всего спаршенного
-
@tekerosi said in Ошибка при работе в многопотоке:
Приложу скрины, скрипта и ошибки.
Возле той же ошибки что вы приложили скрином есть айди блока в котором он была, вот и используя этот айди и поиск вы можете и найти на каком блоке у вас была ошибка, а то пока сложно поянть что у вас там происходит.
-
@hvrsh Я знаю про id и уже искал проблему там, но её там не может быть.
Продублирую пред. сообщение, я там написал как раз таки про блок с id, которым выходит ошибка.
"И ещё что очень странно, данная ошибка "ReferenceError: Can't find variable: VAR_SHOWING_LIST_HOTEL2 во время выполнения действия" в скрипте 2-го потока лежит, довольно таки далеко и она никак не может выводиться моментально после проработки парса у первого потока, получается он перепрыгивает на второй поток + перепрыгивает на конец скрипта 2-го, где идёт сохранение всего спаршенного"

Но я не вижу там проблемы, так как если взять и запустить скрипт для второго потока в одиночку, всё работает, так же во многопотоке при начале второй поток успешно проходит свой скрипт.
Вот я думаю может проблема в запуске функции, может что-то вроде асинхронной функции попробовать или не в этом проблема? -
@tekerosi said in Ошибка при работе в многопотоке:
Ребят, есть варианты, из-за чего так происходит?
Да.
Можно избежать возникновение таких ошибок:
- Не использовать метки. Вообще, никогда, даже если очень хочется.
- Не использовать глобальные переменные. Вообще, никогда, даже если очень хочется.
- Разбивать логику на функции. Функция после работы не должна оставлять после себя мусор в виде переменных.
- Всю подготовительную работу, если она нужна, делать в OnApplicationStart.
- Изолировать код друг от друга, например, запускать часть кода в изолированном потоке.
- Не игнорировать ошибки при записи в файл, так как это критичные ошибки и скрипт не должен продолжать работу.
- .....
Иногда, чтобы машина ехала нормально, надо сменить квадратные колеса на круглые. Квадратные колеса можно чинить долго и упорно.
-
@Vituskosoy Метки одинаковые есть, я даже сказал бы они идентичны. Но Первый поток не мог перепрыгнуть аж в конец скрипта второго по какой-либо из них, так как там ещё нужно проработать блоков так 10-15 до них. Но теория интересная. попробую, поменять имена меток всех.
-
@tekerosi Сложно что то конкертное вам порекомендовать. @sergerdn прав по поводу того что метки и глоб переменные часто могут руинить логику, но это совсем не значит что их нельзя использовать. дело в том как вы их используете. Тут скорее всего так и есть, и где-то в многопотоке метку что то тригрерит и логика не такая как нужна. Вы говорили что в одном потоке все работает отлично. Так если вам всего два потока нужно то запустите по одному потоку в разных инстансах, и работайте так. Порой это быстрее чем копаться не пойми где.
@tekerosi said in Ошибка при работе в многопотоке:
и как я заметил когда второй поток переходит на вторую часть скрипта, первый поток перепрыгивает на скрипт второго потока
Это похоже на то что идет наложение меток и когда один из потоков тригернул общую метку она сработала во всех потоках.
Возможным решением будет попробовать разделить метки для каждого потока так как вы разделили переменые через условие.
Также если у вас есть метки в которых хопы не в рамках одной функции это тоже может пагубно влиять на логику в запуске или вовсе ее руинить.Также насколько я помню, если запускать один и тот же XLM в нескольких окнах метки и глоб. переменные тоже будут тригерится друг на друга между окнами.
Также после каждой метки можно поставить какое-то сообщение указывающее явно для вас что это за место. так можно проверить Дело это в метках или нет.
-
@lesliwp said in Ошибка при работе в многопотоке:
@sergerdn
Привет, метки и глобальные переменные почему лучше не использовать?@hvrsh said in Ошибка при работе в многопотоке:
@sergerdn прав по поводу того что метки и глоб переменные часто могут руинить логику, но это совсем не значит что их нельзя использовать. дело в том как вы их используете.
Метки и глобальные переменные надо уметь готовить. А кто умеет готовить их, тот понимает, что есть пути менее плодовитые к багам. И не использует их.
Парадокс. -
@hvrsh said in Ошибка при работе в многопотоке:
@sergerdn Есть вариант буфер в многопотоке лочить без глоб. переменых?
Можно использовать файловый lock, как имитацию mutex. Вероятно, в это случае без NodeJS не обойтись.
BAS как-то по особенному работает с потокам, может быть можно взять эксклюзивный lock по простому. Но я не знаю как.
-
@sergerdn посмотрел бы с удовольствием на реализацию, т.к мне как пользователю баса с каким не каким но опытом малопонятно это предложение, и чем это вариант объективно лучше глоб переменной. В основном люди идут по пути упрощенния что на первый взгляд не сказать об вашем варианте.
-
@hvrsh said in Ошибка при работе в многопотоке:
@sergerdn посмотрел бы с удовольствием на реализацию
Еле нашел релеватную инфу блокировкам - http://community.bablosoft.com/post/159366.
Вкратце, то в BAS код может быть не асинхронным. А вызывая синхронный код в одном из потоков, все остальные потоки ждут и ничего не делают.И получаем глобальную блокировку всех потоков выполнения как некий побочный эффект.
В NodeJS можно использовать https://www.npmjs.com/package/async-lock.
@hvrsh said in Ошибка при работе в многопотоке:
и чем это вариант объективно лучше глоб переменной.
Я исхожу из того, что глобальные переменные это плохо, так как захламлять пространство имен не может быть хорошим стилем программирования. Для меня это аксиома.
И как будут вести себя модули, если внутри модуль будет работать с глобальными переменными, это я не знаю. А если не знаю, то и не использую.
Вероятно, есть варианты, когда не остается никаких путей, кроме глобальных переменных, например:
- нужно провести инициализацию модуля, чтобы не вызывать одни и те же действия каждый раз при вызове функции из модуля
- хочется иметь глобальный объект с настройками скрипта, чтобы его не таскать по всем потокам, для передачи как параметр в функции
- может быть иметь глобальный явный mutex, как я выше дал ссылку - http://community.bablosoft.com/post/159366



