StudyNet provides students with access to an online website for everyone of their modules. Each module provides staff with tools to create resources, podcasts, video, discussions, etc. One feature that’s steadily developed is our module ‘wiki’ facility.
This year there’s been a significant number of staff using the facility with large cohorts and this has led to a problem when students edit a page at the same time requiring staff to manually merge the contributions.
There appeared to be two solutions. To provide better tools to merge contributions across a number of documents or to lock pages when somebody edited the document. Locking appeared to be the best and easiest solution. It was how to achieve this in a cluster.
I’d been considering implementing my own locking system but after a web search it was clear that the ‘document locking’ facility introduced with Domino 6 that I’d discounted because it ‘doesn’t work on the web’, did via WQO and WQS agents and it was just Lotus’ usual flaky documentation that was wrong.
For those who have been as slow as me, here’s a brief rundown of some of the issues I’ve dug up and issues I’ve faced with our implementation
The first thing to be aware is that the locking option is switched off by default. To enable it you need to assign a master lock server, by assigning an administration server to your database. (Advanced option in the ACL). When a document is edited, the lock is recorded on this server. You will also need to make sure that the ‘enforce a consistent ACL across replicas’ is also set. Once this is done you can enable locking via the database properties.
Locking is actually pretty simple to implement. There’s three main methods, document.lock, document.unlock and document.lockhaolders. When you set a lock, one of two types can be set, permanent and semi-permeant lock. In a web cluster, semi-permeant locks are set if the admin server is unavailable. I found some references to bugs where the semi-permeant locks aren’t released and become permeant locks, so in our case I’ve avoided them. If our admin server is down, the error is caught and locking is disabled.
Once a document is locked, no one else can save the document until the lock is released. Unfortunately, these are permanent locks. You have to clear the lock otherwise no one, including managers, can save the document. It seems that many people use a scheduled agent to free the locks overnight. For us, this isn’t an appropriate solutions.
StudyNet provides a website (domino database) for every module of every course that run at the University, approximately 4000 each year. We also keep live 5 years worth of websites so that students can refer back to their previous modules – totalling over 20,000 active websites. It’s just not practical to run overnight jobs checking all the documents on all these databases for locks. So I’ve implemented a self-clearing lock system.
The locking method adds two fields to the edited document on the master lock server. These are ‘$Writers‘ array and datetime ‘$WritersDate’.
Although it’s possible to return the $Writers array using the document.lockholders function, there isn’t a method to return the $writesdate option. This appears to be an obvious oversight but a extremely annoying one because these fields are not replicated out through the cluster – why would they, the whole point of assigning a single server to handle locks is to get round the replication delay. Since my code is designed to free up locks after 30 minutes, I’m checking the ACL.adminstrationserver property and then (if necessary) opening the version of the document being viewed on the other server to check the lock date.
When a document is locked you cannot delete the document (or copy?). In our case we have agents that handle delete wiki documents, so it was just a case of checking for a lock before deleting.
Another important point is that the lock option is not inherited from templates. So in our case, we got 20,000 websites that do not have the admin or locking option set. So you’ll need to update them using an agent or do what we’ve done and include in your lock code a check to see if the current database’s ‘IsDocumentLockingEnabled’.