25.12.2013, 06:05 | #1 |
Участник
|
Progress Bar для Batch задачи
По следам бременских музыкантов хотелось бы задать вопрос коллегам, имевшим опыт запуска сразу нескольких экземпляров класса в качестве batch задачи.
После изменения создания progress bar таким образом, чтобы он показывал продвижение во время исполнения, мы видим, как он действительно "ползёт" к 100%, но только для первого запущенного задания! По достижении 100% он возвращается на меньшее значение, скажем, 23% и "ползёт" снова. Второй же экземпляр всегда стоит на нуле. Что происходит при запуске пяти классов, я даже не буду рассказывать в эту рождественскую ночь. В классе SysOperationProgressServer, который и используется в случае запуска в виде Batch, ничего подозрительного не происходит: ни при создании, ни при setCount -- все параметры передаются нормально. Какие-нибудь соображения?
__________________
Felix nihil admirari |
|
27.12.2013, 02:06 | #2 |
Участник
|
Цитата:
Сообщение от wojzeh
По следам бременских музыкантов хотелось бы задать вопрос коллегам, имевшим опыт запуска сразу нескольких экземпляров класса в качестве batch задачи.
Какие-нибудь соображения? налицо три бага, которые мешают адекватно отображать прогресс в случае нескольких прогресс-баров на стороне сервера. во-первых, как было найдено коллегами ранее, параметр, регулирующий вообще запуск прогрессбар на стороне сервера, "заглушен" в вызове RunBase. во-вторых, при создании прогрессбара также необходимо также передавать уникальный GUID, чтобы потом точно знать, какой именно бар "прогрессировать". иначе будет цепляться первый и процент исполнения "скакать" то туда, то сюда -- в зависимости от количества одновременно исполняемых задач. ну, и в-третьих, несмотря на то, что метод kill помечен как "более не нужный", он всё-таки нужен, если по завершении всех задач мы действительно хотим удалить прогрессбар из таблицы SysProgress, иначе они будут там оставаться навсегда, так как преемник reset после удаления просто пересоздаст запись с теми же параметрами. ниже пример вашего класса, который исполняется на сервере как batch, и необходимые коррективы в системных классах. X++: void processSomething() { // maximum number of lines to be processed totalLines = ...; // to enjoy our boring user during a few next hours... this.progressInit("@SYS59011", totalLines, #AviUpdate, 1, null, false, newGuid()); // create the progressbar on the server side if it is not a client session with a new unique GUID while (...) { ... } progress.kill(true); } progressInit X++: /* This method is called to initialize the Progress object in runbase. */ public void progressInit( str caption, int64 total, Filename animation, int numOfBars = 1, FormBuildControl embedded = null, // Begin: Alexey Voytsekhovskiy, bug fix boolean _ifOnSrvBypass = true, guid _callerId = str2guid('') // End: Alexey Voytsekhovskiy, bug fix ) { if (! progress) progress = RunbaseProgress::construct(numOfBars,embedded // Begin: Alexey Voytsekhovskiy, bug fix // to set progressbar on the server side ,_ifOnSrvBypass, _callerId); // End: Alexey Voytsekhovskiy, bug fix progress.setCaption(caption); progress.setTotal(total); progress.setAnimation(animation); } construct X++: public static RunbaseProgress construct( int _numOfBars = 1, FormBuildControl _embedded = null, boolean _ifOnSrvBypass = true, // Begin: Alexey Voytsekhovskiy, bug fix guid _callerId = str2guid('') // End: Alexey Voytsekhovskiy, bug fix ) { return new RunbaseProgress(_numOfBars,_embedded, _callerId, -1, DateTimeUtil::minValue(), _ifOnSrvBypass); } X++: // Begin: Alexey Voytsekhovskiy, reset bug fix #obsolete void kill(boolean _toKill = false) { this.reset(_toKill); } // End: Alexey Voytsekhovskiy, reset bug fix / X++: / Begin: Alexey Voytsekhovskiy, reset bug fix void reset(boolean _toKill = false) // End: Alexey Voytsekhovskiy, reset bug fix { if (oprProgress) oprProgress.reset(); else if (oprProgressServer ) // Begin: Alexey Voytsekhovskiy, reset bug fix oprProgressServer.reset(_toKill); // End: Alexey Voytsekhovskiy, reset bug fix } reset X++: // Begin: Alexey Voytsekhovskiy, reset bug fix public void reset(boolean _toKill = false) // End: Alexey Voytsekhovskiy, reset bug fix { UserConnection conn; SysProgress progress; int i; if ( bypass ) return; conn = new UserConnection(); progress.setConnection(conn); conn.ttsbegin(); try { // delete existing recoreds for this session. delete_from progress where progress.SessionIdx == sessionIdx && progress.SessionLoginDateTime == sessionLoginDateTime; // create records for this session based on number of bars for (i=1; i<=numOfBars; i++) { // Begin: Alexey Voytsekhovskiy, reset bug fix // if the task finished, we have to really kill the progress bar if(!_toKill) { // End: Alexey Voytsekhovskiy, reset bug fix select forupdate * from progress where progress.CallId == callId && progress.ProgressIndex == i; progress.CallId = callId; progress.SessionIdx = sessionIdx; progress.SessionLoginDateTime = sessionLoginDateTime; progress.ProgressIndex = i; // any other default values? progress.write(); } // add the recid into the map progressRecIds[i] = progress.RecId; currentCount[i] = -1; currentIncrement[i] = 0; total[i] = 0; text[i] = ''; } caption = ''; animation = ''; ticksAtLastUpdate = 0; conn.ttscommit(); } catch { conn.ttsabort(); } }
__________________
Felix nihil admirari |
|
|
За это сообщение автора поблагодарили: kashperuk (5), Logger (3), Jorj (1), alex55 (1), iCloud (3). |
03.01.2014, 12:16 | #3 |
Участник
|
Привет.
Багу создам. Только вот - не затруднит ли тебя выложить проектик, где видно было бы ошибку сразу, чтобы скриншотов наделать и к багу присобачить? Спасибо |
|
03.01.2014, 19:29 | #4 |
Участник
|
Цитата:
Вот скриншот А вот детальное описание на английском http://alexvoy.blogspot.ca/2013/12/h...-progress.html
__________________
Felix nihil admirari |
|