Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Длительный расчет в CSP / 18 сообщений из 18, страница 1 из 1
03.03.2010, 23:36
    #36501186
gr_vl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
Приветствую

Есть приложение которое несколько минут формирует данные, подскажите как лучше запускать и выводить потом сформированные данные на страницу csp.

Где-то на форуме это обсуждалось , но вот не смог найти.
...
Рейтинг: 0 / 0
04.03.2010, 02:17
    #36501262
kolesov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
gr_vl,
http://localhost/csp/docbook/DocBook.UI.Page.cls?KEY=GZAP_page_really_programming#GZAP_C137584Background Tasks on the Server
There is a mechanism for starting a background job from a Zen page and tracking its progress within the page. This can be useful for cases where a page needs to initiate a long-running task and wants to provide some degree of feedback to the client while waiting for that task to complete.
A Zen page class has a backgroundTimerInterval property. This is the interval, in milliseconds, at which timer events are fired to check on the status of background tasks started by this page. The default is 1000.
Two methods support background tasks; both are available in any class that inherits from %ZEN.Component.page:
%RunBackgroundMethod starts a background job to run a class method of this Zen page. %RunBackgroundMethod returns a %Status value and may have one or more arguments:
The first argument, a %String, is the name of the class method to run.
Depending on the method signature, a variable number of arguments may follow; these are the arguments of the method named in the first argument.
Zen monitors only one background task at a time. If %RunBackgroundMethod is called while a previous background task is running, the new method becomes the current monitored task. The previous task runs to completion, but the client is not notified about it.
%SetBackgroundMethodStatus can be called from within a method that is running in the background, to update its own status information. %SetBackgroundMethodStatus has no return value and takes two arguments:
A %String specifies the status message that will be seen by the client page. The string may be empty.
An optional %Float value indicates how much of the background task is complete (as a percentage between 0 and 100). A client page can use this information to display progress to the user.
...
Рейтинг: 0 / 0
04.03.2010, 09:03
    #36501391
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
gr_vlкак лучше запускать
Джобом. И возвращать управление странице...

gr_vlвыводить потом сформированные данные на страницу csp.
Как вариант...
- Джоб пишет куда-то данные о прогрессе анализа данных
- Страница с неким таймаутом выводит этот прогресс у себя на странице
- По окончании всего показываются итоговые данные
...
Рейтинг: 0 / 0
04.03.2010, 09:22
    #36501421
gr_vl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
а если задача снялась по ошибке?
какой то максимальный таймаут и пользователь не знает о том что программа не отработала?
Кто нибудь делал с запуском в фоновом процесе и обработкой ошибок?
...
Рейтинг: 0 / 0
04.03.2010, 09:27
    #36501427
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
gr_vlа если задача снялась по ошибке?
Таки пусть джоб сам про это и напишет куда-то... Принимающая страница все обработает как надо...

gr_vlКто нибудь делал с запуском в фоновом процесе и обработкой ошибок?
У нас например так работает давно... Вот например вариант с новым синтаксисом

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
CopyBD(dirto) ; копирование файла БД с удаленного сервера в dirto
 n serv,port,login,ns,rc,res,pass,err
 s err= 1 
 try{
     ;s par=##class(adm.Nast).%OpenId("REGAUTO")
     s serv=par.Get("adrsrc")
     s port=par.Get("portsrc")
     s login=par.Get("logsrc")
     i login="" s login="_SYSTEM"
     s pass=par.Get("parsrc")
     i pass="" s pas="SYS"
     s bd=par.Get("bdsrc")
     s bddir=par.Get("bddir")
     s rc=##class(%Net.RemoteConnection).%New()
     s res=rc.Connect(serv,"%SYS",port,login,pass)
     i '+res D LOG("Ошибка подключения к удаленному Cache") q
     S res=rc.OpenObjectId("SYS.Database",bd,.per)
     i '+res!(per="") {
         D LOG("Ошибка подключения к удаленной БД")
         d LOG($System.Status.GetErrorText(res))
         q
     }   
     D LOG("Подключился к удаленному серверу")
     s res=rc.InvokeInstanceMethod(per,"Dismount")
     h  5 
     s lck=##class(%File).Exists(bddir_"\"_"cache.lck")
     i '+res!(lck) { 
        D LOG("Ошибка отмонтирования удаленнной БД")  
        d LOG($System.Status.GetErrorText(res))
        q
     }   
     D LOG("Удаленная БД отмонтирована")
     s res=$$Dismount(dirto)
     i '+res D LOG("Ошибка отмонтирования локальной БД") q
     D LOG("Локальная БД отмонтирована") 
     
     s res=##class(%File).Exists(dirto_"\"_"cache.dat")
     i res {
        D LOG("Удаление локальной БД")
        s res=##class(%File).Delete(dirto_"\"_"cache.dat")
        i '+res D LOG("Ошибка удаления локальной БД") q
     }
     D LOG("Копирование удаленной БД")
     s res=##class(%File).CopyFile(bddir_"\"_"cache.dat",dirto_"\"_"cache.dat") 
     i '+res D LOG("Ошибка копирования удаленнной БД") q
     D LOG("Выполнено копирование удаленной БД")
     
     s res=rc.InvokeInstanceMethod(per,"Mount")
     i '+res D LOG("Ошибка монтирования удаленнной БД") q
     D LOG("Выполнено монтирование удаленной БД")
     s res=$$Mount(dirto)
     i '+res D LOG("Ошибка монтирования локальной БД") q
     D LOG("Выполнено монтирование локальной БД")
     s err= 0 
 }
 catch
 {
    D ERROR 
 }
 i err d LOG($System.Status.GetErrorText(res))
 q 'err

Вот

Код: plaintext
    D ERROR 

как раз и пишет принимающей странице сообщение об ошибке...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
ERROR ; Обработка ошибок
 n log,gl,error,stream
 s log=$NA(^reg("AutoLog"))
 i $G(portal) s log=$NA(^reg("AutoLogPrt"))
 D LOG("Обнаружены ошибки в программе, процесс не выполнен")
 D LOG("Стек сохранен в журнал ошибок приложений")
 D ^AERPROC
 s gl=$NA(^UTILITY("%ER",+$H,^UTILITY("%ER",+$H, 0 )))
 k ^TmpErrREG
 m ^TmpErrREG=@gl
 s error=$ZU( 12 ,"")_"error.xml"
 d $system.OBJ.Export("^TmpErrREG.GBL",error,"-d")
 D SENDMAIL 
 s par=##class(adm.Nast).%OpenId("REGAUTO")
 d par.Set("job","")
 d par.%Save()
 k par 
 l -@log
 Q 
...
Рейтинг: 0 / 0
04.03.2010, 09:43
    #36501455
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
если JOB вывалится с ошибкой конечно есть try catch на это или если по старому $ZTrap
хотя может конечно случится когда процесс может упасть не успев обработать ошибку, например процесс убили вручную, или произошла критическая ошибка в коде самой Cache, и процесс падает сам, тогда можно параллельно мониторить, жив ли процесс например так $d(^$J(JOB интересующего процесса))
_________________________________
Cache for Windows NT (AMD64) 5.0.21 (Build 6408) Tue Jan 3 2006 13:37:41 EST
...
Рейтинг: 0 / 0
04.03.2010, 09:49
    #36501462
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
DAiMorмониторить, жив ли процесс например так $d(^$J(JOB интересующего процесса))
Либо пусть джоб блокирует какой-то глобал... А принимающая страница пусть проверяет состояние блокировки этого глобала...
...
Рейтинг: 0 / 0
04.03.2010, 09:55
    #36501472
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
ну блокировки это разумеется, как например в моем коды который ты привел, там ставится блокировка на глобал с логами
но осуществлять контроль по блокировкам удобен, когда в один момент может существовать только один процесс занятый этой операцией, а вот когда нужно к примеру сформировать отчет, такой контроль не подойдет
_________________________________
Cache for Windows NT (AMD64) 5.0.21 (Build 6408) Tue Jan 3 2006 13:37:41 EST
...
Рейтинг: 0 / 0
04.03.2010, 10:32
    #36501593
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
DAiMorа вот когда нужно к примеру сформировать отчет, такой контроль не подойдет
Все там подойдет... Только блокировать нужно будет не "весь" глобал, а некие узлы в глобале. Например по логинам пользователей...
...
Рейтинг: 0 / 0
04.03.2010, 10:55
    #36501684
servit
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
gr_vl,

Возможно, Вы это искали:Timeout для отдельной csp-страницы ?
...
Рейтинг: 0 / 0
04.03.2010, 12:46
    #36502126
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
krvsaDAiMorмониторить, жив ли процесс например так $d(^$J(JOB интересующего процесса))
Либо пусть джоб блокирует какой-то глобал... А принимающая страница пусть проверяет состояние блокировки этого глобала...
USER>w $zv
Cache for Windows NT (Intel/P4) 5.0.15

Процесс ставит лок
l +a($j)
в панели управления появляется блокировка.
Иду в таск менеджер, убиваю процесс с этим $j.
В панели управления блокировка осталась.

USER>w $zv
Cache for Windows (x86-32) 2009.1

Поведение то же самое.

Если процесс ушел, то его $j может быть выдан одному из следующих.

Или я что-то неправильно понимаю?
...
Рейтинг: 0 / 0
04.03.2010, 13:00
    #36502192
DAiMor
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
если процесс умер, должна пропасть и блокировка
но вы проверяете это на не очень хорошей версии Cache, может быть там с этим проблемы

я проверил сейчас на
Cache for UNIX (Linux Intel/32-bit) 5.0.20 (Build 6305) Fri Sep 16 2005 12:47:21 EDT
и у меня блокировки пропадают вместе с процессом

за номер JOB отвечает операционка, и она не даст процессу появившемуся в след за умершим, тот же номер, номер будет увеличиваться

если проверять существование процесса раз в несколько минут, то этого будет достаточно чтобы быть уверенным что, будет проверятся действительно один и тот же процесс

для дополнительной проверки, можно чтобы тот процесс сообщал PID процесса родителя ($ZP)
_________________________________
Cache for Windows NT (AMD64) 5.0.21 (Build 6408) Tue Jan 3 2006 13:37:41 EST
...
Рейтинг: 0 / 0
04.03.2010, 13:02
    #36502194
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
ну яИли я что-то неправильно понимаю?
Не знаю... Но у нас много какие задачи работают на принципе блокировки... В том числе и формирование статотчетности...
Правда блокируем не локальные, а глобальные переменные...

Вот потестил у себя...

...
Рейтинг: 0 / 0
04.03.2010, 13:07
    #36502213
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
Проверил и с нальтом...




----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
04.03.2010, 13:10
    #36502226
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP

----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
04.03.2010, 13:20
    #36502260
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
Есть даже вариант с неким "управление" процессами...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
<html>
<!--Кривошеев С.А.-->
<title>Управление процессом</title>
<head>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="TEXT/HTML; CHARSET=WINDOWS-1251">
<link rel="stylesheet" type="text/css" href="/css/standart.css">
<script language="javascript">
// Изменение статуса процесса генерации программ
function Action(id) 
{
   var obj=document.fdocjob.raction
   var typ
   var i= 0 
   while (!obj[i].checked) {i++}
   typ=obj[i].value
   #server(..cAction(id,typ))#
}
</script>

<script language="cache" method="cAction" arguments="Id:%String,Type:%String">  
  n buf,job
  s buf=$na(^CacheTemp("Doc",Id))
  s job=$g(@buf@("Job"))
  if Type="break" {
    k @buf
    &javascript<window.navigate("docinfo.csp")>
    q
  }
  if Type="Тест" {
    s Type=Type_" ("_$$Date^zfunc()_" в "_$$Time^zfunc()_")"
  }
  if Type="Продолжить" {
    s Type="Активен"
    d $zu( 143 ,job, 0 )
  }
  s @buf@("Status")=Type
  if Type="Пауза",job'="" {d $zu(143,job,1)}
  &javascript<window.navigate("docjob.csp?id=> w Id &javascript<")>
</script>

</head>
<body>
<form name='fdocjob'>
<table width=' 100 %' border=0>
<tr>
<th align='left' valign='top' width=' 90 %'>Управление процессом
<th align='left' valign='top' rowspan=2>
  <!--Таблица кнопок-->
  <table>
  <tr>
  <td><input type='button' value='Выход' onclick='window.navigate("docinfo.csp")'>
  <tr>
  <td><input type='button' value='Обновить' onclick='window.navigate("docjob.csp?id=#(%request.Data("id",1))#")'>
  </table>
<tr>
<td> 

<script language="cache" runat='server'>
  n buf,id,typ
  s id=%request.Data("id",1)
  s buf=$na(^CacheTemp("Doc",id))
  s typ=$g(@buf@("Status"))
  &html<<input type='hidden' name='ttype' value=1>>
  &html<<fieldset>>
  &html<<legend>Информация о процессе</legend>>
    &html<<table border=0>>
    &html<<tr>>
    &html<<td>Номер>
    &html<<td>>
      w "<input type='text' value='",$g(@buf@("Job")),"' readonly>"
    &html<<tr>>
    &html<<td>Информация>
    &html<<td>>
      w "<input type='text' value='",$g(@buf@("Info")),"' size=60 readonly>"
    &html<<tr>>
    &html<<td>Статус>
    &html<<td>>
      w "<input type='text' value='",typ,"' size=60 readonly>"
    &html<</table>>  
    &html<</fieldset>>
    &html<<fieldset>>
      &html<<legend>Действия</legend>>
      &html<<table border=0>>
      if typ["Активен" {
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Тест' checked>>
        &html<<td>Тестирование>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Пауза'>>
        &html<<td>Пауза>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Остановлен'>>
        &html<<td>Остановить>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='break'>>
        &html<<td>Прервать>
      } elseif typ="Пауза" {
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Продолжить' checked>>
        &html<<td>Продолжить>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Остановлен'>>
        &html<<td>Остановить>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='break'>>
        &html<<td>Прервать>
      } else {
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='Тест' checked>>
        &html<<td>Тестирование>
        &html<<tr>>
        &html<<td><input type='radio' name='raction' value='break'>>
        &html<<td>Прервать>
      }
        &html<<tr>>
        &html<<td colspan=2><input type='button' name='brun' value='Выполнить' onclick='Action(#(%request.Data("id", 1 ))#)'>>
      &html<</table>>  
    &html<</fieldset>>
</script>

</table>
</form>
</body>
</html>
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
04.03.2010, 13:24
    #36502268
krvsa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
И в самом джобе

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
BEGINFO ; Начальная информация
 n var
 s var=$$Date^zfunc()
 s var=var_" в "_$$Time^zfunc()
 s @buf@("Start")=var
 s @buf@("Job")=$j
 s @buf@("Sttus")="Активен"
 q
STATUS ; Обработка статуса
 s:$g(@buf@("Status"),"Остановлен")="Остановлен" exit= 2 
 s:$g(@buf@("Status"))["Тест" @buf@("Status")="Активен ("_$$Date^zfunc()_" в "_$$Time^zfunc_")"
 k:exit= 2  @buf
 q
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
04.03.2010, 14:14
    #36502425
Alexey Maslov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Длительный расчет в CSP
DAiMorно вы проверяете это на не очень хорошей версии CacheМеханизм очистки таблицы процессов Cache от умерших (в ОС - "не своей смертью") процессов нормально заработал, если не ошибаюсь, начиная с 5.0.20. Другое дело, что имеет место задержка - от 10 минут до 1 часа (точнее не скажу, но не 10 секунд :). В Linux, возможно, очистка проходит быстрее. Желающие поэкспериментировать: запустите процесс в терминале, сделайте Lock +aaaaaa, откройте таблицу блокировок в Портале и убейте процесс (не крестиком, а в Диспетчере задач Windows / "kill -9 pid" в Linux). Блокировка в таблице на какое-то время останется.
...
Рейтинг: 0 / 0
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Длительный расчет в CSP / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]