Thursday, January 10, 2008

This database will help you to search log.nsf for a specific error message or string for a given period of time and display the result in one document. It is designed to help support person to view specific error occurrences on a given server without opening multiple log documents.

With a distributed application like Notes, one of the problems is that someone can have a local replica and not replicate for a while. This can cause problems like previously deleted documents reappearing, or replication conflicts. This tip describes one way of reminding users to replicate at least somewhat frequently. If the user hasn't replicated in a week or more, they are reminded to replicate so they'll have the latest information.

The problem becomes "how do you know how long it's been since this user has replicated"? I'm sure there are other ways to do this, but the way I use is to keep a profile document on the server with today's date. A scheduled agent, set up for 12:15 AM every day, updates the profile document. So, whenever the user replicates, they'll have a profile document with the date they last replicated. That profile document is never updated on the local replica - only on the server version. It makes it pretty easy to know the last date they replicated by looking at the profile and comparing it to today's date.

So, let's start by taking a look at the agent. It's a scheduled agent, set to run on the server (just choose 1 server if you're in an environment where your applications are on multiple servers for load balancing purposes), and set to run at 12:15 AM every day. Here's the code:

The name of the profile is CurrentDate and the field on the profile with today's date is also called CurrentDate.

When the database is opened, I check that profile document and compare it to today's date. This tells me how long it has been since the user has replicated. If it's been a long time (more than 60 days) since the user replicated, they are told to replicate immediately. There are even some applications that prevent user access if it's been more than 60 days since they replicated. But that's beyond the scope of this tip. If it's been a little while (more than 7 days) then I give a different warning message suggesting the user replicates. Here's the database PostOpen code:

Sub Postopen(Source As Notesuidatabase) Dim session As New NotesSession Dim db As NotesDatabase Dim profile As NotesDocument Dim msg As String Dim eval As Variant Set db = session.CurrentDatabase If db.Server = "" Then msg = "" Set profile = db.GetProfileDocument("CurrentDate") If Not profile.HasItem("CurrentDate") Then msg = "You have not replicated with the server in a while. Please replicate" msg = msg & " to ensure you have all the latest design and document" msg = msg & " information." Else eval = Evaluate({@Integer((@Now - CurrentDate) / 86400)}, profile) If eval(0) > 60 Then msg = "You have not replicated with the server in at least a couple of months." msg = msg & " You should replicate IMMEDIATELY to ensure you have all" msg = msg & " the latest design and document information." Elseif eval(0) > 7 Then msg = "You have not replicated with the server in at least a week. You should" msg = msg & " replicate to ensure you have all the latest design and" msg = msg & " document information." End If End If If msg <> "" Then Msgbox msg, 48, "Please Replicate" End If End IfEnd Sub

The code first checks to see if the user is on a local replica. If they're already on the server, then I don't need to check the profile. So I only check if the server is blank which indicates they are on a local replica. Next, I get a handle to the profile document. Note that with profile documents, if the profile document doesn't exist, it will be created. So that's why I check for the field being present - if the field is missing then the profile document did not previously exist in the user's local replica. So I want to give a warning message to replicate just to make sure they have the server's profile document for future reference.

If the field does exist, that field holds the date their version was last updated. So I compare it to today's date and see how many days it's been (dividing by 86,400 or the number of seconds in one day). If that has been more than 60 days, then I'm going to give the user the "immediately" message. If it's been more than 7 days I give a slightly less stern message.

If one of the checks resulted in the variable msg being updated, then that prompt is given to the user.

So that's how I implement a check to make sure that users keep up with their local replicas. I will point out if it's been more than 60 days since the user last replicated, there are different ways to make sure the user doesn't use the application - which forces them to replicate. One way is to have some PostOpen code in every view that closes the view immediately if it's been more than 60 days since they replicated. Another way is to hide action buttons if it's been too long since they replicated. You can also prevent the opening of documents if it's been too long since they replicated - this is done through the form QueryOpen event.