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
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.
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.
// 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.