Skip to content

Commit 16567c8

Browse files
0xrinegadeclaude
andcommitted
feat(ovsm): Add sleep function and fix tight loop issue
Problem: WebSocket streaming script hit 10M iteration limit - Tight while loop without delay - stream-poll returns instantly when buffer empty - Loop spins millions of times per second Solution: Add sleep(milliseconds) function - Pauses execution for specified milliseconds - Uses std::thread::sleep internally - Update stream script to sleep 100ms between polls Script changes: - Restore 60 second duration (was reduced to 10) - Add sleep(100) in poll loop - Add poll-count stat to show polling frequency - Now ~600 polls in 60 seconds (1 every 100ms) Benefits: - No more iteration limit errors - CPU friendly (no busy-wait spinning) - Still responsive (100ms latency acceptable) - WebSocket events buffered while sleeping 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent d417d6e commit 16567c8

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

crates/ovsm/src/runtime/lisp_evaluator.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ impl LispEvaluator {
320320
"clamp" => self.eval_clamp(args), // Clamp between min/max
321321
"random" => self.eval_random(args), // Random number
322322
"now" => self.eval_now(args),
323+
"sleep" => self.eval_sleep(args),
323324
"log" => self.eval_log(args),
324325
"print" => self.eval_print(args), // Python/JS-style output
325326
"println" => self.eval_println(args), // Python/JS-style output with newline
@@ -4016,6 +4017,31 @@ impl LispEvaluator {
40164017
Ok(Value::Int(timestamp as i64))
40174018
}
40184019

4020+
/// (sleep milliseconds) - Sleep for specified milliseconds
4021+
fn eval_sleep(&mut self, args: &[crate::parser::Argument]) -> Result<Value> {
4022+
if args.len() != 1 {
4023+
return Err(Error::InvalidArguments {
4024+
tool: "sleep".to_string(),
4025+
reason: format!("Expected 1 argument, got {}", args.len()),
4026+
});
4027+
}
4028+
4029+
let val = self.evaluate_expression(&args[0].value)?;
4030+
let ms = match val {
4031+
Value::Int(i) => i as u64,
4032+
Value::Float(f) => f as u64,
4033+
_ => {
4034+
return Err(Error::TypeError {
4035+
expected: "number".to_string(),
4036+
got: val.type_name().to_string(),
4037+
})
4038+
}
4039+
};
4040+
4041+
std::thread::sleep(std::time::Duration::from_millis(ms));
4042+
Ok(Value::Null)
4043+
}
4044+
40194045
/// (base58-encode string) - Encode string to base58
40204046
fn eval_base58_encode(&mut self, args: &[crate::parser::Argument]) -> Result<Value> {
40214047
if args.len() != 1 {

examples/ovsm_scripts/stream_pumpfun.ovsm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,17 @@
2727
(define graduation-count 0)
2828
(define transfer-count 0)
2929

30-
;; Main event loop (60 seconds)
30+
;; Main event loop (60 seconds with sleep to avoid spinning CPU)
3131
(define start-time (now))
3232
(define duration 60)
33+
(define poll-count 0)
3334

3435
(while (< (- (now) start-time) duration)
3536
(define events (stream-poll stream-id :limit 50))
37+
(set! poll-count (+ poll-count 1))
38+
39+
;; Sleep 100ms between polls to avoid tight loop
40+
(sleep 100)
3641

3742
(for (event events)
3843
(define event-type (get event "type"))
@@ -128,6 +133,7 @@
128133
(println " FORENSICS SUMMARY")
129134
(println "═══════════════════════════════════════════════════════════════")
130135
(println (str "Duration: " duration " seconds"))
136+
(println (str "Poll Count: " poll-count " polls"))
131137
(println (str "Buy Txs: " buy-count))
132138
(println (str "Sell Txs: " sell-count))
133139
(println (str "Token Transfers: " transfer-count))

0 commit comments

Comments
 (0)