Gettting exclusive access to a resource in the frontend

Using the @mod-system/js/wh/exclusiveaccess.es module, you can get a lock on a (string-identified) resource. This uses the a same infrastructure as the Tollium GetExclusiveAccess API.

Considerations

Locks can be stolen by other users at arbitrary times. In Tollium, this ususally isn't a big problem, because code running under a lock is usually synchronous, so locks can't be stolen while the code is running. In the web frontend, manipulations are usually done by RPCs that are decoupled from the locking logic.

To solve this, the API provides the user with a lock token. With this token, the user can call GetExclusiveLockRPCMutex (from mod::tollium/lib/applications.whlib) that guarantees that the lock is active at the moment that function is called. Also, that function returns a mutex lock that prevents other users from getting a lock on the resource. You should not hold on to this lock for a long time, as no feedback is given to the other users.

Using the dialog-API

The easiest way to lock a resource is using getExclusiveAccessWithDialog. This function will show dialogs using the dompack dialog-api, and uses dompack modal UI-busy locks to lock the interface while obtaining the requested lock. The dialogs contents can be overridden using the callbacks.

Example:

let lock;
try
{
  lock = await getExclusiveAccessWithDialog("resource-id",
    { realname: "Henk Testuser", entityid: 7 },
    { onAlreadyLocked: (realname, login) => <div>Already locked by {realname || login}. Take over?<div>
    , onLockStolenShown: () => { /* lock was stolen and the user acknowledged it, navigate away */ }
    , buttontitles: { yes: "YES!" }
    });
}
catch (e)
{
  // obtaining the lock failed, navigate away
}

// guard against lock stealing
lock.addEventListener("close", () => lock = null);

// .. show some ui, interact with user

if (lock)
{
  // ... call RPC editresource, passing lock.token
}

if (lock)
  lock.release();
MACRO RPC_EditResource(STRING locktoken, RECORD editdata)
{
  OBJECT lock := GetExclusiveLockRPCMutex(locktoken);
  TRY
  {
    ... perform the edit
  }
  FINALLY
    lock->Release();
}

Compatibility with Tollium GetExclusiveAccess

The web frontend only supports strings as identifiers, while the tollium API allowes arbitrary HareScript values. You can translate the web frontend identifiers to Tollium identifiers wby wrapping them in a record, with the identifier in the cell jslock. Eg:

  this->GetExclusiveAccess([ jslock := identifier ]);