Workshop Dashboard

I’m building a pure Workshop application in Palantir Foundry (no Slate, no OSDK). The application has a dashboard that shows a list of requests. A user can open a specific request and edit some of its data.

My challenge is ensuring that only one person can work on a request at a time, so that two people don’t edit the same request simultaneously and cause data loss or confusion.

Since this is a Workshop-only application, what is the recommended way to solve concurrency control or record locking in Foundry Workshop? What patterns or tools should I use to:

  • Prevent two users from editing the same request at the same time

  • Show the user that the request is currently locked or in use

  • Safely release the lock when the user finishes or times out

Any guidance or examples for implementing safe “one-at-a-time editing” in Workshop would be very helpful.

There might not be an out-of-the-box solution for this workflow, but it can be configured by tracking the lock status of each record. I asked AI and it phrased a solution with far more details than I would have:

Concurrency Control Patterns in Foundry Workshop

1. Optimistic vs. Pessimistic Locking: Why Pessimistic is Needed Here

  • Optimistic Locking is often supported via timestamp/version checks on save (detecting conflicts), but does not actively prevent simultaneous edits.

  • Pessimistic Locking, which is your goal, explicitly marks a record as “locked” and prevents other session(s) from editing.

Workshop (unlike OSDK backend or Slate) can’t natively enforce field- or row-level locks, but you can build this with a few core patterns.

Recommended Approach: Implementing Pessimistic Record Locking in Workshop

A. Create a “Locks” Table

  • Make a new Workshop table (or add columns to your “requests” table) to track lock status.

    • request_id (foreign key to your main record)

    • locked_by (username or user ID)

    • locked_at (timestamp)

    • lock_expires_at (optional, for timeout auto-expiry)

B. Lock Acquisition Workflow

  1. On “Edit” Request:

    • When a user wants to edit, check the Locks table for this request:

      • If locked_by is blank or expired, allow the user to acquire the lock:

        • Write their user ID and a current timestamp into the lock.

        • Optionally, set an expiry (e.g., +15min).

      • If locked by someone else and not expired:

        • Show a UI banner: “This request is currently being edited by [user].”

        • Disable editing.

  2. Concurrency Reinforcement:

    • All edit actions (writes) should check the Locks table to confirm active lock ownership before committing changes.

C. Lock Release Patterns

  • Explicit Release: When user clicks “Save” or “Cancel,” clear the lock (delete row or null out owner fields).

  • Timeout/Expiration: Periodically check if the lock is old and, if so, consider it expired and reusable.

    • Can be implemented by storing lock_expires_at and checking against current time during edit attempts.
  • UI Banner or Indicator: Always show clearly if a lock is in place, including the locking user and how long until expiration.

D. Implementation Tips

  • Atomicity: Use Workshop “actions” for lock acquisition and release to keep the logic clear and reduce race conditions. The write that sets the lock should be atomic.

  • Workshop UI: Use “Conditional Cell Rendering” or “Dynamic Form State” to disable form inputs if a lock is present.

  • Polling/Refreshing: Consider a modest auto-refresh/polling interval on the lock status in the UI for live feedback (every ~10–30 seconds).

  • Edge Cases: Handle users closing their browser/crashing by relying on lock expiration.

Example Schema for a “Locks” Table

request_id locked_by locked_at lock_expires_at
1234 userA@email.com 2025-12-12 12:00:00 2025-12-12 12:15:00
2345

Example UI Logic (Pseudo-Code)

// When editing a request
if (lock for request_id is empty or expired) {
write lock with (request_id, user, now, now + 15min)
allow editing
} else if (lock.locked_by == currentUser) {
allow editing
} else {
show "Locked by [User X] until [expiry]" and disable editing
}

Summary & Practical Recommendations

  • Create a Locks Table: This is your concurrency “source of truth.”

  • Atomic Lock Acquisition: Always check and write the lock as a single atomic update.

  • UI Feedback: Clearly display lock status to users; disable edit controls when locked.

  • Safe Release: Release on save/cancel, or via stale lock expiration.

  • Periodic Refresh: Poll lock status to reflect real-time status changes.

This approach aligns with how many Foundry teams structure collaborative workflows within Workshop’s limits—simple, auditable, and resilient.

3 Likes