Tommy Valand commented on Aug 7, 2009

I actually like scheduled agent.. :)

1. The content update I mentioned is an update to a couple of fields (including a RichText field). The applications in question contain the customers content plus content that they subscribe to from our company.

When we update our "master" databases, the updates are put in a queue.

2. Can't see how this is better than/an argument agains event bubbling. More of a complementary feature than either-or.

3. Already doing that. A custom log application that the update routine writes to. Updated documents per database.

Regarding your english.. Mine is probably worse.. :)

Anže Bajde commented on Aug 7, 2009

Scheduled agents exception logging.

Scheduled agents are LN programers nightmare. :)

In your case I recomend some options:

1. If all 250+ databases are notesdatabases why don't you use replication?

2. If replication does not work for you, than enable agent loging and transactional logging. Both native to Domino/Lotus Notes.

3. Try creating log documents like all servers do. Every night you create a new txt document on server, write every error event to new line in a structured way so it will be readable by any SQL database, excel, even notes import agent can work. In that way you will be able to fully alocate error and also to analize it. In every case using OS functionality is faster than any thing else. I recomend comaseparated (csv) text structure.

Here are just some ideas how to handle with problems like yours. I am sure that those are not the only options to handle it but are just put into considoration.

P.S. Sorry about my english.

Tommy Valand commented on Aug 7, 2009

Regaring the example..

This is a scheduled agent that runs every night..

Tommy Valand commented on Aug 7, 2009

It depends on what you're working on..

I work on applications where I -need- the routine to stop if it encounters -any- exception. If it didn't I'd have to do an hour(++, depending) of work to clean up the mess.

One example:

A routine updates content in 250+ databases. If deep in a call stack, the bottom one fails -without bubbling-, the routine continues, and the db in question never gets the update (after the update is completed, the updates are removed update-queue).

If I -use bubbling-, the update-routine is stopped on any exception, the updates remain in the queue. I get a mail that something has gone wrong. I fix the error, and the update routine is restarted.

If you haven't used exception bubbling, I understand your skepticism. After implementing it in the critical applications, I sleep a lot better at night.. :)

Anže Bajde commented on Aug 7, 2009

OpenLog doesn’t help you with Exception bubbling - true but ...

True, but why should you code that way that Exception bubbling is needed. You shoduld create Class that includes open log with constructio initializing it, defineing object in class.

Than in initialize you set it. That way the class containing openlog loging in global trought your library/agent. Whenever error acures you log error and do not continue.

Lib MyLogLib

Public MyClass As MyClassClass

Public Class MyClassClass

Public Sub New()

Set Me.openlog = New LogItem (Item containing openlog)

Exit Sub

End Class

SL:

Options:

Use "MyLogLib"

Initialize: Set MyClass = new MyClassClass

anywhere else use

on error goto Error

Error:

Call MyClass.openlog.OpenLog()

Tommy Valand commented on Aug 7, 2009

OpenLog doesn't help you with Exception bubbling

@Anže: OpenLog doesn't do Exception bubbling. If an exception occurs deep in a call stack, and you use:

..

Exit Sub

handleError:

Call OpenLog()

Exit Sub

End Sub

The previous functions in the stack may continue to run. If you instead bubble the exception, and use OpenLog/whatever at the top, you avoid (possibly) doing damage, and you get a nice printout of the exception stack.

My bubbling-function/helper:

Function errorMessage As String

'Event bubbling helper

Dim message As String

message = Error

If Cstr( Getthreadinfo(10) ) = "INITIALIZE" Then

errorMessage = "Error " & Err & " on line " & Erl & " in function " & Getthreadinfo( LSI_THREAD_CALLPROC ) & ": " + Error

Else

errorMessage = Chr(13) + Chr(9) + "Error " & Err & " on line " & Erl & " in function " & Getthreadinfo( LSI_THREAD_CALLPROC ) & ": " + Error$

End If

End Function

In script-lib functions:

On Error Goto bubbleError

..

Exit Sub

bubbleError:

Error Err, errorMessage()

In Initialize:

On Error Goto logError

..

Exit Sub

logError:

Call OpenLog()

Exit Sub

Anže Bajde commented on Aug 6, 2009

Or ... OpenLog

Use OpenLog.

Esther Strom commented on Mar 27, 2009

Or..

You could just use the built-in ArrayUnique function...