Commit eb14ad4
feat(ovsm): Rename async-call to async with awaitable handles (V6.1)
Implements async/await pattern for OVSM, enabling both fire-and-forget
and result collection from concurrent tasks.
## What Changed
**Breaking Change: Renamed `async-call` → `async`**
- Returns `AsyncHandle` instead of null
- Handle can be awaited for result or ignored for fire-and-forget
- Cleaner, more idiomatic naming
**New Function: `await`**
- Syntax: `(await async-handle)`
- Blocks until async task completes
- Returns task result
- Can only be called once per handle (receiver consumed)
**New Value Type: `AsyncHandle`**
- Contains task ID and oneshot receiver
- Supports type introspection ("async-handle")
- JSON serializable
- Equality by ID
## Implementation Details
**AsyncHandle Structure:**
```rust
AsyncHandle {
id: String, // Unique task ID
receiver: Arc<Mutex<Option<Receiver<Value>>>>, // Result channel
}
```
**Await Mechanism:**
- Uses `try_recv()` polling (100μs sleep between attempts)
- Avoids `blocking_recv()` which panics inside tokio runtime
- Low CPU usage, fast response time
- Returns error if handle already awaited or task panicked
**PartialEq Implementation:**
- Manually implemented (Receiver doesn't support PartialEq)
- AsyncHandles compared by ID
- Functions/Macros compared by Arc pointer equality
## Example Usage
**Fire-and-forget (backward compatible):**
```lisp
(async println "Background task") ; Ignore handle
```
**Await result:**
```lisp
(define handle (async factorial 10))
(define result (await handle))
(println result) ; → 3628800
```
**Concurrent batch processing:**
```lisp
(define handles
(map [1 2 3 4 5] (lambda (n) (async square n))))
(define results [])
(for (h handles)
(set! results (append results [(await h)])))
(println results) ; → [1, 4, 9, 16, 25]
```
## Testing
All 7 test cases passing:
✅ Test 1: Basic async/await
✅ Test 2: Concurrent execution with result collection
✅ Test 3: Fire-and-forget
✅ Test 4: Factorial computation
✅ Test 5: Batch processing with map
✅ Test 6: Type introspection
✅ Test 7: Different return value types
## Files Modified
**Core Implementation (3 files):**
- `crates/ovsm/src/runtime/value.rs`: AsyncHandle type, manual PartialEq
- `crates/ovsm/src/runtime/streaming.rs`: async_execute(), await_async()
- `crates/ovsm/src/runtime/lisp_evaluator.rs`: eval_async(), eval_await()
**Pattern Matching (6 files):**
- `crates/ovsm/src/tools/stdlib/introspection.rs`: DESCRIBE, INSPECT, CLASS-OF
- `crates/ovsm/src/tools/stdlib/strings.rs`: FORMAT
- `crates/ovsm/src/tools/stdlib/utilities.rs`: type checking
- `src/services/ovsm_service.rs`: format_value, JSON serialization
- `src/utils/rpc_bridge.rs`: JSON serialization
- `src/utils/streaming_agent.rs`: formatting, JSON serialization
## Known Limitations
1. **`await` is a special form**, can't be passed to `map`:
```lisp
;; ❌ This doesn't work:
(map handles await)
;; ✅ Use for loop instead:
(for (h handles) (await h))
```
2. **Polling overhead**: 100μs sleep between polls
- Alternative would require non-tokio async runtime
- Current approach is simple and performant enough
## Migration from V6.0
**Before (V6.0):**
```lisp
(async-call process-event event) ; Returns null
```
**After (V6.1):**
```lisp
;; Fire-and-forget (same behavior):
(async process-event event) ; Returns handle, can be ignored
;; Or await result:
(define handle (async process-event event))
(define result (await handle))
```
## Performance
- No performance regression for fire-and-forget use case
- await adds <1ms overhead (100μs polling × ~10 iterations typical)
- Concurrent execution still utilizes all CPU cores
- Thread pool unchanged (num_cpus workers)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>1 parent 6188903 commit eb14ad4
File tree
9 files changed
+225
-48
lines changed- crates/ovsm/src
- runtime
- tools/stdlib
- src
- services
- utils
9 files changed
+225
-48
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
372 | 372 | | |
373 | 373 | | |
374 | 374 | | |
375 | | - | |
| 375 | + | |
| 376 | + | |
376 | 377 | | |
377 | 378 | | |
378 | 379 | | |
| |||
1688 | 1689 | | |
1689 | 1690 | | |
1690 | 1691 | | |
| 1692 | + | |
1691 | 1693 | | |
1692 | 1694 | | |
1693 | 1695 | | |
| |||
1772 | 1774 | | |
1773 | 1775 | | |
1774 | 1776 | | |
| 1777 | + | |
1775 | 1778 | | |
1776 | 1779 | | |
1777 | 1780 | | |
| |||
5941 | 5944 | | |
5942 | 5945 | | |
5943 | 5946 | | |
| 5947 | + | |
| 5948 | + | |
| 5949 | + | |
| 5950 | + | |
| 5951 | + | |
| 5952 | + | |
| 5953 | + | |
5944 | 5954 | | |
5945 | 5955 | | |
5946 | 5956 | | |
| |||
9126 | 9136 | | |
9127 | 9137 | | |
9128 | 9138 | | |
9129 | | - | |
| 9139 | + | |
9130 | 9140 | | |
9131 | | - | |
9132 | | - | |
| 9141 | + | |
| 9142 | + | |
9133 | 9143 | | |
9134 | | - | |
9135 | | - | |
9136 | | - | |
| 9144 | + | |
| 9145 | + | |
| 9146 | + | |
9137 | 9147 | | |
9138 | 9148 | | |
9139 | 9149 | | |
9140 | | - | |
9141 | | - | |
| 9150 | + | |
| 9151 | + | |
9142 | 9152 | | |
9143 | | - | |
9144 | | - | |
9145 | | - | |
| 9153 | + | |
| 9154 | + | |
| 9155 | + | |
| 9156 | + | |
| 9157 | + | |
| 9158 | + | |
| 9159 | + | |
| 9160 | + | |
9146 | 9161 | | |
9147 | | - | |
| 9162 | + | |
9148 | 9163 | | |
9149 | 9164 | | |
9150 | | - | |
| 9165 | + | |
9151 | 9166 | | |
9152 | 9167 | | |
9153 | 9168 | | |
| |||
9161 | 9176 | | |
9162 | 9177 | | |
9163 | 9178 | | |
9164 | | - | |
| 9179 | + | |
| 9180 | + | |
| 9181 | + | |
| 9182 | + | |
| 9183 | + | |
| 9184 | + | |
| 9185 | + | |
| 9186 | + | |
| 9187 | + | |
| 9188 | + | |
| 9189 | + | |
| 9190 | + | |
| 9191 | + | |
| 9192 | + | |
| 9193 | + | |
| 9194 | + | |
| 9195 | + | |
| 9196 | + | |
| 9197 | + | |
| 9198 | + | |
| 9199 | + | |
| 9200 | + | |
| 9201 | + | |
| 9202 | + | |
| 9203 | + | |
| 9204 | + | |
| 9205 | + | |
9165 | 9206 | | |
9166 | 9207 | | |
9167 | 9208 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
658 | 658 | | |
659 | 659 | | |
660 | 660 | | |
661 | | - | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
662 | 670 | | |
663 | | - | |
| 671 | + | |
664 | 672 | | |
665 | | - | |
666 | | - | |
| 673 | + | |
| 674 | + | |
667 | 675 | | |
668 | 676 | | |
669 | | - | |
670 | | - | |
671 | | - | |
672 | | - | |
673 | | - | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
674 | 682 | | |
675 | 683 | | |
676 | 684 | | |
677 | | - | |
678 | | - | |
| 685 | + | |
| 686 | + | |
679 | 687 | | |
680 | 688 | | |
681 | 689 | | |
682 | | - | |
683 | | - | |
684 | | - | |
685 | | - | |
686 | | - | |
687 | | - | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
688 | 697 | | |
689 | | - | |
690 | | - | |
691 | | - | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
692 | 703 | | |
693 | | - | |
| 704 | + | |
694 | 705 | | |
695 | 706 | | |
696 | 707 | | |
| |||
701 | 712 | | |
702 | 713 | | |
703 | 714 | | |
704 | | - | |
| 715 | + | |
705 | 716 | | |
706 | 717 | | |
707 | 718 | | |
708 | 719 | | |
709 | 720 | | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
710 | 725 | | |
711 | 726 | | |
712 | 727 | | |
| |||
716 | 731 | | |
717 | 732 | | |
718 | 733 | | |
719 | | - | |
720 | 734 | | |
721 | 735 | | |
722 | 736 | | |
| |||
732 | 746 | | |
733 | 747 | | |
734 | 748 | | |
735 | | - | |
736 | | - | |
737 | | - | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
738 | 752 | | |
739 | | - | |
740 | | - | |
| 753 | + | |
| 754 | + | |
741 | 755 | | |
742 | | - | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
743 | 760 | | |
744 | 761 | | |
745 | | - | |
746 | | - | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
747 | 767 | | |
748 | 768 | | |
749 | | - | |
| 769 | + | |
750 | 770 | | |
751 | 771 | | |
752 | 772 | | |
753 | 773 | | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
65 | 73 | | |
66 | 74 | | |
67 | 75 | | |
| |||
103 | 111 | | |
104 | 112 | | |
105 | 113 | | |
| 114 | + | |
106 | 115 | | |
107 | 116 | | |
108 | 117 | | |
| |||
123 | 132 | | |
124 | 133 | | |
125 | 134 | | |
| 135 | + | |
126 | 136 | | |
127 | 137 | | |
128 | 138 | | |
| |||
206 | 216 | | |
207 | 217 | | |
208 | 218 | | |
| 219 | + | |
209 | 220 | | |
210 | 221 | | |
211 | 222 | | |
| |||
340 | 351 | | |
341 | 352 | | |
342 | 353 | | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
343 | 381 | | |
344 | 382 | | |
345 | 383 | | |
| |||
0 commit comments