Skip to content

Conversation

@cheesycod
Copy link
Contributor

@cheesycod cheesycod commented Dec 31, 2025

Summary by CodeRabbit

  • New Features

    • Added a delay queue with async retrieval and cancellable handles for scheduled items.
  • Improvements

    • Task execution now runs via the async scheduler.
    • Runtime state now uses structured JSON-like data.
  • Chores

    • Added a timing utility dependency.
  • Tests

    • Added a Lua test demonstrating delayed enqueue and retrieval.
  • Breaking Changes

    • Key-value expiry support removed; public state shape changed (flags → data).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 31, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Replaces sync CLI chunk execution with scheduler-await, migrates TenantState flags: u32data: serde_json::Value, removes KV expiry fields/methods and related APIs, adds tokio-util dependency, implements a cancellable DelayChannel with async next() and KeyHandle, and adds TimeDelta constructors and a delay test.

Changes

Cohort / File(s) Summary
CLI async execution
crates/cli/src/cli.rs
Switches chunk execution from direct sync error path to awaiting rt.call_in_scheduler(chunk_fn, ctx).await.
TenantState migration
crates/cli/src/provider/mod.rs, crates/runtime/src/traits/ir/runtime.rs
Replaces exported TenantState field flags: u32 with data: serde_json::Value; updates FromLua/IntoLua, validation, defaults and adds MAX_EVENTS = 100.
Delay channel system
crates/runtime/src/core/channel.rs, delayqueuetest.luau
Adds DelayChannel, KeyHandle, QueueStream and DelayQueue integration; APIs: new(), add(), add_with_handle() -> KeyHandle, async next(); exposes Lua userdata and a demo test.
KV expiry removal & API changes
crates/runtime/src/plugins/antiraid/kv/mod.rs, crates/runtime/src/traits/ir/kv.rs, crates/runtime/src/traits/kvprovider.rs
Removes expires_at from KvRecord and trait methods; deletes set_expiry* methods and expiry handling; updates KVProvider::set/set_by_id signatures and adjusts KvExecutor::check to accept &str.
Datetime helpers
crates/runtime/src/core/datetime.rs
Adds TimeDelta::from_millis(i64) and TimeDelta::from_std(Duration) constructors.
Dependency
crates/runtime/Cargo.toml
Adds tokio-util = "0.7" with "time" feature.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Scheduler
    participant DelayChannel
    participant DelayQueue
    participant Timer

    Note over Client,Scheduler: Client schedules delayed insertion
    Client->>Scheduler: add(value, delay)
    Scheduler->>Timer: schedule timeout(delay)
    Timer-->>Scheduler: timeout fires
    Scheduler->>DelayChannel: enqueue expired item
    Note over Client,DelayChannel: consumer awaits next()
    Client->>DelayChannel: await next()
    DelayChannel->>DelayQueue: poll for expired items
    DelayQueue-->>DelayChannel: return expired value
    DelayChannel-->>Client: deliver value
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 I hopped through code and found a queue,

Timers ticked and messages flew,
Keys can cancel, waits set right,
Tenant data swapped clear and bright,
A rabbit cheers — async feels new!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.38% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: adding a DelayChannel primitive and introducing tenant state limits (MAX_EVENTS constant).

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb9625d and f964751.

📒 Files selected for processing (1)
  • crates/cli/src/provider/mod.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
crates/runtime/src/traits/ir/runtime.rs (1)

43-63: Consider simplifying the metatable validation logic.

The current structure with an empty if block for the success case is slightly awkward. A minor refactor could improve readability.

🔎 Suggested refactor
         // Ensure data is either a Object or Nil
         match data {
             LuaValue::Table(ref t) => {
-                if t.metatable().is_none() {
-                    // OK
-                } else {
+                if t.metatable().is_some() {
                     return Err(LuaError::FromLuaConversionError {
                         from: "table with metatable",
                         to: "TenantState".to_string(),
                         message: Some("data field must be an object/map with no metatable or nil".to_string()),
                     });
                 }
             },
             LuaValue::Nil => {}
delayqueuetest.luau (1)

4-9: Clarify the expected behavior in the test.

The test schedules task.delay(2, ...) which adds an item after 2 seconds, and then the item itself has a 2-second expiration delay via timedelta_seconds(2). This means next() will block for approximately 4 seconds total.

If the intent is to demonstrate the delay queue functionality, consider adding a comment explaining this expected behavior, or simplifying to a single delay for clarity.

crates/runtime/src/core/channel.rs (1)

114-126: Consider adding a maximum delay limit for consistency.

OneshotChannel::recvtimeout enforces a MAX_TIMEOUT of 7 seconds, but DelayChannel::add and add_with_handle accept arbitrary delays without validation. This inconsistency could allow very long delays. Consider whether a similar limit should apply here.

🔎 Suggested change if limit is desired
+const MAX_DELAY: Duration = Duration::from_secs(60); // or appropriate limit
+
     /// Inserts a value into the delay channel with the given delay
-    pub fn add(&self, value: LuaValue, delay: Duration) {
+    pub fn add(&self, value: LuaValue, delay: Duration) -> Result<(), &'static str> {
+        if delay > MAX_DELAY {
+            return Err("Delay cannot exceed maximum allowed duration");
+        }
         self.queue.borrow_mut().insert(value, delay);
         self.notify.notify_one();
+        Ok(())
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b97c5e5 and 98523bf.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • crates/cli/src/cli.rs
  • crates/cli/src/provider/mod.rs
  • crates/runtime/Cargo.toml
  • crates/runtime/src/core/channel.rs
  • crates/runtime/src/traits/ir/runtime.rs
  • delayqueuetest.luau
🧰 Additional context used
🧬 Code graph analysis (1)
crates/runtime/src/traits/ir/runtime.rs (1)
crates/cli/src/provider/mod.rs (16)
  • data (156-156)
  • data (161-161)
  • data (162-162)
  • data (164-164)
  • data (165-165)
  • data (166-166)
  • data (167-167)
  • data (194-194)
  • data (199-199)
  • data (200-200)
  • data (202-202)
  • data (203-203)
  • data (204-204)
  • data (205-205)
  • data (417-417)
  • data (422-422)
🔇 Additional comments (13)
crates/runtime/Cargo.toml (1)

14-14: LGTM!

The tokio-util dependency with the time feature is correctly added to support the new DelayQueue-based functionality in the channel module.

crates/runtime/src/traits/ir/runtime.rs (3)

5-6: LGTM!

The MAX_EVENTS constant provides a sensible upper bound to prevent runaway event accumulation.


29-37: LGTM!

The events length validation provides a good safeguard against application logic errors with a clear error message.


75-87: LGTM!

The IntoLua implementation correctly serializes the new data field using lua.to_value().

crates/cli/src/cli.rs (1)

216-220: LGTM!

The shift to call_in_scheduler aligns with the async scheduler-based execution model, properly awaiting the chunk execution.

crates/cli/src/provider/mod.rs (3)

786-791: LGTM!

The local TenantState struct is correctly updated to use data: serde_json::Value, aligning with the runtime layer changes.


805-820: LGTM!

The get_tenant_state implementation correctly maps the new data field and provides an appropriate default of serde_json::Value::Null.


822-830: LGTM!

The set_tenant_state correctly propagates the data field through serialization.

crates/runtime/src/core/channel.rs (5)

72-98: LGTM!

The KeyHandle implementation provides proper cancellation semantics with appropriate error handling when the queue has been dropped. The Eq metamethod correctly compares both the key and queue reference.


128-145: LGTM!

The next() implementation correctly uses biased in tokio::select! to prioritize draining expired items. The loop structure handles notification wakeups properly by recreating the stream wrapper.


148-165: LGTM!

The LuaUserData implementation correctly converts TimeDelta to std::time::Duration with proper error handling for invalid conversions.


167-180: LGTM!

The QueueStream wrapper correctly implements Stream by borrowing the RefCell only during poll_next, avoiding borrow conflicts with other operations.


189-191: LGTM!

The DelayChannel constructor is correctly exposed in init_plugin, making it available to Lua scripts.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/runtime/src/core/channel.rs (1)

148-169: Consider adding maximum delay validation for consistency.

The OneshotChannel validates that timeouts don't exceed MAX_TIMEOUT (7 seconds), but DelayChannel::add() and addwithhandle() accept any duration. This inconsistency could allow extremely long delays that may not be intended.

🔎 Proposed validation

Add validation in the Lua binding methods:

 methods.add_method("add", |_, this, (value, delay): (LuaValue, LuaUserDataRef<TimeDelta>)| {
     let delay = delay.timedelta.to_std().map_err(LuaError::external)?;
+    if delay > MAX_TIMEOUT {
+        return Err(LuaError::external("Delay cannot be greater than the max timeout"));
+    }
     Ok(this.add(value, delay))
 });

 methods.add_method("addwithhandle", |_, this, (value, delay): (LuaValue, LuaUserDataRef<TimeDelta>)| {
     let delay = delay.timedelta.to_std().map_err(LuaError::external)?;
+    if delay > MAX_TIMEOUT {
+        return Err(LuaError::external("Delay cannot be greater than the max timeout"));
+    }
     let handle = this.add_with_handle(value, delay);
     Ok(handle)
 });

Note: If longer delays are intentionally supported, consider documenting this difference or using a separate constant like MAX_DELAY.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98523bf and da7227b.

📒 Files selected for processing (1)
  • crates/runtime/src/core/channel.rs
🧰 Additional context used
🧬 Code graph analysis (1)
crates/runtime/src/core/channel.rs (1)
crates/runtime/src/core/datetime.rs (1)
  • from_secs (19-23)
🔇 Additional comments (6)
crates/runtime/src/core/channel.rs (6)

1-14: LGTM: Imports and type updates support the new DelayQueue implementation.

The new imports for Stream, DelayQueue, Notify, and related types are appropriate for the delay channel functionality. The MAX_TIMEOUT type change to Duration aligns with standard Rust async patterns.


16-70: LGTM: OneshotChannel enhanced to support selection patterns.

The addition of the rx field with Rc<RefCell<Option<...>>> wrapping properly enables the receiver to be shared and taken once, which is necessary for the selectoneshots functionality while maintaining correct ownership semantics.


72-98: LGTM: KeyHandle properly implements cancellation with safe borrowing.

The use of Weak reference prevents reference cycles, try_borrow_mut() handles potential borrow conflicts gracefully, and the Eq implementation correctly checks both key and queue identity.


128-145: LGTM: Correct async implementation with biased polling.

The loop-and-recreate pattern is appropriate here: recreating the QueueStream ensures fresh polling after notifications, and the biased select correctly prioritizes expired items over notifications to prevent starvation. The method will block indefinitely if the queue remains empty, which is standard behavior for channel primitives.


171-184: LGTM: Stream wrapper correctly limits borrow scope.

The QueueStream implementation properly constrains the mutable borrow to just the poll_expired() call. The explanatory comment confirms the brief borrow duration, which allows other operations to safely access the queue between polls.


186-238: LGTM: Module properly exposes DelayChannel to Lua.

The DelayChannel constructor is correctly registered, and the existing selectoneshots function properly integrates with the updated OneshotChannel structure.

Comment on lines 115 to 126
pub fn add(&self, value: LuaValue, delay: Duration) {
self.queue.borrow_mut().insert(value, delay);
self.notify.notify_one();
}

/// Inserts a value into the delay channel with the given delay
/// and returns a handle that can be used to cancel it
pub fn add_with_handle(&self, value: LuaValue, delay: Duration) -> KeyHandle {
let key = self.queue.borrow_mut().insert(value, delay);
self.notify.notify_one();
KeyHandle { key, queue: Rc::downgrade(&self.queue) }
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential panic risk: use try_borrow_mut() for defensive error handling.

The add() and add_with_handle() methods use borrow_mut() directly, which will panic if the RefCell is already borrowed (e.g., if another operation is accessing the queue concurrently). While the single-threaded Lua scheduler makes this rare, it's better to handle borrow conflicts gracefully, especially since KeyHandle::cancel() already uses the safer try_borrow_mut() pattern.

🔎 Suggested defensive fix
-pub fn add(&self, value: LuaValue, delay: Duration) {
-    self.queue.borrow_mut().insert(value, delay);
+pub fn add(&self, value: LuaValue, delay: Duration) -> LuaResult<()> {
+    self.queue.try_borrow_mut()
+        .map_err(|_| LuaError::external("Delay channel is currently being accessed"))?
+        .insert(value, delay);
     self.notify.notify_one();
+    Ok(())
 }

-pub fn add_with_handle(&self, value: LuaValue, delay: Duration) -> KeyHandle {
-    let key = self.queue.borrow_mut().insert(value, delay);
+pub fn add_with_handle(&self, value: LuaValue, delay: Duration) -> LuaResult<KeyHandle> {
+    let key = self.queue.try_borrow_mut()
+        .map_err(|_| LuaError::external("Delay channel is currently being accessed"))?
+        .insert(value, delay);
     self.notify.notify_one();
-    KeyHandle { key, queue: Rc::downgrade(&self.queue) }
+    Ok(KeyHandle { key, queue: Rc::downgrade(&self.queue) })
 }

Then update the Lua bindings (lines 150-159) to propagate the Result:

 methods.add_method("add", |_, this, (value, delay): (LuaValue, LuaUserDataRef<TimeDelta>)| {
     let delay = delay.timedelta.to_std().map_err(LuaError::external)?;
-    Ok(this.add(value, delay))
+    this.add(value, delay)
 });

 methods.add_method("addwithhandle", |_, this, (value, delay): (LuaValue, LuaUserDataRef<TimeDelta>)| {
     let delay = delay.timedelta.to_std().map_err(LuaError::external)?;
-    let handle = this.add_with_handle(value, delay);
-    Ok(handle)
+    this.add_with_handle(value, delay)
 });

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In crates/runtime/src/core/channel.rs around lines 115-126, replace the direct
RefCell::borrow_mut() calls with try_borrow_mut() to avoid panics: for add(),
attempt try_borrow_mut(), if Ok insert the value and notify, if Err return early
(or log a warning) without panicking; for add_with_handle() use try_borrow_mut()
and change the function signature to return a Result<KeyHandle, ChannelError>
(define a minimal ChannelError or use existing error type), on Ok construct and
return the KeyHandle, on Err return Err(ChannelError::BorrowFailed); then update
the Lua bindings (around lines 150-159) to propagate the Result instead of
assuming success so borrow failures surface to the caller.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
crates/runtime/src/core/channel.rs (2)

137-142: Borrow conflict can still cause panics in add_with_handle().

Similar to add(), Line 139 uses borrow_mut() which can panic on borrow conflicts. This should use try_borrow_mut() for consistency with KeyHandle::cancel().

🔎 Recommended fix
 pub fn add_with_handle(&self, value: LuaValue, delay: Duration) -> LuaResult<KeyHandle> {
     Self::check_delay(delay)?;
-    let key = self.queue.borrow_mut().insert(value, delay);
+    let key = self.queue.try_borrow_mut()
+        .map_err(|_| LuaError::external("Delay channel is currently being accessed"))?
+        .insert(value, delay);
     self.notify.notify_one();
     Ok(KeyHandle { key, queue: Rc::downgrade(&self.queue) })
 }

Based on learnings, past review comments indicated this should use defensive borrowing.


128-133: Borrow conflict can still cause panics in add().

The past review comment flagged that borrow_mut() on Line 130 can panic if the RefCell is already borrowed. While the method now returns LuaResult<()>, it still uses the panicking borrow_mut() instead of try_borrow_mut(). Although the single-threaded Lua scheduler makes this unlikely, the KeyHandle::cancel() already demonstrates the safer pattern with try_borrow_mut().

🔎 Recommended fix
 pub fn add(&self, value: LuaValue, delay: Duration) -> LuaResult<()> {
     Self::check_delay(delay)?;
-    self.queue.borrow_mut().insert(value, delay);
+    self.queue.try_borrow_mut()
+        .map_err(|_| LuaError::external("Delay channel is currently being accessed"))?
+        .insert(value, delay);
     self.notify.notify_one();
     Ok(())
 }

Based on learnings, past review comments indicated this should use defensive borrowing.

🧹 Nitpick comments (2)
crates/runtime/src/core/datetime.rs (1)

31-36: Consider simplifying the error propagation.

The explicit match with Err(e) => Err(e) can be replaced with the ? operator or map for more idiomatic Rust.

🔎 Proposed simplification
 pub const fn from_std(td: Duration) -> Result<TimeDelta, chrono::OutOfRangeError> {
-    match chrono::Duration::from_std(td) {
-        Ok(x) => Ok(TimeDelta { timedelta: x }),
-        Err(e) => Err(e)
-    }
+    Ok(TimeDelta { 
+        timedelta: chrono::Duration::from_std(td)?
+    })
 }
crates/runtime/src/core/channel.rs (1)

197-202: Consider defensive borrowing in poll_next().

Line 201 uses borrow_mut() which could panic if the queue is borrowed concurrently. While the borrow scope is tight and the async/await model makes this unlikely, using try_borrow_mut() would be more defensive and consistent with the KeyHandle::cancel() pattern.

🔎 Proposed defensive fix
 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
-    self.queue.borrow_mut().poll_expired(cx)
+    match self.queue.try_borrow_mut() {
+        Ok(mut queue) => queue.poll_expired(cx),
+        Err(_) => Poll::Pending, // Retry later if borrowed
+    }
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da7227b and 020512f.

📒 Files selected for processing (2)
  • crates/runtime/src/core/channel.rs
  • crates/runtime/src/core/datetime.rs
🔇 Additional comments (9)
crates/runtime/src/core/datetime.rs (2)

2-2: LGTM!

The Duration import is correctly added to support the new from_std constructor.


25-29: LGTM!

The from_millis constructor provides a convenient way to create TimeDelta from milliseconds and is correctly marked as const.

crates/runtime/src/core/channel.rs (7)

3-10: LGTM!

The new imports are necessary for the DelayChannel implementation and related types.


14-20: LGTM!

The constants define reasonable limits for the delay queue (~793 days max). The 5-second safety margin in MAX_DURATION_OBJ and MAX_DURATION_OBJ_STD provides a buffer against edge cases.


22-34: LGTM!

Adding the rx field to OneshotChannel enables the selectoneshots function to access receivers. The wrapping pattern is consistent with the existing tx field.


78-104: LGTM!

The KeyHandle implementation is well-designed:

  • Uses Weak reference to avoid cycles
  • Defensively uses try_borrow_mut() in cancel() to handle borrow conflicts gracefully
  • Properly checks if the queue is still alive before attempting cancellation

144-161: LGTM!

The next() method correctly uses tokio::select! with biased to prioritize expired items over notifications, ensuring efficient processing. Recreating the QueueStream wrapper in the loop is a reasonable approach.


164-188: LGTM!

The LuaUserData implementation for DelayChannel properly exposes the queue functionality to Lua. Good use of try_borrow() in the Len meta-method to avoid panics.


212-214: LGTM!

The DelayChannel constructor is correctly registered in the module, making it available to Lua code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/cli/src/provider/mod.rs (1)

318-377: Remove unused expires_at from SELECT statements.

The find method still includes expires_at in its SQL SELECT statements (lines 326 and 340), but this field has been systematically removed from all other KV operations in this file. The constructed KvRecord objects (lines 362-371) don't use expires_at, confirming it's unused.

This inconsistency will cause a SQL error if the expires_at column has been dropped from the kv_v2 table, or waste resources if it still exists.

🔎 Proposed fix
         let entries = if query == "%%" {
             // Fast path for querying all keys
             sqlx::query(
-                "SELECT id, key, value, created_at, last_updated_at, scopes, expires_at
+                "SELECT id, key, value, created_at, last_updated_at, scopes
                 FROM kv_v2
                 WHERE 
                 guild_id = $1 
                 AND scopes @> $2
             ",
             )
             .bind(self.guild_id.to_string())
             .bind(scopes)
             .fetch_all(&self.pool)
             .await
             .map_err(|e| format!("Failed to get key: {e}"))?
         } else {
             sqlx::query(
-                "SELECT id, key, value, created_at, last_updated_at, scopes, expires_at
+                "SELECT id, key, value, created_at, last_updated_at, scopes
                 FROM kv_v2
                 WHERE 
                 guild_id = $1 
                 AND key ILIKE $2
                 AND scopes @> $3
             ",
             )
             .bind(self.guild_id.to_string())
             .bind(query)
             .bind(scopes)
             .fetch_all(&self.pool)
             .await
             .map_err(|e| format!("Failed to get key: {e}"))?
         };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 020512f and bb9625d.

📒 Files selected for processing (4)
  • crates/cli/src/provider/mod.rs
  • crates/runtime/src/plugins/antiraid/kv/mod.rs
  • crates/runtime/src/traits/ir/kv.rs
  • crates/runtime/src/traits/kvprovider.rs
💤 Files with no reviewable changes (2)
  • crates/runtime/src/traits/ir/kv.rs
  • crates/runtime/src/traits/kvprovider.rs
🧰 Additional context used
🧬 Code graph analysis (1)
crates/runtime/src/plugins/antiraid/kv/mod.rs (1)
crates/runtime/src/traits/kvprovider.rs (1)
  • exists (23-23)
🔇 Additional comments (4)
crates/cli/src/provider/mod.rs (2)

745-770: LGTM!

The tenant state methods have been correctly updated to use the data field with serde_json::Value::Null as the default. The serialization and deserialization logic properly maps between the local and runtime TenantState representations.


725-732: Breaking change from flags: u32 to data: serde_json::Value has been properly implemented across all code paths.

Verification confirms that all TenantState usages—including serialization in get_tenant_state (lines 750-752), deserialization in set_tenant_state (lines 764-766), and Lua interop in both FromLua and IntoLua implementations—correctly use the new data field. No references to the old flags field remain.

crates/runtime/src/plugins/antiraid/kv/mod.rs (2)

148-190: LGTM! Good performance improvement.

Changing the action and key parameters from String to &str reduces unnecessary allocations and is more idiomatic for read-only string parameters. The change is applied consistently throughout the method.


376-404: LGTM! Expiry removal is clean.

The removal of expiry parameters from the set method is consistent with the broader changes to eliminate expires_at handling from the KV system. The simplified method signature is cleaner and easier to use.

@cheesycod cheesycod merged commit ee2e48b into master Jan 1, 2026
1 check was pending
@coderabbitai coderabbitai bot mentioned this pull request Jan 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants