Какая То Фигня С Шедульным Агентом

Eugen

Well-known member
22.03.2012
177
0
#1
Всем здрасьте.

Проблема следующая:
Есть база. На postopen висит вот такой код:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">код</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub Postopen(Source As Notesuidatabase)
Set lastLog=source.Database.getDocumentByUNID("UNID дока")

Dim s As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent
Dim todayDate As NotesDateTime
Dim lastUDate As NotesDateTime
Dim shift5sec As NotesDateTime

Set db=s.CurrentDatabase
Set agent=db.GetAgent("Repeat")
Set todayDate = New NotesDateTime( Now )
Set lastUDate = New NotesDateTime( lastLog.lastUpdate(0))
If todayDate.TimeDifference( lastUDate ) > 86400 Then
Call agent.Run
Set shift5sec = New NotesDateTime(Now)
Do While shift5sec.TimeDifference( todayDate ) < 5
Set shift5sec = New NotesDateTime(Now)			
Loop
Set lastLog=source.Database.getDocumentByUNID("UNID дока")
Set lastUDate = New NotesDateTime( lastLog.lastUpdate(0))
If todayDate.TimeDifference( lastUDate ) < 86400 Then
MsgBox "Всё хорошо."
Else
MsgBox "Всё плохо! Обратитесь к администратору системы."
End If	
Else
MsgBox "Всё хорошо."
End If
End Sub

Есть агент (Repeat), который запускается каждый день в 23:00 и если он отработал хорошо, но он пишет об этом в документ lasdLog. Кстати в логе сервера никакой критики насчет запуска агента нет... но так или иначе он почему то не модифицирует этот док lastLog.
Поэтому при открытии базы замутили проверку времени, когда он был последний раз модифицирован. Если более 24 часов назад, то идет принудительный запуск агента, после чего повторная проверка поля lastUpdate. В таком варианте агент норм запускается и изменяет документ, но даже при переопределении дока и поля с датой, вылазит сообщение, что все плохо. Потом быза открывается, я обновляю вью и там в доке вижу, что док все таки обновился. Что делаю не так?
 

savl

Lotus team
28.10.2011
2 135
104
#2
Принтуйте, смотрите результаты
Код:
		Set lastLog=source.Database.getDocumentByUNID("UNID дока")
Set lastUDate = New NotesDateTime( lastLog.lastUpdate(0))
Print "Today:" & todayDate.DateOnly & " LastUpdate: " & lastUDate.dateonly
If todayDate.TimeDifference( lastUDate ) < 86400 Then
MsgBox "Всё хорошо."
Else
MsgBox "Всё плохо! Обратитесь к администратору системы."
End If
Еще бы заменил:
Код:
Set todayDate = New NotesDateTime( Now )
на
Код:
Set todayDate = New NotesDateTime( Today )
Чтобы время не брать в расчет
 

Eugen

Well-known member
22.03.2012
177
0
#3
<!--QuoteBegin-savl+-->
<table border="0" cellpadding="0" cellspacing="0" align="center" width="98%"> [tr] <td class="vbquote"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> [tr] <td class="vbquote" width="75" valign="bottom"> <table border="0" cellpadding="0" cellspacing="0" width="50px"> [tr] <td class="vbquote" width="28" valign="top">
</td> <td class="vbquote" width="100%" style="background-image: url('style_images/ckr/quotes/quote-bg.gif'); background-position: center;" valign="middle"><span class="vbquote">Цитата:</span></td> <td class="vbquote" valign="top">
</td> [/tr] </table> </td> <td class="vbquote" align="left" style="background-image: url('style_images/ckr/quotes/quot-lr-bg.gif')" valign="bottom"></td><td class="vbquote" width="0" align="left" valign="bottom"> <table border="0" cellpadding="0" cellspacing="0" width="200"> [tr] <td class="vbquote" valign="top">
</td> <td class="vbquote" width="100%" style="background-image: url('style_images/ckr/quotes/quot-bye-bg.gif')" align="left" valign="middle" nowrap="nowrap"><span class="vbquote">(savl)</span></td> <td class="vbquote" valign="top">
</td> [/tr] </table> </td><td class="vbquote" width="100%" align="right" valign="bottom"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> [tr] <td class="vbquote" width="100%"> <table border="0" cellpadding="0" cellspacing="0" width="100%"> [tr] <td class="vbquote" style="background-image: url('style_images/ckr/quotes/quot-top-bg.gif')" width="100%" valign="middle"></td> <td class="vbquote" align="left" valign="top">
</td> [/tr] </table> </td> [/tr] </table> </td> [/tr] </table> <table border="0" cellpadding="0" cellspacing="0" width="100%"> [tr] <td class="vbquote" width="10" style="background-image: url('style_images/ckr/quotes/quoting-left.gif')"></td> <td class="vbquotemain" width="100%" valign="top"></td> <td class="vbquote" width="10" style="background-image: url('style_images/ckr/quotes/quoting-right.gif')"></td> [/tr] [tr] <td class="vbquote" width="10" style="background-image: url('style_images/ckr/quotes/quot-left-bg.gif')"></td> <td class="vbquotemain" width="100%" valign="top"><!--QuoteEBegin-->Еще бы заменил:Set todayDate = New NotesDateTime( Now )на Set todayDate = New NotesDateTime( Today )Чтобы время не брать в расчет<!--QuoteEnd--></td> [/tr] [tr] [/tr] </table> </td> [/tr] </table>
<!--QuoteEEnd-->

А если время не брать, как он тогда разницу времени посчитает?
И почему может не запускаться агент?
 

savl

Lotus team
28.10.2011
2 135
104
#4
если он запускается каждый день в 23:00, то открыв базу утром в 7 часов он его не запустит, 24 часа не прошли.
Значит более суток надо ждать в любом случае, там уже минуты и часы не важны сильно. Разница в датах даст 24 часа.
 

savl

Lotus team
28.10.2011
2 135
104
#5
А вот если по расписанию не запускается, то прорвете права на запуск агента на сервере, подпишите сервером.
Проверте документ сервера на предмет странностей.
 

Eugen

Well-known member
22.03.2012
177
0
#6
Я неправильно написал. В логе сервера видно, что он запускается, но он не изменяет нужный док. При открытии базы получается, что агент отработал, но при повторной проверке он идет в то условие, что все плохо. Т.е. он не видит, что док уже обновился.

Пытаюсь сделать так
Код:
If todayDate.TimeDifference( lastUDate.Dateonly ) > 24 Then
, говорит type mismatch. Где туплю?
 

savl

Lotus team
28.10.2011
2 135
104
#7
ненене, Дэвид Блейн...

Все было верно, а вот это правильно:
Код:
If todayDate.TimeDifference( lastUDate ) < 86400 then
разница возвращается в секундах, поэтому сравнивать надо именно с 86400.
24 это же секунды будут )
 

hosm

* so what *
18.05.2009
2 442
6
#8
lastUDate.Dateonly Data type String
возьмите установите SetAnyTime
 

savl

Lotus team
28.10.2011
2 135
104
#9
В логе сервера видно, что он запускается, но он не изменяет нужный док. При открытии базы получается, что агент отработал, но при повторной проверке он идет в то условие, что все плохо. Т.е. он не видит, что док уже обновился.
Код агента можно глянуть?
Возможно он обходит момент изменения по условиям, либо пропускает save.
Про док на событии базы, надо просто принтами посмотреть что происходит
 

hosm

* so what *
18.05.2009
2 442
6
#10
вы агент в постопене запускаете на клиенте, тут надо смотреть локальный лог. А при запусках по расписанию - возможно, он вообще не стартует по расписанию из-за чего-то (неправильной настройки или уи-классов, например) или вываливается с ошибкой еще до момента сохранения. Добавьте в самое начало агента, до и после сохранения дока тестовые сообщения.
 

Eugen

Well-known member
22.03.2012
177
0
#11
Код агента:
Код:
Option Public
Option Declare
Use "Repeating"

Dim coll As NotesDocumentCollection
Dim copy As Variant

Sub Initialize
Dim task As New task
Set coll=task.GetAllTodayTasks
Call task.Repeat(coll)
End Sub
Коды вызываемых процедур функций:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Function GetAllTodayTasks</div></div><div class="sp-body"><div class="sp-content">
Код:
Function GetAllTodayTasks As NotesDocumentCollection
Dim s As New NotesSession

Set v=s.Currentdatabase.Getview("TasksByDate")
Set GetAllTodayTasks=v.Getalldocumentsbykey(Today, True)

End Function
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Sub Repeat</div></div><div class="sp-body"><div class="sp-content">
Код:
Sub Repeat(Tasks As NotesDocumentCollection)
Dim w As New NotesUIWorkspace
Dim s As New NotesSession

Dim TaskDate As New NotesDateTime (Today)

'Если сегодня СБ или ВС, ничего не делать
'Это - доп. проверка. Агент будет запускаться только в будни (по расписанию)
If Weekday(TaskDate.Dateonly)=7 Or Weekday(TaskDate.Dateonly)=1 Then
Exit Sub
End If



Set doc=Tasks.Getfirstdocument()

While Not doc Is Nothing

Set NextDayTask=s.CurrentDatabase.Createdocument()
Call doc.Copyallitems(NextDayTask, True)

'Работаем с периодичностью ДЛЯ КАЖДОЙ ЗАДАЧИ ОТДЕЛЬНО
Select Case doc.Period(0)
Case "Ежедневно"	
'Если сегодня ПТ, то создать задачу на ПН
If Weekday(TaskDate.Dateonly)=6 Then 
NumberOfDays=3
Else
NumberOfDays=1
End If
Call TaskDate.Adjustday(NumberOfDays)
Case "В текущий день месяца"
Call TaskDate.AdjustMonth(1)
'Если попадает на выходной, то перенести вперед 
Select Case (TaskDate.Dateonly)
Case 7 'СБ
Call TaskDate.Adjustday(2)
Case 1 'ВС
Call TaskDate.Adjustday(1)
End Select
Case "В текущий день недели"
Call TaskDate.Adjustday(7)
End select



Set Item=NextDayTask.ReplaceItemValue("StartDate",TaskDate)
NextDayTask.Done=""
NextDayTask.DoneBy=""

Call NextDayTask.Save(True, False,)

Set doc=Tasks.Getnextdocument(doc)
Wend

'Перед самым завершением процедуры зафиксируем дату текущего (каждый раз последнего) запуска копирования
Set logDoc=s.Currentdatabase.Getdocumentbyunid("AD9C2C47AB081FE044257B2E00297213")
logDoc.lastUpdate=Now
Call logDoc.Save(true, false,)
End Sub
 

Мыш

Премиум
12.02.2008
1 097
10
#12
Вы на самом деле UNID документа захардкодили? Это совсем нехорошо. Во-вторых, надо обрабатывать ошибку его ненахождения при вызове Getdocumentbyunid. Хотя.. ошибок работы агента, я так понимаю в консоли не видно?
 

Мыш

Премиум
12.02.2008
1 097
10
#15
Видимо на автомате... она не используется.
Убрать немедленно! :)
И еще. У Вас вид TasksByDate, я так понимаю, содержит столбец с функцией типа @Today? С такими видами бывают нюансы, впрочем, к данной проблеме не относящиеся...
 

savl

Lotus team
28.10.2011
2 135
104
#16
Код:
Select Case (TaskDate.Dateonly)
Case 7 'СБ
Call TaskDate.Adjustday(2)
Case 1 'ВС
Call TaskDate.Adjustday(1)
End Select
Думаю тут weekDay не хватает...
и меняем сейв на это:
Код:
		Call logDoc.ReplaceItemValue("lastUpdate",Now)
Print "Сохранение LogDoc: " & Now
Call logDoc.Save(true, false)
Больше добавить к озвученному нечего, хотя там много что можно переписать, хех...

Так что наблюдаем и ловим.
 

erdi

Well-known member
20.08.2008
265
17
#17
1) можно попробовать агенту выставить security=3
2) может быть сервер неправильно дату берет, нежели на клиенте
я последнее время дату перевожу в Double( CDbl(theDateV) )делаю все сравнения(сложения, вычитания) и потом обратно в дату ( theDateV = CDat(34633) ) при этом дата до точки, а время после точки
3) обычно стараюсь не модифицировать 1 документ, а создавать новый и потом брать 1-й во вьюшке...правда нужен агент-мусорщик
 

Eugen

Well-known member
22.03.2012
177
0
#18
1) можно попробовать агенту выставить security=3
2) может быть сервер неправильно дату берет, нежели на клиенте
я последнее время дату перевожу в Double( CDbl(theDateV) )делаю все сравнения(сложения, вычитания) и потом обратно в дату ( theDateV = CDat(34633) ) при этом дата до точки, а время после точки
3) обычно стараюсь не модифицировать 1 документ, а создавать новый и потом брать 1-й во вьюшке...правда нужен агент-мусорщик
1)сейчас стоит security=2, но пробовал со всеми вариантами;
2)сервер в лог пишет правильное значение даты-времени. Чуть позже попробую с конвертированием;
3)этот вариант наверно тоже попробую
 

Eugen

Well-known member
22.03.2012
177
0
#19
Агент стал запускаться нормально, но вот если возникнет ситуация, что он не отработал, проблема остается. Агент отрабатывает, но при повторной проверке он идет в то условие, что все плохо. Т.е. он не видит, что док уже обновился. По принтам все ок.
 

savl

Lotus team
28.10.2011
2 135
104
#20
Возможно таблица базы не обновилась, внутренний индекс TableID.
Как это точно и когда происходит мне неизвестно, можно попробовать так:
Код:
sleep(2) ' Зависаем на 2 секунды
Set lastLog=source.Database.getDocumentByUNID("UNID дока")
Set lastUDate = New NotesDateTime( lastLog.lastUpdate(0))
Print "Today:" & todayDate.DateOnly & " LastUpdate: " & lastUDate.dateonly
If todayDate.TimeDifference( lastUDate ) < 86400 Then
MsgBox "Всё хорошо."
Else
MsgBox "Всё плохо! Обратитесь к администратору системы."
End If
Есть еще подозрение, что пока база не откроется, то ее внутренний индекс не обновиться.
Есть вариант получать документ не через базу, а через вьюху.
Сделать представление byUNID и тянуть документ оттуда, через notesView.GetDocumentByKey( keyArray [, exactMatch% ] )

Добавлено: Хотя странно, раз даты верные, значит он обновился.
Сохраните "todayDate.TimeDifference( lastUDate )" в перменную и выведите ее значение через Print посмотрите что там получилось.