Semafy provides synchronization and concurrency management across execution agents (main thread, web workers). It contains a robust set of tools modeled after C++ synchronization primitives, offering control and flexibility for managing shared resources and states.
- Mutexes: Exclusive and shared locking to protect data from concurrent access.
- Semaphores: Control access to a finite number of resources.
- ConditionVariable: Allows agents to wait for certain conditions to occur.
- Barriers: Ensures agents reach a certain point before any can proceed.
- Utilities: Manage async code with
lock
,tryLock
,lockGuard
, andcallOnce
. - Error Handling: Specific error classes to enhance debuggability and reliability.
- Platform Agnostic: Works in any browser or server-side environment that supports
SharedArrayBuffer
.
NPM:
npm install semafy
Yarn:
yarn add semafy
JSR:
jsr add @rojas/semafy
-
[Sync]BasicLockable: A base interface that provides exclusive blocking for agents.
-
[Sync]Lockable: Extends
BasicLockable
to include attempted locking. -
SharedLockable: Provides shared blocking semantics for agents.
-
SharedResource: Represents a shared resource that is backed by a
SharedArrayBuffer
. -
SharedTimedLockable: Extends
SharedLockable
to include timed blocking. -
[Sync]TimedLockable: Extends
Lockable
to include timed blocking.
-
Mutex: Provides essential mutex operations including
lock
,unlock
, andtryLock
. -
TimedMutex: A timed variant that supports timed operations including
tryLockFor
andtryLockUntil
. -
RecursiveMutex: Allows multiple locks from the same agent.
-
RecursiveTimedMutex: A timed variant that supports timed operations.
-
SharedMutex: Allows multiple readers or exclusive writer access, facilitating reader-writer scenarios.
-
SharedTimedMutex: A timed variant that supports timed operations.
-
lock(): Sequentially acquires the given locks. If any lock fails, the process is stopped, and any acquired locks are released in reverse order.
-
lockGuard[Sync](): Locks a mutex before calling a callback function, ensuring the mutex is unlocked afterwards.
-
MultiLock: Wraps multiple
BasicLockable
objects to create a multi-lock. Calls tolock
,unlock
, etc will acquire / release locks on all of the wrapped objects. -
SharedLock: Wraps a
SharedLockable
object (e.g.SharedMutex
) to create a shared lock. Calls tolock
,unlock
, etc will acquire / release a shared lock instead of an exclusive lock. -
tryLock(): Tries to sequentially acquire the given locks. If any lock fails, the process is stopped, and any acquired locks are released in reverse order.
-
UniqueLock: Wraps a
BasicLockable
object to create a unique lock. Calls tolock
,unlock
, etc will acquire / release a lock on the wrapped object.
-
callOnce(): Executes a callback function at most once, based on the state of a provided
OnceFlag
. -
OnceFlag: Represents a flag that can be set exactly once, shared across different execution agents.
- ConditionVariable: Allows agents to wait for specific conditions, tightly integrated with mutexes for state management.
- CountingSemaphore: Manages access to a finite number of resources, allowing multiple entities to hold the semaphore concurrently up to a maximum count.
- Latch: Allows agents to wait until a set of operations has been completed. Ideal for scenarios where multiple tasks must reach a common point before proceeding. For example, the completion of multiple data loading operations before data processing begins.
-
LockError: A generic error related to errors in lock acquisition, release and management.
-
MultiLockError: Occurs when attempting to acquire multiple locks simultaneously.
-
MultiUnlockError: Occurs when attempting multiple unlocks simultaneously.
-
OwnershipError: Occurs when attempting to unlock an unacquired mutex.
-
RelockError: Occurs when attempting to lock an already acquired mutex. Prevents deadlocks from occurring.
-
TimeoutError: Occurs when an operation exceeds a set time, such as when using
tryLockFor
ortryLockUntil
.
Browser security requirements for using shared memory must be met. Please see SharedArrayBuffer > Security Requirements for details.
The use of synchronous methods (e.g. lockSync
) may not be allowed on the main thread. If not, their async versions (e.g. lock
) are available.
Contributions are welcome!
-
Bug Reports: Please use the GitHub issue tracker to report any bugs. Include a detailed description and any relevant code snippets or logs.
-
Feature Requests: Please submit feature requests as issues, clearly describing the feature and its potential benefits.
-
Pull Requests: Please ensure your code adheres to the existing style of the project and include any necessary tests and documentation.
For more information, check out the contributor's guide.