Добавил еще ведущие нули к миллисекундам, если кому-то еще когда-то этот код понадобится
log = function (text, color, define){ var id, time, thread, logHtml, textLog; define = (typeof define == 'string') ? define.split(/[\s,.|:;]+/g) : define; if(typeof define === 'object' && define !== null){ if(Array.isArray(define)){ id = define.indexOf('id') > -1; time = define.indexOf('time') > -1; thread = define.indexOf('thread') > -1; } else{ id = define.id == true; time = define.time == true; thread = define.thread == true; } } else id = time = thread = true; id = id ? '<a href="action://action' + ScriptWorker.GetCurrentAction() + '" style="color:gray;">[' + ScriptWorker.GetCurrentAction() + ']</a>' : ''; time = time ? ' ' + getTime() : ''; thread = thread ? ' Поток №' + thread_number() : ''; logHtml = (id || time || thread) ? id + '<span style="color: white">' + time + thread + ' : </span>' : ''; logHtml += '<span style="color:' + (color ? color : 'white') + '">' + text + '</span>'; textLog = '[' + ScriptWorker.GetCurrentAction() + ']' + time + thread + ' : ' + text function getTime(){ var checkTime = function(i){ return (i < 10) ? "0" + i : i; }; var checkMilliSeconds = function(ms){ if (ms < 10) { return "00" + ms; } else if (ms < 100) { return "0" + ms; } else { return ms; } }; var d = new Date(); var hh = checkTime(d.getHours()); var mm = checkTime(d.getMinutes()); var ss = checkTime(d.getSeconds()); var ms = checkMilliSeconds(d.getMilliseconds()); return '[' + hh + ':' + mm + ':' + ss + '.' + ms + ']'; }; Logger.WriteHtml(logHtml, textLog); }Ошибка при работе в многопотоке
-
И ещё что очень странно, данная ошибка "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



