Ошибка при работе в многопотоке

Поддержка
  • Дополню: Первый поток быстрее начинает делать вторую часть скрипта и успевает сделать 2 парса и после второго успешного моментально вылезает ошибка.

  • При вызове функции "Threads1 / 2", скрипт переходит и там весь скрипт лежит в функции For, может ли из-за него эта ошибка быть?
    image.png

    При одном потоке, скрипт работает, как по маслу.

  • И ещё что очень странно, данная ошибка "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-го, где идёт сохранение всего спаршенного"

    a196d8d7-8772-487e-b2ca-24f48141d137-image.png

    Но я не вижу там проблемы, так как если взять и запустить скрипт для второго потока в одиночку, всё работает, так же во многопотоке при начале второй поток успешно проходит свой скрипт.
    Вот я думаю может проблема в запуске функции, может что-то вроде асинхронной функции попробовать или не в этом проблема?

  • Ребят, есть варианты, из-за чего так происходит?

  • @tekerosi said in Ошибка при работе в многопотоке:

    Ребят, есть варианты, из-за чего так происходит?

    Да.

    Можно избежать возникновение таких ошибок:

    • Не использовать метки. Вообще, никогда, даже если очень хочется.
    • Не использовать глобальные переменные. Вообще, никогда, даже если очень хочется.
    • Разбивать логику на функции. Функция после работы не должна оставлять после себя мусор в виде переменных.
    • Всю подготовительную работу, если она нужна, делать в OnApplicationStart.
    • Изолировать код друг от друга, например, запускать часть кода в изолированном потоке.
    • Не игнорировать ошибки при записи в файл, так как это критичные ошибки и скрипт не должен продолжать работу.
    • .....

    Иногда, чтобы машина ехала нормально, надо сменить квадратные колеса на круглые. Квадратные колеса можно чинить долго и упорно.

  • @tekerosi проверь, нет ли одинаковых меток в функциях Threads1/2. И вообще давай имена меткам текстом и без пробелов и не длиной в предложение...

  • @sergerdn
    Привет, метки и глобальные переменные почему лучше не использовать?

  • @tekerosi
    Где у тебя задаётся эта пременнная? "SHOWING_LIST_HOTEL2"
    Смотри почему она не записывается в много потоке.
    В чём вообще отличие thread 1-2

  • @Vituskosoy Метки одинаковые есть, я даже сказал бы они идентичны. Но Первый поток не мог перепрыгнуть аж в конец скрипта второго по какой-либо из них, так как там ещё нужно проработать блоков так 10-15 до них. Но теория интересная. попробую, поменять имена меток всех.

  • @lesliwp "SHOWING_LIST_HOTEL2" создается уже внутри функции "threads1/2"
    19768719-93c0-43b1-8756-a3041c66c16c-image.png
    dc1cd353-21be-46c5-947b-58a6747ac795-image.png

    по сути разницы между threads 1/2. Только при создании каждой функции для них 1, меняется на 2, соответственно если это для второго потока функция.
    256e7e2c-725e-484e-8372-7e0ae7e3f2bc-image.png

  • @tekerosi Сложно что то конкертное вам порекомендовать. @sergerdn прав по поводу того что метки и глоб переменные часто могут руинить логику, но это совсем не значит что их нельзя использовать. дело в том как вы их используете. Тут скорее всего так и есть, и где-то в многопотоке метку что то тригрерит и логика не такая как нужна. Вы говорили что в одном потоке все работает отлично. Так если вам всего два потока нужно то запустите по одному потоку в разных инстансах, и работайте так. Порой это быстрее чем копаться не пойми где.

    @tekerosi said in Ошибка при работе в многопотоке:

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

    Это похоже на то что идет наложение меток и когда один из потоков тригернул общую метку она сработала во всех потоках.
    Возможным решением будет попробовать разделить метки для каждого потока так как вы разделили переменые через условие.
    Также если у вас есть метки в которых хопы не в рамках одной функции это тоже может пагубно влиять на логику в запуске или вовсе ее руинить.

    Также насколько я помню, если запускать один и тот же XLM в нескольких окнах метки и глоб. переменные тоже будут тригерится друг на друга между окнами.

    Также после каждой метки можно поставить какое-то сообщение указывающее явно для вас что это за место. так можно проверить Дело это в метках или нет.

  • @lesliwp said in Ошибка при работе в многопотоке:

    @sergerdn
    Привет, метки и глобальные переменные почему лучше не использовать?

    @hvrsh said in Ошибка при работе в многопотоке:

    @sergerdn прав по поводу того что метки и глоб переменные часто могут руинить логику, но это совсем не значит что их нельзя использовать. дело в том как вы их используете.

    Метки и глобальные переменные надо уметь готовить. А кто умеет готовить их, тот понимает, что есть пути менее плодовитые к багам. И не использует их.
    Парадокс.

  • @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
  • @sergerdn Спасибо. Посмотрю на досуге.