Agent и параметры его

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
эти все пляски-с-бубнами порядком поднадоели, но звук высоких технологий доходит очень медленно (в вязкой среде) :), я про DOTS
а потому - агент
передать документ - не проблема, а вот коллекцию - уже вызывает задумчивость...
c у Андрея не срослось (да и виндядко - не сильно веселая тема)
дергать сильно замороченная тема, да и ЛС там никак
возникла мысль, тривиальная, передавать список unid
оформил в классы докрутил zip/unzip
если будет интересно - выложу, в данный момент могу только кусками, в отдельную БД оформить не было времени
Код:
%REM
*********************************************
Agent test\NDCFile
Created Mar 30, 2015
Description: Comments for Agent
%END REM
Option Public
Option Declare
Use "Files.LS2J"
Sub Initialize
On Error GoTo ErrH
Dim NDCfile As New NDCFile, path As String
Dim NDC As NotesDocumentCollection
Set NDC=SelectedDocsUI
Set NDCfile.Collection(Path)=NDC
NDCfile.Add(path)
NDCfile.Compress(path &{.zip})
NDCfile.Decompress(path &{.zip})
Set NDC=NDCfile.Collection(path)
Dim doc As NotesDocument
Set doc=NDC.Getfirstdocument()
Print {first unid:} doc.Universalid
Kill path &{.zip}
Print {path:} path
Quit:
Exit Sub
ErrH:
Error Err, RaiseError
End Sub
сжатие и распаковка, в реальном варианте - на разных компах будет (или в разных частях кода - так правильнее)
Код:
Function AgentWNDC(db As NotesDatabase, agentName As String, NDC As NotesDocumentCollection)
On Error Goto ErrH
Dim docproc As NotesDocument
Dim NDCfile As New NDCFile, path As String
Set NDC=SelectedDocsUI
'получаем файл с коллекцией unid
Set NDCfile.Collection(Path)=NDC
NDCfile.Add(path)
path=path &{.zip}
NDCfile.Compress(path)
Dim agent As NotesAgent
Set agent=db.GetAgent(agentName)
Set docproc=db.CreateDocument
Call docproc.ReplaceItemValue({form},{Log})
Dim rtItem As NotesRichTextItem
Set rtItem=docproc.CreateRichTextItem({body})
'прекрепляем файл к документу, для агента
Call rtItem.EmbedObject(EMBED_ATTACHMENT,{}, path)
Call docproc.ComputeWithForm(False,False)
Call docproc.Save(True,False)
Call agent.Run(docproc.NoteID)
'в docproc прописывается STATUS_FLD с результатом обработки
Set AgentWNDC=docproc
Quit:
Exit Function
ErrH:
Error 1024, RaiseError
Resume Quit
End Function
 
Последнее редактирование модератором:

duchan

Green Team
20.09.2006
128
11
BIT
249
можно несколько мыслей вслух? :)
1. про путь: всегда можно использовать temp, как получить в винде и линухах где-то было на форумах
2. на сколько я помню, параметр для агента это некая строка из 8 симолов и не обязательно, что бы она была реально как-то связана с каким-то реальным Noteid. (возможно только цифры hex, точно уже не помню давно это было)

Таким образом можно упростить т.е.
set NDCfile = New NDCfile(NotesDocCollection)
'где в New будет сформирован временный файл в temp директории с именем подходящим для передачи в агент и сразу зазипован.
Call agent.Run(NDCfile.FileName)
'где DCfile.FileName имя зазипованного файла без .zip в формате подходящем для agent.Run

в Destroy класса NDCfile - удаление файла. и всё ни каких лишних движений, документов, строк кода - всё спрятано.

Есть еще момент, когда надо вызвать агент на сервере, то тогда только через временный файл, но надо будет этот файл приаттачить к временному документу и передать Noteid временного док-та. Кстати тоже логику можно спрятать, например, если берем свойство NDCfile.Noteid, то автоматом формируем временный док-т и отдаем его noteid, а при удалении класса удаляем не только файл, но и временный док.

Тут кстати вопрос, а ГДЕ вы временные док-ты будите создавать? Поскольку если это продакшин и пользователи, например, не могут удалять док-ты в базе, получим проблему с мусорными док-тами. Решение, база для временных операций, но тут уже логика системы в целом должна играть. Так что универсально для ВСЕХ случаев тут не подойдет.
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
541
Хм...
Я обычно документ создавал в базе со списком UNID, которые надо обработать.
Далее агент просто ищет этот док, если есть - обрабатывает.

Можно использовать, если есть база Mail-In, в которой крутится агент на приход почты. - этакая очередь запросов на обработку.
Агент анализирует и уже запускает внешний... Который работает с этим запросом, в котором файл...
Хм, в такой связке, это интересно... Надо подумать...
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
1. про путь: всегда можно использовать temp, как получить в винде и линухах где-то было на форумах
оно так и есть, в проперти Collection, path - это принимающая переменная
все действяи над файлами скрыты, более того - есть возможность автоматически удалять (она вшита в класс)
оставлена возможность указать путь принудительно и не удалять автоматически
опять же - сжатие необязательная процедура, потому и путь оставлен как параметр
др. ловами - создан базовый класс, с более широкой кастомизацией, под дальнейшую специализацию
там и развертывание архива основано на классе, кот. выдает рекурсивный список файлов по всем вложенным каталогам (на java, визитор)
2. на сколько я помню, параметр для агента это некая строка из 8 симолов и не обязательно, что бы она была реально как-то связана с каким-то реальным Noteid. (возможно только цифры hex, точно уже не помню давно это было)
через док сделано для того (и это я акцентировал) - чтобы запускать на разных компах (клиент-сервер, например RunOnServer)
Я обычно документ создавал в базе со списком UNID, которые надо обработать.
Далее агент просто ищет этот док, если есть - обрабатывает.
глубина озвученной мною мысли - в использовании (в том числе) для очень больших коллекций (или для группы коллекций), что автоматически приведет к головняку с РТ, потому и файл
В качестве доработки - возможна подобная передача уже DXL коллекций (что более нагрузочно, но не менее забавно ;) )
 
Последнее редактирование модератором:
  • Нравится
Реакции: savl

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
собсно
Код:
%REM
*********************************************
Class NDCFile
Description: получить коллекцию документов
по списку UNID из файла
или записать в Файл
%END REM
Class NDCFile As FilesObj
Private NDC As NotesDocumentCollection
Private db As NotesDatabase
Private ses As NotesSession
Private arrFiles As Variant
Private path As String
Private tmp As TempFolderManager
%REM
*--------------------------------------------
Sub New
Description: Comments for Sub
%END REM
Sub New()
Dim routineName As String
routineName="New"
On Error GoTo ErrH
'your code here
Set me.ses=New NotesSession
Set me.db=me.ses.Currentdatabase
Quit:
Exit Sub
ErrH:
Error Err, RaiseError
Resume Quit
End Sub
%REM
*--------------------------------------------
Property Get Collection
Description: path is directory
%END REM
Property Get Collection(path As String) As NotesDocumentCollection
Dim routineName As String
routineName="Collection"
On Error GoTo ErrH
'your code here
Set NDC=db.CreateDocumentCollection()
me.path=path
me.arrFiles=Me.Files(me.path)
If DataType(me.arrFiles)=V_STRING Then
Me.NDCFromFile(CStr(me.arrFiles))
Else
ForAll f In me.arrFiles
Me.NDCFromFile(CStr(f))
End ForAll
End If
Set Collection=NDC
Quit:
Exit Property
ErrH:
Error Err, RaiseError
Resume Quit
End Property
%REM
*--------------------------------------------
Function NDCFromStream
Description: Comments for Function
%END REM
Private Sub NDCFromFile(fname As String)
Dim stream As NotesStream
Set stream=ses.Createstream()
Dim routineName As String
routineName="NDCFromStream"
On Error GoTo ErrH
'your code here
If stream.Open(fname) Then
Dim unid As String
Do
unid=stream.Readtext(STMREAD_LINE, EOL_PLATFORM)
Dim doc As NotesDocument
Set doc=GetDocumentByUNIDSilent(me.db, unid)
If Not doc Is Nothing Then Call NDC.Adddocument(doc)
Loop Until stream.Iseos
End If
Quit:
Exit Sub
ErrH:
Error Err, RaiseError
Resume Quit
End Sub
%REM
*--------------------------------------------
Property Set Collection
Description: path is full path to file
%END REM
Property Set Collection(path As String) As NotesDocumentCollection
Dim routineName As String
routineName="Collection"
On Error GoTo ErrH
'your code here
Dim doc As NotesDocument, stream As NotesStream
Set doc=Me.Collection.Getfirstdocument()
Set stream=ses.Createstream()
Set tmp=New TempFolderManager
me.path=tmp.NewFilename({txt}, true)
path=me.path
Call stream.Open(me.path)
Do While Not doc Is Nothing
Call stream.Writetext(doc.Universalid, EOL_PLATFORM)
Set doc=Me.Collection.Getnextdocument(doc)
Loop
Set NDC=Collection
Quit:
Exit Property
ErrH:
Error Err, RaiseError
Resume Quit
End Property
End Class
и
Код:
Set tmp=New TempFolderManager
me.path=tmp.NewFilename({txt}, true)
это именно автоматическое удаление при дестрое, а zip не трогаю ибо его создание факультативно, класс базовый
удаление можно оформить в виде TempFolderManager.Manage(path+{.zip}), в Compress, нюанс состоит в необходимом времени жизни зипа (его можно и не аттачить и использовать позже...)
[DOUBLEPOST=1428571225,1428571098][/DOUBLEPOST]над EOL_PLATFORM тоже надо думать ;) ибо клиент, в большинстве, винда, а вот серваки, у мну - линух

ЗЫЖ коллеги, спасибо за комментарии и интерес к теме
 
Последнее редактирование модератором:

savl

Lotus Team
28.10.2011
2 624
314
BIT
541
В качестве доработки - возможна подобная передача уже DXL коллекций (что более нагрузочно, но не менее забавно ;) )
О, идея...В XML можно же все сгруппировать как надо и все связи прописать...
Еще чуть-чуть и можно сделать нормальный журнал транзакций.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
столкнулся с интересной особенностью бриджа LS2J...
код
Java:
public class ZipUtil {
private String enc = "Windows-1251";
ArrayList arrFiles = new ArrayList();
boolean bFullPath = false;
public static final String sep = System.getProperty("file.separator");
....
public static String fs_sep(){return sep;}
выше - класс, кот. дергает в конструкторе
Код:
 Set ZipClass = jSession.GetClass("org.files.ZipUtil")
sep=ZipClass.sep
дергаем из формы (как угодно хоть акшн, хоть кнопка на форме), дык эта сумкадраная грит - де нету такого мембера, в то время как из агента - все норм
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
также не будет работать:
sep=ZipClass.fs_sep()
а вот из агента будет и с приватным private static final String sep = System.getProperty("file.separator");
и sep=ZipClass.fs_sep()
 

Darkhan

Green Team
14.12.2012
99
2
BIT
0
Я предпочел бы, в качестве передачи параметров (serverName, databasePath, unid или NotesUrl), использовать транзитную вспомогательную базу. Группировать параметры путем создания документа-контейнера (через DigestSearch), а сами параметры к нему респонзить. По окончании все это подчищать. Во избежании проблем с индексами вьюх, просто не создаем их вообще, пусть останется единственная с формулой отбора Select Form="Babuin"))
Без бубна с зипами и бриджами, без обид
 

savl

Lotus Team
28.10.2011
2 624
314
BIT
541
дергаем из формы (как угодно хоть акшн, хоть кнопка на форме), дык эта сумкадраная грит - де нету такого мембера, в то время как из агента - все норм
Давно заметил, что мост корректно работает только в агентах...
Даже если есть LS2J либа, то все равно в агенте лучше работает.
Где-то видел инфу, что это связано с класслоудером, мол в технологии агентов он один, а в форме другой.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
Я предпочел бы, в качестве передачи параметров (serverName, databasePath, unid или NotesUrl), использовать транзитную вспомогательную базу. Группировать параметры путем создания документа-контейнера (через DigestSearch), а сами параметры к нему респонзить. По окончании все это подчищать. Во избежании проблем с индексами вьюх, просто не создаем их вообще, пусть останется единственная с формулой отбора Select Form="Babuin"))
Без бубна с зипами и бриджами, без обид
не понял мысли...
бридж только исходя из работы в ЛС и только для экономии трафика - зип(и сокращения времени передачи)

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

второй кэйс - некий код наработал коллекцию и есть желание обработать её в рамках другого процесса и, возможно, отложенно

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

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
471
как будет это представлено:
будет отдельная БД, для спец доков
будет только файл
глубоко безразлично на общем уровне
НО файл, в контексте универсальности обработки, на мой взгляд - гибче, а сжатие текстовой информации - это вполне себе достойная задача
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!