Имя: Пароль:
1C
1С v8
Завершение фоновых заданий (проблема реализации многопоточности в 1С)
0 adelaide
 
21.02.14
13:55
Пытаюсь реализовать многопоточность в 1С при помощи фоновых заданий.
Обработка запускает 100 потоков (фоновых заданий), на выполнение им выделяется 20 секунд, после чего задания грохаются: тФоновоеЗадание.Отменить();    
и запускается новая партия фоновых заданий, так вот, проблема в том что не всегда они завершаются, и на сервере они накапливаются и база зависает.
Версия платформы: 8.2.19.83
1 Dolphinbet
 
21.02.14
14:09
Зачем??
2 adelaide
 
21.02.14
14:11
(1) что зачем? многопоточность? ну есть у меня такая задача, цены конкурентов парсить.

Кусок кода, может в нем что не так :( :

        Если МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
            Попытка
                ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий, 15);
            Исключение
                //что-то пошло не так, даем 15 сек. завершится заданиям:
                глПауза(15);
            КонецПопытки;
            //-----------------------------------------------------------------
            //все что не успело завершится завершаем принудительно:
            //-----------------------------------------------------------------
            Отбор = Новый Структура;
            Отбор.Вставить("Наименование",     "ПолучениеПредложений");
            Отбор.Вставить("Состояние",     СостояниеФоновогоЗадания.Активно);  
            мФоновыеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
            Если мФоновыеЗадания.Количество() > 0 Тогда         
                Для каждого тФоновоеЗадание Из мФоновыеЗадания Цикл
                        тФоновоеЗадание.Отменить();      
                КонецЦикла;
            КонецЕсли;
            //-----------------------------------------------------------------
            МассивЗаданий.Очистить();
        КонецЕсли;
3 zladenuw
 
21.02.14
14:12
(2) ну на фига его в потоки ?
4 zladenuw
 
21.02.14
14:13
(2) еще раз смотришь как реализовано тут
http://infostart.ru/public/182139/
5 fisher
 
21.02.14
14:18
ИМХО, контролировать стек заданий через "гроханье" - изначально не лучшая идея.
6 ДенисЧ
 
21.02.14
14:18
Не делай отменить(), выставляй флаг завершения, в задании его проверяй и закругляйся.
7 adelaide
 
21.02.14
14:23
(5) может и так, но оно у меня все равно будет запускать новые фоновые пока все не переварит...
(3) чтоб быстрей было
(6) не понял, как? приведи пример кода, у фонового задание есть свойство состояние но оно вроде только на чтение.
8 adelaide
 
21.02.14
14:29
(4) вот как раз по тому примеру и делал, и после его отработки у меня скапливается много незавершенных фоновых заданий которые валят сервер, потому как этот кусок кода:
9 Torquader
 
21.02.14
14:29
Только мне одному кажется, что из-за "столкновения" транзакций задание может "повиснуть" на ожидании захвата блокировки объекта, то есть на обращении к SQL-серверу.
В этом состоянии корректно его грохнуть не получится, так как транзакция отвалится, когда сервер ей позволит.
В итоге, вы просто "загаживаете" буфер транзакций - оно вам надо ?
10 adelaide
 
21.02.14
14:29
Если МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
            Попытка
                ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);
            Исключение
            КонецПопытки;
            МассивЗаданий.Очистить();
        КонецЕсли;
11 adelaide
 
21.02.14
14:30
короче кусок кода из (10) он не завершает задания, он только ожидает их завершения, а если одно задание фейнулось он просто очистит массив и запустит новый пакет фоновых заданий.
12 adelaide
 
21.02.14
14:32
(9) не в моем случае, у меня фоновые задания работают только с временным хранилищем, объекты СУБД не блокируются.
13 Torquader
 
21.02.14
14:52
(12) А нафига они тебе вообще тогда - клади данные в файл и запускай процессы на php - там их душить не передушить, что хочешь, то с ними и делай.
14 adelaide
 
21.02.14
14:56
(13) в конечном итоге хотелось бы решить задачу средствами 1С, оно конечно на php проще и ресурсов меньше будет жрать, но это еще php нужен...
15 Torquader
 
21.02.14
15:00
(14) Просто, если процессы не обращаются к самой базе, то зачем они такие вообще нужны ?
16 Dolphinbet
 
21.02.14
15:06
парсить цены конкурентов - all-sku.ru
17 Torquader
 
21.02.14
15:10
(16) Если что-то парсить, то тогда точно php
18 Dolphinbet
 
21.02.14
15:10
nodeJS лучше)
19 hhhh
 
21.02.14
15:14
(14) но можно же одним заданием, зачем 200 заданий запускать?
20 Dolphinbet
 
21.02.14
15:15
(19) по всей видимости для параллельного получения данных страниц с ценами
21 hhhh
 
21.02.14
15:19
(20) цены же у конкурентов не каждый день меняются. Может раз в полгода.
22 Dolphinbet
 
21.02.14
15:20
бывает и несколько раз в день, например на смартфоны)
23 Torquader
 
21.02.14
15:24
Ну, если все конкуренты друг у друга цены мониторят, то да - всё меняется очень и очень динамично.
24 Asmody
 
21.02.14
15:25
(19) может у него сервант о двухсот головах?
25 Torquader
 
21.02.14
15:28
(24) Проще 200 голов по сети собрать - тем более, для парсинга - самое оно.
26 MM
 
21.02.14
15:30
Запуск и остановка задания самая затратная по ресурсам штука, не правильнее ли реализовать, что-то вроде пула фоновых заданий. Или есть серьёзный риск, что они повиснут на сетевых операциях?
27 Torquader
 
21.02.14
15:31
Мне кажется, что это всё вообще можно на отдельную машину вынести, чтобы в 1С попадал только готовый результат.
28 adelaide
 
21.02.14
16:22
(21) ню-ню, у нас в Украине цены каждый час меняются =)
29 adelaide
 
21.02.14
16:27
(26) хм, возможно ты и прав, попробую, но это не отменяет проблемы корректного завершения фоновых заданий.
(24) (25) Не, вполне хватает обычного i7
30 Kalambur
 
21.02.14
16:30
(28) да майдан пройдет и хотелка тоже потеряет смысл..
31 adelaide
 
21.02.14
16:34
(30) не хотелка появилась задолго до майдана и уже больше чем пол года как фунциклирует :-Р.
32 adelaide
 
24.02.14
19:24
апну тему, платформа не завершает нормально фоновые задания, они остаются висеть в консоли, хотя из консоли их удается завершить.
33 adelaide
 
24.02.14
19:24
кто сталкивался и что делать?
34 Torquader
 
24.02.14
19:29
(33) Нужно смотреть, что там с ним произошло и в какой стадии оно находится.
35 Torquader
 
24.02.14
19:30
Потом, если вы лезете в сеть, то можно ожидать, что пока получение данных не окончено, соединение корректно не будет закрыто.
А если в задания вставлять проверку наличия файлов и т.п., чтобы определить момент, когда его нужно максимально быстро завершить.
36 adelaide
 
24.02.14
19:34
(35) >если вы лезете в сеть, то можно ожидать, что пока получение данных не окончено, соединение корректно не будет закрыто.
Я выставляю таймаут для соединений.

>А если в задания вставлять проверку наличия файлов и т.п., чтобы определить момент, когда его нужно максимально быстро завершить.
Что имелось ввиду?
37 adelaide
 
24.02.14
19:35
(34) а они могут висеть в другом состоянии кроме "Активно"?
38 adelaide
 
24.02.14
19:36
блин 1С стоит подумать о новом состоянии для фоновых - "Зависло"
39 Torquader
 
24.02.14
19:36
(36) Просто, если задание выполняет какое-то действие, то в нём нужно периодически проверять состояние какого-то флага, чтобы если он установлен - сразу его завершить.

Кстати, по опросу в сеть - сколько максимально можно держать соединений в состоянии "установка" в XP, насколько я помню, было 10 - просто - остальные висят и не обращаются в сеть, пока им не дадут на это право - при этом, таймаут не считается, так как он начнёт считаться только с того момента, когда пакет пойдёт в сеть.
40 Torquader
 
24.02.14
19:37
(38) Нормальное задание не может зависнуть - если, конечно вы их "валите", то есть вероятность подвесить tcp-стек, но тогда у вас уже не только задания, а и вообще всё взаимодействие будет висеть.
41 adelaide
 
24.02.14
19:44
(39)
с флагом конечно вариант, но не думаю что изнутри оно лучше отработает чем снаружи, так как я после таймаута данного на выполнение фоновых заданий прохожусь по массиву этих заданий и грохаю их:

Задание = ФоновыеЗадания.Выполнить("Многопоточность.МП_ПолучениеПредложений", МассивПараметров, Ключ, "ПолучениеПредложений");    
        КонецЕсли;
        
        МассивЗаданий.Добавить(Задание);         
        
        Если МассивЗаданий.Количество() >= ЧислоПараллельныхПотоков Тогда
            Попытка
                ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий, 25);
            Исключение
                //что-то пошло не так, даем 25 сек. завершится заданиям:
                глПауза(10);
            КонецПопытки;
            //-----------------------------------------------------------------
            //все что не успело завершится завершаем принудительно:
            //-----------------------------------------------------------------
            Отбор = Новый Структура;
            Отбор.Вставить("Наименование",     "ПолучениеПредложений");
            мФоновыеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
            Если мФоновыеЗадания.Количество() > 0 Тогда         
                Для каждого тФоновоеЗадание Из мФоновыеЗадания Цикл
                        тФоновоеЗадание.Отменить();      
                КонецЦикла;
            КонецЕсли;
            //-----------------------------------------------------------------
            МассивЗаданий.Очистить();
        КонецЕсли;



у меня виндовс сервер 2008, там вроде таких ограничений нет.
42 Torquader
 
24.02.14
19:57
(41)  А ты уверен, что интернет-канал таких ограничений не имеет.
Потом, я бы как-то научился общаться с заданиями, чтобы знать, в каком оно состоянии находится, а не только - вам дано время или сделай или сдохни.
AdBlock убивает бесплатный контент. 1Сергей