Autor Thema: Profildokument mit Serveragent?  (Gelesen 2936 mal)

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Profildokument mit Serveragent?
« am: 03.04.10 - 08:42:30 »
Moin,moin,

also über die Suche hab ich da nichts passendes zu gefunden. Ich experiemtiere etwas mit Profildokumenten.

Ich habe eine Ansichtsaktion in der das Profildokument mit diversen Werten gefüllt und gespeichert wird. Danach ruft die Aktion einen Agenten via .runonserver auf. Der Serveragent soll nun bei vorhandensein einer bestimmten Datei den Status 1 oder 0 (bei nicht vorhandensein der Datei) in das Profildokument schreiben und ebenfalls speichern.

In der Aktion wird nach Aufruf des Agenten das Profildokument auf diesen Wert abgefragt. Leider wirft er mir nicht den Wert aus, den das Profildok laut meinen Logs haben müsste.

Das Ganze ist irgendwie leicht mysteriös. Setze ich zum Beispiel in der Aktion den Wert im Profildok auf 0 wirft mir mein Serveragent danach den Wert 1 aus???

Das die Aktion mir nicht den Wert auswirft, den der Serveragent reingeschrieben hat, ist wahrscheinlich ein Timing-Problem, oder? Wird der Code in der Aktion pausiert, bis der Agent via .runonserver fertig gelaufen ist, oder läuft er ganz normal weiter?

Hintergrund des Ganzen ist, der Agent darf nur von einem User gestartet werden, wenn eine bestimmte Datei nicht vorhanden ist. Wenn diese vorhanden ist, sollen andere User halt den Hinweis bekommen, dass sie es später erneut probieren sollen.


Gruß
Demian

PS: Cache hatte ich schon gelöscht. Hatte es vorher auch schon mit einem normalen Dok probiert, und den Agenten via runonserver (ID) aufgerufen, jedoch mit dem selben Ergebnis. Deswegen die Vermutung, dass es sich um ein Timing-Problem handelt. Der einzige Lösungsweg der mir dann jetzt spontan einfallen würde, wäre in der Aktion ne Schleife einzubauen, die solange läuft, bis das Dokument vom Server signiert wurde. Fände es aber sehr unschön, dass so zu lösen.


Gruß
Demian

Offline Werner Götz

  • Aktives Mitglied
  • ***
  • Beiträge: 248
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #1 am: 03.04.10 - 09:18:10 »
Nein, das ist kein Timing-Problem, ich denke, dass es schon ein Caching Problem ist.

Profildokumente werden bei Zugriff via GetProfileDoc nur einmal pro "Datenbank-Session" (also solange man sich in einer Datenbank befindet) gelesen. Da kann dann ein Server-Agent reinsschreiben, was er will, die Werte werden nicht aktualisiert.

Bei normalen Dokumenten muss man die Referenz auf das bereits geholte (das ja "mit diversen Werten gefüllt" wurde) erst löschen (z.B. Delete doc).

-Werner

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #2 am: 03.04.10 - 09:28:36 »
Bei normalen Dokumenten muss man die Referenz auf das bereits geholte (das ja "mit diversen Werten gefüllt" wurde) erst löschen (z.B. Delete doc).

oh mann...delete...da muss man auch erstmal drauf kommen. Hatte diese Vermutung nämlich auch schon und es mit set doc = nothing probiert, weil ich es von anderen Sprachen so kenne, nur in Notes mag er das wohl nicht.

Werde es dann heut nachmittag/abend mal so probieren und berichten.

Vielen Dank.

Gruß
Demian
Gruß
Demian

Offline pram

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.170
  • Geschlecht: Männlich
    • Foconis Object Framework
Re: Profildokument mit Serveragent?
« Antwort #3 am: 03.04.10 - 17:42:58 »
ein doc=nothing sollte aber auch reichen, wenn man es richtig macht und keine weitere Referenz mehr existiert. So z.B.:
Code
set doc = new NotesDocument(db)
... doc füllen
call doc.save(false,false)
id = doc.NoteID
set doc = nothing
call agent.runOnServer(id)
set doc = db.getDocumentById(id)
... doc lesen
call doc.remove()

Frohe Ostern
Roland
Roland Praml

IBM Certified Application Developer - Lotus Notes and Domino 8
Ich verwende das Foconis Object Framework

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #4 am: 03.04.10 - 17:48:23 »
Es sei aber angemerkt, dass weder Delete noch Set to Nothing in diesem Zusammenhang mit ProfileDocs irgend etwas nützen. Man bräuchte ja sonst auch nur den Agent zweimal starten - das erste Terminate hätte ja das ProfileDocument-Object mit absoluter Sicherheit in die ewigen Jagdgründe geschickt  ;)

Bernhard

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #5 am: 03.04.10 - 19:28:17 »
Hallo zusammen,

also delete in Verbindung mit einem normalen Dokument tat es so wie ich wollte. Mit set profileDoc = nothing hatte ich es heut morgen auch probiert, da kam aber eine Meldung irgendwas in der Richtung "SET can only be used...." oder so ähnlich. Weiß es offen gestanden nicht mehr genau.

Gruß
Demian
Gruß
Demian

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #6 am: 13.04.10 - 10:56:47 »
so ich nochmal  ;D

habe irgendwie grad ne totale Denkblockade, bzw. Probleme mit der Umsetzung. Ich habe einen periodischen Agenten, der mir abends Schnittstellendateien im Datenbankverzeichnis erstellt.

Dieses DB-Verzeichnis ist auf unserem Zeitserver als Netzlaufwerk verknüpft. Auf dem Zeitserver kopiert (ebenfalls periodisch) eine Batch-Datei die erstellten Dateien in das Arbeitsverzeichnis des Zeitservers, wo diese vom Zeitprogramm letzlich periodisch eingelesen werden. Das funktioniert ja auch alles prächtig. Das Problem ist aber, dass bestimmte Personen diesen Agenten auch (unter Umständen mehrmals am Tag) manuell starten müssen. Wenn das gemacht wird, müssen sich die User auf dem Zeitserver aufschalten und die Batch-Datei ebenfalls manuell ausführen, da sonst die von einem User erstellten Dateien, ggf. von einem anderen User überschrieben werden.

Mein Gedanke war nun folgender:

Im Datenbankverzeichnis arbeite ich mit 3 weiteren Dateien (AllreadyImported.notes, AllreadyImported.true, AllreadyImported.false). Die Datei .true enthält den Wert 1, die Datei .false den Wert 0. Die Datei .notes soll den momentanen Import Status darstellen und wird vom Agenten gelesen. Enthält die Datei den Wert 0, soll der Agent abbrechnen und im "Profildokument" FilesAllreadyImported = "0" setzen. Wenn die Batch-Datei ausgeführt wird, wird die Datei
.true in .notes kopiert. Der Agent kopiert die Datei .false in .notes, nachdem die Schnittstellendateien erstellt wurden.

Der Wert von FilesAllreadyImported im Profildokument muss dann in der Aktion die den Agenten startet abgefragt werden um dem User mitzuteilen, ob der Agent durchgelaufen ist oder seit der letzten Datei Erstellung die Batch-Datei auf dem Zeitserver nicht ausgeführt wurde.

Nur wie kriege ich nach dem Ausführen der Batch Datei im Profildokument den Wert FilesAllreadyImported wieder auf 1 gesetzt? Irgendwie verrenne ich mich da seit Stunden. Die einzige Option die mir da so einfallen würde (bitte nicht hauen), wäre denn Agent am Schluss so lange in eine Endlosschleife zu schicken, bis mir die Datei .notes den Wert 1 zurückliefert und dann das Profildok zu ändern. Nur wenn der User das mit der Batch vergisst, knallt es wahrscheinlich spätestens, wenn der Agent zu dem eingestellten Zeitpunkt anfängt zu laufen. Sofern er das dann überhaupt tut.

Hat da irgendwer ne Idee?

Gruß
Demian
Gruß
Demian

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #7 am: 13.04.10 - 11:01:12 »
PS: Mein bisheriger oft geänderter Code:

Aktion:
Code
Sub Click(Source As Button)
	'*********************************************************************************************************************************
	'creates the interface file KOSTT.TXT for the time managment in the same path of database
	'*********************************************************************************************************************************
	'Invoked from:		Initialize of this agent
	'used libraries:		logging
	'used functions:		CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
	'							Text As String)as Boolean	
	'*********************************************************************************************************************************
	'changed:	09.04.2010 - DDorn - verify that files allready imported from the time server side
	'*********************************************************************************************************************************
	On Error Goto ErrHandle	
	'*********************************************************************************************************************************
	Dim agent As notesagent
	Dim profileView As NotesView
	Dim profileDoc As NotesDocument	
	Dim Item As NotesItem
	
	'diyplay to user
	Dim AllreadyImported As String
	Dim ImportedBy As String
	'*********************************************************************************************************************************
	Set s = New NotesSession
	Set db = s.CurrentDatabase	
	Set agent = db.GetAgent("InterfaceTime")	
	Set profileView = db.GetView(lkpProfileView)	
	Set profileDoc = profileView.GetDocumentByKey(Cstr("ProfileInterfaceTime"))
	'-----------------------------------------------------------------------------------------------------------------------------------------------------------------
	'create profileDoc if it not exist an set status to 0 to warn other users if they start the action
	If profileDoc Is Nothing Then
		Set profileDoc = db.CreateDocument
		profileDoc.form = "ProfileInterfaceTime"
		profileDoc.ImportingUser = s.CommonUserName	
		profileDoc.FilesAllreadyImported = "0"
		Set item = New NotesItem(profileDoc,"ProfileInterfaceTimeAuthors", "[InterfaceData]")
		item.IsAuthors = True
		
		Call profileDoc.Save(True,False)
		
		'needed in the first run of this action, if no profileDoc exists
		'AllreadyImported = "1"
	Else
		If profileDoc.FilesAllreadyImported(0) = "0" Then
			'don't start the agent
			ImportedBy = profileDoc.ImportingUser(0)
			AllreadyImported = profileDoc.FilesAllreadyImported(0)
			
			Goto Message
		Elseif profileDoc.FilesAllreadyImported(0) = "1" Then
			'lock the agent for other users
			profileDoc.ImportingUser = s.CommonUserName
			profileDoc.FilesAllreadyImported = "0"
			Call profileDoc.Save(True,False)
		Else
			Call CreateLogEntry(db.title,s.CommonUserName,"Aktion: CreateInterfaceTime","Click",_
			"Error - Import Status konnte nicht von Profildokument ausgelesen werden")
		End If
		
	End If
	
	Set profileDoc = Nothing
	
	'agent decide if it will run or not and write status to profileDoc
	Call agent.RunOnServer()	
	
	'read the status from the profile doc
	Set profileDoc = profileView.GetDocumentByKey(Cstr("ProfileInterfaceTime"))
	AllreadyImported = profileDoc.FilesAllreadyImported(0)
	
Message: 
	If AllreadyImported = "0" Then
		Call CreateLogEntry(db.title,s.CommonUserName,"Aktion: CreateInterfaceTime","Click",_
		"Agent läuft bereits - " & " User: " & ImportedBy & " & Status: " & AllreadyImported)		
		
		Msgbox "Die Kostenträger werden zur Zeit von " & ImportedBy & " aktualisiert. Bitte probieren Sie es später erneut.",,"Muster GmbH"
		Goto Leave		
	Else
		Msgbox "Dateien wurden erstellt! Bitte starten Sie die batch-Datei auf dem Zeitserver um die Kostenträger zu importieren.",,"Muster GmbH"
	End If
	
Leave:
	Exit Sub
	
ErrHandle:
	Call CreateLogEntry(db.title,s.CommonUserName,"Aktion: CreateInterfaceTime","Click",_
	"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
	Resume Leave
End Sub

Agent - Initialize:
Code
	'*********************************************************************************************************************************
	'Creates the interface files for the time managment in the same path of database. They will copied sheduled by a batch
	'file on the time server. If the agent will run manual the batch file on the time server must be started by user. 
	'*********************************************************************************************************************************
	'used libraries:		logging
	'used functions:		CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
	'							Text As String)as Boolean	
	'*********************************************************************************************************************************
	On Error Goto ErrHandle	
	'*********************************************************************************************************************************
	Dim profileView As NotesView
	'*********************************************************************************************************************************
	Set s = New NotesSession
	Set db = s.CurrentDatabase
	Set profileView = db.GetView("lkpProfileDocs")	
	Set profileDoc = profileView.GetDocumentByKey("ProfileInterfaceTime")
	
	If profileDoc Is Nothing Then
		Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
		"Error - Das Profildokument konnte nicht gefunden werden")
		Exit Sub
	End If
	
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
	"Profildokument wurde gefunden, prüfe ob Dateien noch nicht importiert wurden")
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
	"Profildokument User: " & Cstr(profileDoc.ImportingUser(0)))
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
	"Profildokument Status: " & Cstr(profileDoc.FilesAllreadyImported(0)))
	
	If FilesNotImported = True Then
		Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
		"Die Dateien konnten nicht erstellt werden, da ein anderer User die Kostenträger importiert")
		
		Exit Sub
	End If
	
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
	"Die Listen für die Zeitwirtschaft werden aktualisiert")
	
	Call CreateKOSTT()
	Call CreateCHIPKOSTT()
	Call CreateWORKPLACEKOSTT()
	Call DeleteMarkedChipAssigns
	Call DeleteInterfaceIndicators
	Call SetImportStatus
	
Leave:
	Exit Sub
	
ErrHandle:
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
	"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
	Resume Leave
End Sub

Agent - FilesNotImported:
Code
Function FilesNotImported As Boolean
	'*********************************************************************************************************************************
	'check if the files allready imported by the batch file on the time server an write the status to profileDoc for displaying 
	'status to the user
	'*********************************************************************************************************************************
	'used libraries:		logging
	'used functions:		CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
	'							Text As String)as Boolean	
	'*********************************************************************************************************************************
	On Error Goto ErrHandle	
	'*********************************************************************************************************************************
	Dim FileNum As Integer
	Dim BatchReturn As Integer
	'*********************************************************************************************************************************
	
	FileNum = Freefile()	
	Open ConditionFile For Input As fileNum	
	
	BatchReturn = Input$ (1 , FileNum )
	
	Call CreateLogEntry(DB.title,s.CommonUserName,"Agent: InterfaceTime","FilesNotImported",_
	"BatchReturn: " & BatchReturn)
	
	Close FileNum
	
	'set status to profileDoc for display to user
	If BatchReturn = "0" Then
		profileDoc.FilesAllreadyImported = "0"
		Call profileDoc.Save(True,False)
		'RETURN
		FilesNotImported = True
	Else
		profileDoc.FilesAllreadyImported = "1"
		Call profileDoc.Save(True,False)
		'RETURN
		FilesNotImported = False
	End If
	
	Call CreateLogEntry(DB.title,s.CommonUserName,"Agent: InterfaceTime","FilesNotImported",_
	"Profildokument Status:" & Cstr(profileDoc.FilesAllreadyImported(0)))
	
	
Leave:
	Exit Function
	
ErrHandle:
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","FilesNotImported",_
	"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
	'RETURN
	FilesNotImported = False
	Resume Leave
End Function

Agent - SetImportStatus:
Code
Sub SetImportStatus()
	'*********************************************************************************************************************************
	'if agent is has created the interface files set AllreadyImported to 0, to stop creating new interface file from other users
	'*********************************************************************************************************************************
	'used libraries:		logging
	'used functions:		CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
	'							Text As String)as Boolean	
	'*********************************************************************************************************************************
	On Error Goto ErrHandle	
	'*********************************************************************************************************************************
	
	Filecopy AllreadyImportedFalse, AllreadyImportedNotes	
	
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","SetImportStatus",_
	"ImportStatus wurde auf 0 gesetzt - .false in .notes kopiert")
	
Leave:
	Exit Sub
	
ErrHandle:
	Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","SetImportStatus",_
	"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
	
	Resume Leave
End Sub
Gruß
Demian

Offline Demian

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 569
  • Geschlecht: Männlich
Re: Profildokument mit Serveragent?
« Antwort #8 am: 13.04.10 - 20:59:11 »
neuer Gedankengang... ;D

ich lasse die Aktion wie sie eigentlich war:

Code
	
	'*********************************************************************************************************************************
	'runs the server agent which creates the interface files
	'*********************************************************************************************************************************	
	'used libraries:		logging
	'used functions:		CreateLogEntry(DBName As String, User As String, DesignElement As String, InvokingEvent As String, _
	'							Text As String)as Boolean	
	'*********************************************************************************************************************************
	On Error Goto ErrHandle	
	'*********************************************************************************************************************************

	Dim s As New notessession
	Dim db As NotesDatabase
	Dim agent As notesagent
	'*********************************************************************************************************************************
	
	Set db = s.CurrentDatabase
	Set agent = db.GetAgent("InterfaceTime")
	Call agent.RunOnServer
	
	Msgbox "Dateien wurden erstellt!",,"Muster GmbH"

Leave:
	Exit Sub

	
ErrHandle:
	Call CreateLogEntry(db.title,s.CommonUserName,"Aktion: CreateInterfaceTime","Click",_
	"Error" & Str(Err) & ": " & Error$ & " in Zeile " & Erl)
	Resume Leave


Während der Agent weiterhin prüft, ob die zu Letzt erstellten Dateien seitens Batch schon kopiert wurden:


Code
...	
	If FilesNotImported = True Then
		Call CreateLogEntry(db.title,s.CommonUserName,"Agent: InterfaceTime","Initialize",_
		"Die Dateien konnten nicht erstellt werden, da ein anderer User die Kostenträger importiert")
		
		Exit Sub
	End If
	
...

Der brave Anleitung lesende User ( ::) ) weiß ja, dass er die Batch-Datei manuell ausführen muss. Tut ers nicht auch nicht weiter schlimm. Irgendein anderer User wird schon Änderungen vornehmen, den Agenten starten und die Batch Datei ausführen. Dadurch werden jedoch zunächst die zuvor vom anderen User erzeugten Dateien in die Zeitwirtschaft importiert. Man wird sich wundern, warum die eigenen vorgenommenen Änderungen nicht in die Zeitwirtschaft übertragen wurden. An diesem Punkt werde ich dann darauf hinweisen, dass halt ein anderer User den Agenten gestartet, jedoch die Batch nicht ausgeführt hat und man halt einfach das Prozedere (Agent Start und Batch Start) nochmal machen muss (AllreadyImported.notes enthält zu diesem Zeitpunkt ja wieder den Wert 1). Wenn man das permanent für andere mitmachen muss, wird man evtl. bei sich selbst mehr drauf achten. Das geht dann hoffentlich irgendwann in Fleisch und Blut über. >:D

Bleibt nur noch das Problem mit der Handhabung, wenn der Agent dann zu seinem täglichen Zeitpunkt läuft und die von einem User erzeugten Dateien noch nicht via Batch Skript importiert wurden. Hier sollte vielleicht die Usergruppe, die den Agenten manuell ausführen kann per Mail informiert werden, damit die Batch-Datei am nächsten Morgen manuell ausgeführt und die Änderungen vom Vortag auch manuell übernommen werden. Mal schauen.  :-:

Für irgendwelche anderen Vorgehensweisen bin ich natürlich offen ;)

Gruß
Demian


 
Gruß
Demian

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz