2007-07-13

UndoBlocks, SyncServer, and multiple EcoSpaces

In an ECO app I am writing it is very important that updates by other users are identified as soon as possible. This is because there will be multiple users all selecting jobs to do from a predefined list, and it is not only possible but also very likely that more than one user will select the same job at the same time (the job at the top of the list).

To implement this I chose to use the remote persistence feature of ECO and in particular its Sync Server feature. Every 5 seconds my client apps will contact the server and retrieve a list of updates made by other users, it will then apply those updates to the cache of its own EcoSpace. So when a user selects a job to do at the top of the list their app will stamp it as InProgress and update the DB, the job will then automatically disappear from the screens of all other users.

As I like to use undo blocks in my app to allow the user to cancel changes (using my DirtyObjectCatcher component) it is highly likely that during these synchronisation operations there will be an active undo block. As a result of this any changes applied to the cache via the sync' process will be caught by the undo block. If the user decides to cancel their changes then all values in the undo block will be undone, including the synchronised changes from other users. This isn't a great problem for me because I am using the TimeStamp feature in ECO to ensure that when I update the DB I am actually updating the same values I originally fetched, but it does mean that the user is looking at old data. For example

01: User A is looking at a list of jobs, they choose to action Job 1
02: User B sees Job 1 disappear from their screen and choose to action Job 2
03: User A sees Job 2 disappear from their screen.

So far, so good. Now remember, the change of state to Job 2 was caught by the undo block that was activated when User A started to edit Job 1.

04: User A decides to cancel their changes.
05: The active undo block reverses its changes, this includes the changes applied by the sync server.

As a result user A sees Job 2 reappear on their screen.

This didn't cause me an operational problem, because when actioning a job I do this...

01: Assign to current user
02: Update DB
03: If no exception then continue to edit
04: If OptimisticLockException occurs then unload the job and tell the user another user is working on the same job and ask them to select another + unload the job from the cache (will causes it to be reloaded with the new info and disappear from the screen).

This is essential anyway because the Sync server only makes it less likely to experience a conflict, it does not make it impossible (always use OptimisticLocking unless overwrites are acceptable!).

Still, I wanted to prevent the user from seeing this message as much as I possibly could. The answer is very simple, you just use a new instance of the EcoSpace for editing the job. The UndoBlock isn't actually needed now, but I still have it because the DirtyObjectCatcher provides a great way of providing validation feedback to the user. When the UndoBlock is reversed though it will revert to old values in the new EcoSpace instance, which is irrelevant because it will be disposed once the owning form is closed. Any updates to the data will appear in the main app within 5 seconds due to the fact that the second EcoSpace instance will also use remote persistence to save the changes which will in turn ensure that all other EcoSpaces (in the same app or on different machines) will be notified of the changes.

I think I might play with this technique some more. It looks like quite a nice way of working with ECO and multiple users!

No comments: