API: State
ChatSDK::State::Base is the abstract interface for thread subscriptions, distributed locks, and key-value storage.
ChatSDK::State::Base is the abstract base class for state backends. It provides the interface for thread subscriptions, distributed locks, and key-value storage. The SDK ships with State::Memory for development/testing; production deployments typically use State::Redis, State::Pg, or State::Mysql.
State::Base
All methods raise NotImplementedError and must be implemented by concrete backends.
Thread Subscriptions
subscribe(thread_id)
Marks a thread as subscribed. Messages in subscribed threads trigger the on_subscribed_message handler.
state.subscribe("slack:C123:T456")| Parameter | Type | Required | Description |
|---|---|---|---|
thread_id | String | Yes | Thread state key |
unsubscribe(thread_id)
Removes a thread subscription.
state.unsubscribe("slack:C123:T456")| Parameter | Type | Required | Description |
|---|---|---|---|
thread_id | String | Yes | Thread state key |
subscribed?(thread_id)
Returns true if the thread is currently subscribed.
state.subscribed?("slack:C123:T456") # => true / false| Parameter | Type | Required | Description |
|---|---|---|---|
thread_id | String | Yes | Thread state key |
Distributed Locks
acquire_lock(key, owner:, ttl:)
Attempts to acquire an exclusive lock. Returns true if the lock was acquired, false if it is already held.
state.acquire_lock("handler:C123:T456", owner: "worker-1", ttl: 30)
# => true| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Lock key |
owner | String | Yes | Lock owner identifier |
ttl | Numeric | Yes | Time-to-live in seconds |
release_lock(key, owner:)
Releases a lock held by the given owner. Returns true if released, false if the lock is not held by this owner.
state.release_lock("handler:C123:T456", owner: "worker-1")
# => true| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Lock key |
owner | String | Yes | Lock owner identifier |
force_lock(key, owner:, ttl:)
Acquires a lock unconditionally, overriding any existing holder. Always returns true.
state.force_lock("handler:C123:T456", owner: "worker-2", ttl: 30)
# => true| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Lock key |
owner | String | Yes | Lock owner identifier |
ttl | Numeric | Yes | Time-to-live in seconds |
Key-Value Store
get(key)
Returns the stored value, or nil if the key does not exist or has expired.
state.get("myapp:counter") # => 42 or nil| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Storage key |
set(key, value, ttl: nil)
Stores a value. Optionally sets a TTL in seconds.
state.set("myapp:counter", 42, ttl: 3600)| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
key | String | Yes | -- | Storage key |
value | any | Yes | -- | Value to store |
ttl | Numeric | No | nil | Time-to-live in seconds. nil means no expiration. |
delete(key)
Deletes a key and its associated expiration and lock data.
state.delete("myapp:counter")| Parameter | Type | Required | Description |
|---|---|---|---|
key | String | Yes | Storage key |
set_if_absent(key, value, ttl: nil)
Stores a value only if the key does not already exist (or has expired). Returns true if set, false if the key already exists.
state.set_if_absent("myapp:initialized", true, ttl: 600)
# => true (first call)
# => false (subsequent calls within TTL)| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
key | String | Yes | -- | Storage key |
value | any | Yes | -- | Value to store |
ttl | Numeric | No | nil | Time-to-live in seconds |
State::Memory
ChatSDK::State::Memory is the built-in in-memory implementation of State::Base. It is suitable for development, testing, and single-process deployments.
state = ChatSDK::State::Memory.newAll operations are thread-safe via a Mutex. In addition to the base interface, State::Memory provides:
clear
Resets all stored data, subscriptions, and locks.
state.clear