restate-sdk 0.14.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98226ceeedf91fa42bbafa435efad5ee72571bea81cd7684a3e8726efafc049d
4
- data.tar.gz: 87520432eed026201b420da367ecf89bb56d3ced49aa0de243ac6610f8cbd584
3
+ metadata.gz: 225624c7507997dff92b55064e95b9991183f8f568bee215b53e8f8d5a26bd4c
4
+ data.tar.gz: 00f16cae8ce1b3e2469aa55c60bfc8e41706589ee395a37972a300624e27f6c1
5
5
  SHA512:
6
- metadata.gz: babf39022a0c123d246623a174afa5af2f56a6e552f6de2299b74fbe8845a98396a12842a818e91fb04a707f6a26054c28dace700362a6bf9ea0b89fe958dcab
7
- data.tar.gz: 441dd64b8d55779837a3a819d9c30908fbfcff5c17c67db6f89dfd3906d4f7857e12347dcea860bb911c1ca3d617ab2292281a69a1124947e32740a04335948e
6
+ metadata.gz: 3dce3cb5a471d6b05a23459a42615704816a0b34b6fe72a8b9d3365f26223daca2f4837072ad1dca08127e17daa49f18b3ac306c7060756cd92da8f56960b139
7
+ data.tar.gz: 0374c779599422d0a5e09a59e5f1368901390917a0801c8ea5720c3fcf3195823331d17a919d79a87e485a57739e5a1c5f83635c155bb32d76ebf6a996c83657
data/Cargo.lock CHANGED
@@ -17,12 +17,6 @@ version = "1.0.102"
17
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
18
18
  checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
19
19
 
20
- [[package]]
21
- name = "autocfg"
22
- version = "1.5.0"
23
- source = "registry+https://github.com/rust-lang/crates.io-index"
24
- checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
25
-
26
20
  [[package]]
27
21
  name = "base64"
28
22
  version = "0.22.1"
@@ -38,7 +32,7 @@ dependencies = [
38
32
  "bitflags",
39
33
  "cexpr",
40
34
  "clang-sys",
41
- "itertools 0.12.1",
35
+ "itertools",
42
36
  "proc-macro2",
43
37
  "quote",
44
38
  "regex",
@@ -55,11 +49,11 @@ checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
55
49
 
56
50
  [[package]]
57
51
  name = "block-buffer"
58
- version = "0.11.0-pre.5"
52
+ version = "0.12.0"
59
53
  source = "registry+https://github.com/rust-lang/crates.io-index"
60
- checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e"
54
+ checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be"
61
55
  dependencies = [
62
- "crypto-common",
56
+ "hybrid-array",
63
57
  ]
64
58
 
65
59
  [[package]]
@@ -93,16 +87,6 @@ dependencies = [
93
87
  "either",
94
88
  ]
95
89
 
96
- [[package]]
97
- name = "cc"
98
- version = "1.2.56"
99
- source = "registry+https://github.com/rust-lang/crates.io-index"
100
- checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
101
- dependencies = [
102
- "find-msvc-tools",
103
- "shlex",
104
- ]
105
-
106
90
  [[package]]
107
91
  name = "cexpr"
108
92
  version = "0.6.0"
@@ -131,44 +115,33 @@ dependencies = [
131
115
 
132
116
  [[package]]
133
117
  name = "const-oid"
134
- version = "0.10.0-pre.2"
118
+ version = "0.10.2"
135
119
  source = "registry+https://github.com/rust-lang/crates.io-index"
136
- checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea"
120
+ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
137
121
 
138
122
  [[package]]
139
123
  name = "cpufeatures"
140
- version = "0.2.17"
124
+ version = "0.3.0"
141
125
  source = "registry+https://github.com/rust-lang/crates.io-index"
142
- checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
126
+ checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
143
127
  dependencies = [
144
128
  "libc",
145
129
  ]
146
130
 
147
131
  [[package]]
148
132
  name = "crypto-common"
149
- version = "0.2.0-pre.5"
133
+ version = "0.2.2"
150
134
  source = "registry+https://github.com/rust-lang/crates.io-index"
151
- checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e"
135
+ checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
152
136
  dependencies = [
153
- "getrandom",
154
137
  "hybrid-array",
155
- "rand_core",
156
- ]
157
-
158
- [[package]]
159
- name = "deranged"
160
- version = "0.5.8"
161
- source = "registry+https://github.com/rust-lang/crates.io-index"
162
- checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
163
- dependencies = [
164
- "powerfmt",
165
138
  ]
166
139
 
167
140
  [[package]]
168
141
  name = "digest"
169
- version = "0.11.0-pre.8"
142
+ version = "0.11.3"
170
143
  source = "registry+https://github.com/rust-lang/crates.io-index"
171
- checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25"
144
+ checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
172
145
  dependencies = [
173
146
  "block-buffer",
174
147
  "const-oid",
@@ -181,12 +154,6 @@ version = "1.15.0"
181
154
  source = "registry+https://github.com/rust-lang/crates.io-index"
182
155
  checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
183
156
 
184
- [[package]]
185
- name = "find-msvc-tools"
186
- version = "0.1.9"
187
- source = "registry+https://github.com/rust-lang/crates.io-index"
188
- checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
189
-
190
157
  [[package]]
191
158
  name = "getrandom"
192
159
  version = "0.2.17"
@@ -194,10 +161,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
194
161
  checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
195
162
  dependencies = [
196
163
  "cfg-if",
197
- "js-sys",
198
164
  "libc",
199
165
  "wasi",
200
- "wasm-bindgen",
201
166
  ]
202
167
 
203
168
  [[package]]
@@ -214,9 +179,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
214
179
 
215
180
  [[package]]
216
181
  name = "hybrid-array"
217
- version = "0.2.3"
182
+ version = "0.4.12"
218
183
  source = "registry+https://github.com/rust-lang/crates.io-index"
219
- checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9"
184
+ checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
220
185
  dependencies = [
221
186
  "typenum",
222
187
  ]
@@ -230,15 +195,6 @@ dependencies = [
230
195
  "either",
231
196
  ]
232
197
 
233
- [[package]]
234
- name = "itertools"
235
- version = "0.14.0"
236
- source = "registry+https://github.com/rust-lang/crates.io-index"
237
- checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
238
- dependencies = [
239
- "either",
240
- ]
241
-
242
198
  [[package]]
243
199
  name = "itoa"
244
200
  version = "1.0.17"
@@ -257,17 +213,17 @@ dependencies = [
257
213
 
258
214
  [[package]]
259
215
  name = "jsonwebtoken"
260
- version = "9.3.1"
216
+ version = "10.4.0"
261
217
  source = "registry+https://github.com/rust-lang/crates.io-index"
262
- checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
218
+ checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc"
263
219
  dependencies = [
264
220
  "base64",
221
+ "getrandom",
265
222
  "js-sys",
266
- "pem",
267
- "ring",
268
223
  "serde",
269
224
  "serde_json",
270
- "simple_asn1",
225
+ "signature",
226
+ "zeroize",
271
227
  ]
272
228
 
273
229
  [[package]]
@@ -358,41 +314,7 @@ version = "0.50.3"
358
314
  source = "registry+https://github.com/rust-lang/crates.io-index"
359
315
  checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
360
316
  dependencies = [
361
- "windows-sys 0.61.2",
362
- ]
363
-
364
- [[package]]
365
- name = "num-bigint"
366
- version = "0.4.6"
367
- source = "registry+https://github.com/rust-lang/crates.io-index"
368
- checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
369
- dependencies = [
370
- "num-integer",
371
- "num-traits",
372
- ]
373
-
374
- [[package]]
375
- name = "num-conv"
376
- version = "0.2.0"
377
- source = "registry+https://github.com/rust-lang/crates.io-index"
378
- checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
379
-
380
- [[package]]
381
- name = "num-integer"
382
- version = "0.1.46"
383
- source = "registry+https://github.com/rust-lang/crates.io-index"
384
- checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
385
- dependencies = [
386
- "num-traits",
387
- ]
388
-
389
- [[package]]
390
- name = "num-traits"
391
- version = "0.2.19"
392
- source = "registry+https://github.com/rust-lang/crates.io-index"
393
- checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
394
- dependencies = [
395
- "autocfg",
317
+ "windows-sys",
396
318
  ]
397
319
 
398
320
  [[package]]
@@ -402,20 +324,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
402
324
  checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
403
325
 
404
326
  [[package]]
405
- name = "paste"
406
- version = "1.0.15"
407
- source = "registry+https://github.com/rust-lang/crates.io-index"
408
- checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
409
-
410
- [[package]]
411
- name = "pem"
412
- version = "3.0.6"
327
+ name = "pastey"
328
+ version = "0.2.3"
413
329
  source = "registry+https://github.com/rust-lang/crates.io-index"
414
- checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
415
- dependencies = [
416
- "base64",
417
- "serde_core",
418
- ]
330
+ checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4"
419
331
 
420
332
  [[package]]
421
333
  name = "pin-project-lite"
@@ -423,12 +335,6 @@ version = "0.2.17"
423
335
  source = "registry+https://github.com/rust-lang/crates.io-index"
424
336
  checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
425
337
 
426
- [[package]]
427
- name = "powerfmt"
428
- version = "0.2.0"
429
- source = "registry+https://github.com/rust-lang/crates.io-index"
430
- checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
431
-
432
338
  [[package]]
433
339
  name = "proc-macro2"
434
340
  version = "1.0.106"
@@ -440,9 +346,9 @@ dependencies = [
440
346
 
441
347
  [[package]]
442
348
  name = "prost"
443
- version = "0.13.5"
349
+ version = "0.14.3"
444
350
  source = "registry+https://github.com/rust-lang/crates.io-index"
445
- checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
351
+ checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
446
352
  dependencies = [
447
353
  "bytes",
448
354
  "prost-derive",
@@ -450,12 +356,12 @@ dependencies = [
450
356
 
451
357
  [[package]]
452
358
  name = "prost-derive"
453
- version = "0.13.5"
359
+ version = "0.14.3"
454
360
  source = "registry+https://github.com/rust-lang/crates.io-index"
455
- checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
361
+ checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
456
362
  dependencies = [
457
363
  "anyhow",
458
- "itertools 0.14.0",
364
+ "itertools",
459
365
  "proc-macro2",
460
366
  "quote",
461
367
  "syn",
@@ -540,18 +446,17 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
540
446
 
541
447
  [[package]]
542
448
  name = "restate-sdk-shared-core"
543
- version = "0.7.0"
449
+ version = "7.0.0"
544
450
  source = "registry+https://github.com/rust-lang/crates.io-index"
545
- checksum = "dc31df792d23376df8d3a6d4264ec3ce658bf68f0ec5296da43de8377c9352aa"
451
+ checksum = "9bf02583379fc28d6386bd864629ba6553ce942124956b862fa9e95a4d836558"
546
452
  dependencies = [
547
453
  "base64",
548
454
  "bs58",
549
455
  "bytes",
550
456
  "bytes-utils",
551
457
  "jsonwebtoken",
552
- "paste",
458
+ "pastey",
553
459
  "prost",
554
- "ring",
555
460
  "serde",
556
461
  "sha2",
557
462
  "strum",
@@ -561,7 +466,7 @@ dependencies = [
561
466
 
562
467
  [[package]]
563
468
  name = "restate_internal"
564
- version = "0.14.0"
469
+ version = "1.0.0"
565
470
  dependencies = [
566
471
  "magnus",
567
472
  "rb-sys",
@@ -569,20 +474,6 @@ dependencies = [
569
474
  "tracing-subscriber",
570
475
  ]
571
476
 
572
- [[package]]
573
- name = "ring"
574
- version = "0.17.14"
575
- source = "registry+https://github.com/rust-lang/crates.io-index"
576
- checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
577
- dependencies = [
578
- "cc",
579
- "cfg-if",
580
- "getrandom",
581
- "libc",
582
- "untrusted",
583
- "windows-sys 0.52.0",
584
- ]
585
-
586
477
  [[package]]
587
478
  name = "rustc-hash"
588
479
  version = "2.1.2"
@@ -646,9 +537,9 @@ dependencies = [
646
537
 
647
538
  [[package]]
648
539
  name = "sha2"
649
- version = "0.11.0-pre.3"
540
+ version = "0.11.0"
650
541
  source = "registry+https://github.com/rust-lang/crates.io-index"
651
- checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6"
542
+ checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
652
543
  dependencies = [
653
544
  "cfg-if",
654
545
  "cpufeatures",
@@ -677,15 +568,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
677
568
  checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
678
569
 
679
570
  [[package]]
680
- name = "simple_asn1"
681
- version = "0.6.4"
571
+ name = "signature"
572
+ version = "2.2.0"
682
573
  source = "registry+https://github.com/rust-lang/crates.io-index"
683
- checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d"
574
+ checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
684
575
  dependencies = [
685
- "num-bigint",
686
- "num-traits",
687
- "thiserror",
688
- "time",
576
+ "rand_core",
689
577
  ]
690
578
 
691
579
  [[package]]
@@ -755,37 +643,6 @@ dependencies = [
755
643
  "cfg-if",
756
644
  ]
757
645
 
758
- [[package]]
759
- name = "time"
760
- version = "0.3.47"
761
- source = "registry+https://github.com/rust-lang/crates.io-index"
762
- checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
763
- dependencies = [
764
- "deranged",
765
- "itoa",
766
- "num-conv",
767
- "powerfmt",
768
- "serde_core",
769
- "time-core",
770
- "time-macros",
771
- ]
772
-
773
- [[package]]
774
- name = "time-core"
775
- version = "0.1.8"
776
- source = "registry+https://github.com/rust-lang/crates.io-index"
777
- checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
778
-
779
- [[package]]
780
- name = "time-macros"
781
- version = "0.2.27"
782
- source = "registry+https://github.com/rust-lang/crates.io-index"
783
- checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
784
- dependencies = [
785
- "num-conv",
786
- "time-core",
787
- ]
788
-
789
646
  [[package]]
790
647
  name = "tinyvec"
791
648
  version = "1.10.0"
@@ -864,9 +721,9 @@ dependencies = [
864
721
 
865
722
  [[package]]
866
723
  name = "typenum"
867
- version = "1.19.0"
724
+ version = "1.20.0"
868
725
  source = "registry+https://github.com/rust-lang/crates.io-index"
869
- checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
726
+ checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
870
727
 
871
728
  [[package]]
872
729
  name = "unicode-ident"
@@ -874,12 +731,6 @@ version = "1.0.24"
874
731
  source = "registry+https://github.com/rust-lang/crates.io-index"
875
732
  checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
876
733
 
877
- [[package]]
878
- name = "untrusted"
879
- version = "0.9.0"
880
- source = "registry+https://github.com/rust-lang/crates.io-index"
881
- checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
882
-
883
734
  [[package]]
884
735
  name = "valuable"
885
736
  version = "0.1.1"
@@ -943,15 +794,6 @@ version = "0.2.1"
943
794
  source = "registry+https://github.com/rust-lang/crates.io-index"
944
795
  checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
945
796
 
946
- [[package]]
947
- name = "windows-sys"
948
- version = "0.52.0"
949
- source = "registry+https://github.com/rust-lang/crates.io-index"
950
- checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
951
- dependencies = [
952
- "windows-targets",
953
- ]
954
-
955
797
  [[package]]
956
798
  name = "windows-sys"
957
799
  version = "0.61.2"
@@ -962,68 +804,24 @@ dependencies = [
962
804
  ]
963
805
 
964
806
  [[package]]
965
- name = "windows-targets"
966
- version = "0.52.6"
807
+ name = "zeroize"
808
+ version = "1.8.2"
967
809
  source = "registry+https://github.com/rust-lang/crates.io-index"
968
- checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
810
+ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
969
811
  dependencies = [
970
- "windows_aarch64_gnullvm",
971
- "windows_aarch64_msvc",
972
- "windows_i686_gnu",
973
- "windows_i686_gnullvm",
974
- "windows_i686_msvc",
975
- "windows_x86_64_gnu",
976
- "windows_x86_64_gnullvm",
977
- "windows_x86_64_msvc",
812
+ "zeroize_derive",
978
813
  ]
979
814
 
980
815
  [[package]]
981
- name = "windows_aarch64_gnullvm"
982
- version = "0.52.6"
983
- source = "registry+https://github.com/rust-lang/crates.io-index"
984
- checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
985
-
986
- [[package]]
987
- name = "windows_aarch64_msvc"
988
- version = "0.52.6"
816
+ name = "zeroize_derive"
817
+ version = "1.4.3"
989
818
  source = "registry+https://github.com/rust-lang/crates.io-index"
990
- checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
991
-
992
- [[package]]
993
- name = "windows_i686_gnu"
994
- version = "0.52.6"
995
- source = "registry+https://github.com/rust-lang/crates.io-index"
996
- checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
997
-
998
- [[package]]
999
- name = "windows_i686_gnullvm"
1000
- version = "0.52.6"
1001
- source = "registry+https://github.com/rust-lang/crates.io-index"
1002
- checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1003
-
1004
- [[package]]
1005
- name = "windows_i686_msvc"
1006
- version = "0.52.6"
1007
- source = "registry+https://github.com/rust-lang/crates.io-index"
1008
- checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1009
-
1010
- [[package]]
1011
- name = "windows_x86_64_gnu"
1012
- version = "0.52.6"
1013
- source = "registry+https://github.com/rust-lang/crates.io-index"
1014
- checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1015
-
1016
- [[package]]
1017
- name = "windows_x86_64_gnullvm"
1018
- version = "0.52.6"
1019
- source = "registry+https://github.com/rust-lang/crates.io-index"
1020
- checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1021
-
1022
- [[package]]
1023
- name = "windows_x86_64_msvc"
1024
- version = "0.52.6"
1025
- source = "registry+https://github.com/rust-lang/crates.io-index"
1026
- checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
819
+ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
820
+ dependencies = [
821
+ "proc-macro2",
822
+ "quote",
823
+ "syn",
824
+ ]
1027
825
 
1028
826
  [[package]]
1029
827
  name = "zmij"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "restate_internal"
3
- version = "0.14.0"
3
+ version = "1.0.0"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
@@ -12,5 +12,5 @@ doc = false
12
12
  [dependencies]
13
13
  magnus = { version = "0.8", features = ["rb-sys"] }
14
14
  rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
15
- restate-sdk-shared-core = { version = "=0.7.0", features = ["request_identity", "sha2_random_seed"] }
15
+ restate-sdk-shared-core = { version = "7.0.0" , features = ["request_identity", "sha2_random_seed"] }
16
16
  tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] }
@@ -1,14 +1,13 @@
1
1
  use magnus::{
2
2
  function, method,
3
- prelude::*,
4
3
  value::ReprValue,
5
- Error, ExceptionClass, Module, Object, RArray, RString, Ruby, Value,
4
+ Error, ExceptionClass, Module, Object, RArray, RString, Ruby, Symbol, TryConvert, Value,
6
5
  };
7
6
  use restate_sdk_shared_core::{
8
- CallHandle, CoreVM, DoProgressResponse, Error as CoreError, Header, IdentityVerifier, Input,
9
- NonEmptyValue, NotificationHandle, ResponseHead, RetryPolicy, RunExitResult,
10
- TakeOutputResult, Target, TerminalFailure, VMOptions, Value as CoreValue, VM,
11
- CANCEL_NOTIFICATION_HANDLE,
7
+ AwaitResponse, CallHandle, CoreVM, Error as CoreError, Header, IdentityVerifier, Input,
8
+ NonEmptyValue, NotificationHandle, OnMaxAttempts, ResponseHead, RetryPolicy, RunExitResult,
9
+ RunHandle, State, Target, TerminalFailure, UnresolvedFuture, VMOptions, Value as CoreValue,
10
+ VM, CANCEL_NOTIFICATION_HANDLE,
12
11
  };
13
12
  use std::cell::RefCell;
14
13
  use std::fmt;
@@ -299,6 +298,7 @@ impl From<RbExponentialRetryConfig> for RetryPolicy {
299
298
  .max_interval
300
299
  .map(Duration::from_millis)
301
300
  .or_else(|| Some(Duration::from_secs(10))),
301
+ on_max_attempts: OnMaxAttempts::FailAsTerminal,
302
302
  }
303
303
  } else {
304
304
  RetryPolicy::Infinite
@@ -355,6 +355,30 @@ impl From<CallHandle> for RbCallHandle {
355
355
  }
356
356
  }
357
357
 
358
+ #[magnus::wrap(class = "Restate::Internal::Run")]
359
+ struct RbRun {
360
+ replayed: bool,
361
+ handle: u32,
362
+ }
363
+
364
+ impl RbRun {
365
+ fn replayed(&self) -> bool {
366
+ self.replayed
367
+ }
368
+ fn handle(&self) -> u32 {
369
+ self.handle
370
+ }
371
+ }
372
+
373
+ impl From<RunHandle> for RbRun {
374
+ fn from(r: RunHandle) -> Self {
375
+ RbRun {
376
+ replayed: r.replayed,
377
+ handle: r.handle.into(),
378
+ }
379
+ }
380
+ }
381
+
358
382
  // ── VM ──
359
383
 
360
384
  #[magnus::wrap(class = "Restate::Internal::VM")]
@@ -418,10 +442,8 @@ impl RbVM {
418
442
 
419
443
  fn take_output(&self) -> Result<Value, Error> {
420
444
  let ruby = Ruby::get().map_err(|_| Error::new(vm_error_class(), "Ruby not available"))?;
421
- Ok(match self.vm.borrow_mut().take_output() {
422
- TakeOutputResult::Buffer(b) => ruby.str_from_slice(&b).as_value(),
423
- TakeOutputResult::EOF => ruby.qnil().as_value(),
424
- })
445
+ let buffer = self.vm.borrow_mut().take_output();
446
+ Ok(ruby.str_from_slice(&buffer).as_value())
425
447
  }
426
448
 
427
449
  fn is_ready_to_execute(&self) -> Result<bool, Error> {
@@ -435,33 +457,39 @@ impl RbVM {
435
457
  self.vm.borrow().is_completed(handle.into())
436
458
  }
437
459
 
438
- fn do_progress(&self, handles: RArray) -> Result<Value, Error> {
460
+ // Drive the VM forward against an UnresolvedFuture tree. The Ruby-side
461
+ // encoding is:
462
+ // Integer handle → Single(handle)
463
+ // [:first_completed, [child, ...]] → race / wait_any
464
+ // [:all_completed, [child, ...]] → all_settled
465
+ // [:first_succeeded_or_all_failed,[child, ...]] → any
466
+ // [:all_succeeded_or_first_failed,[child, ...]] → all
467
+ // [:unknown, [child, ...]] → unknown combinator
468
+ fn do_await(&self, future_value: Value) -> Result<Value, Error> {
439
469
  let ruby = Ruby::get().map_err(|_| Error::new(vm_error_class(), "Ruby not available"))?;
440
- let handle_vec: Vec<u32> = handles.to_vec()?;
441
- let notification_handles: Vec<NotificationHandle> =
442
- handle_vec.into_iter().map(NotificationHandle::from).collect();
443
-
444
- let res = self.vm.borrow_mut().do_progress(notification_handles);
470
+ let future = parse_unresolved_future(future_value)?;
471
+ let res = self.vm.borrow_mut().do_await(future);
445
472
 
446
473
  match res {
447
474
  Err(e) if e.is_suspended_error() => Ok(ruby.into_value(RbSuspended)),
448
475
  Err(e) => Err(core_error_to_magnus(e)),
449
- Ok(DoProgressResponse::AnyCompleted) => {
476
+ Ok(AwaitResponse::AnyCompleted) => {
450
477
  Ok(ruby.into_value(RbDoProgressAnyCompleted))
451
478
  }
452
- Ok(DoProgressResponse::ReadFromInput) => {
453
- Ok(ruby.into_value(RbDoProgressReadFromInput))
454
- }
455
- Ok(DoProgressResponse::ExecuteRun(handle)) => Ok(ruby.into_value(
479
+ Ok(AwaitResponse::ExecuteRun(handle)) => Ok(ruby.into_value(
456
480
  RbDoProgressExecuteRun {
457
481
  handle: handle.into(),
458
482
  },
459
483
  )),
460
- Ok(DoProgressResponse::CancelSignalReceived) => {
484
+ Ok(AwaitResponse::CancelSignalReceived) => {
461
485
  Ok(ruby.into_value(RbDoProgressCancelSignalReceived))
462
486
  }
463
- Ok(DoProgressResponse::WaitingPendingRun) => {
464
- Ok(ruby.into_value(RbDoWaitForPendingRun))
487
+ Ok(AwaitResponse::WaitingExternalProgress { waiting_input, .. }) => {
488
+ if waiting_input {
489
+ Ok(ruby.into_value(RbDoProgressReadFromInput))
490
+ } else {
491
+ Ok(ruby.into_value(RbDoWaitForPendingRun))
492
+ }
465
493
  }
466
494
  }
467
495
  }
@@ -590,9 +618,12 @@ impl RbVM {
590
618
  handler,
591
619
  key: key_opt,
592
620
  idempotency_key: idem_opt,
621
+ scope: None,
622
+ limit_key: None,
593
623
  headers: hdr_vec,
594
624
  },
595
625
  bytes.into(),
626
+ None,
596
627
  Default::default(),
597
628
  )
598
629
  .map(Into::into)
@@ -639,6 +670,8 @@ impl RbVM {
639
670
  handler,
640
671
  key: key_opt,
641
672
  idempotency_key: idem_opt,
673
+ scope: None,
674
+ limit_key: None,
642
675
  headers: hdr_vec,
643
676
  },
644
677
  bytes.into(),
@@ -648,13 +681,14 @@ impl RbVM {
648
681
  .expect("Duration since unix epoch cannot fail")
649
682
  + Duration::from_millis(millis)
650
683
  }),
684
+ None,
651
685
  Default::default(),
652
686
  )
653
687
  .map(|s| s.invocation_id_notification_handle.into())
654
688
  .map_err(core_error_to_magnus)
655
689
  }
656
690
 
657
- fn sys_run(&self, name: String) -> Result<u32, Error> {
691
+ fn sys_run(&self, name: String) -> Result<RbRun, Error> {
658
692
  self.vm
659
693
  .borrow_mut()
660
694
  .sys_run(name)
@@ -727,21 +761,21 @@ impl RbVM {
727
761
  }
728
762
 
729
763
  fn is_replaying(&self) -> bool {
730
- self.vm.borrow().is_replaying()
764
+ matches!(self.vm.borrow().state(), State::Replaying)
731
765
  }
732
766
 
733
767
  // ── Awakeables ──
734
768
 
735
769
  fn sys_awakeable(&self) -> Result<Value, Error> {
736
770
  let ruby = Ruby::get().map_err(|_| Error::new(vm_error_class(), "Ruby not available"))?;
737
- let (id, handle) = self
771
+ let awakeable = self
738
772
  .vm
739
773
  .borrow_mut()
740
774
  .sys_awakeable()
741
775
  .map_err(core_error_to_magnus)?;
742
776
  let ary = ruby.ary_new_capa(2);
743
- ary.push(ruby.str_new(&id))?;
744
- ary.push(u32::from(handle))?;
777
+ ary.push(ruby.str_new(&awakeable.id))?;
778
+ ary.push(u32::from(awakeable.handle))?;
745
779
  Ok(ary.as_value())
746
780
  }
747
781
 
@@ -926,6 +960,54 @@ Or remove the begin/rescue altogether if you don't need it.
926
960
 
927
961
  // ── Helpers ──
928
962
 
963
+ // Recursive Ruby → UnresolvedFuture parser. Accepts an Integer handle, or a
964
+ // [Symbol, Array[children]] pair encoding a combinator node. See the do_await
965
+ // docstring for the variant tags.
966
+ fn parse_unresolved_future(value: Value) -> Result<UnresolvedFuture, Error> {
967
+ let ruby = Ruby::get().map_err(|_| Error::new(vm_error_class(), "Ruby not available"))?;
968
+
969
+ if let Ok(handle) = u32::try_convert(value) {
970
+ return Ok(UnresolvedFuture::Single(NotificationHandle::from(handle)));
971
+ }
972
+
973
+ let pair = RArray::try_convert(value).map_err(|_| {
974
+ Error::new(
975
+ ruby.exception_arg_error(),
976
+ "UnresolvedFuture must be a Integer handle or [Symbol, Array] pair",
977
+ )
978
+ })?;
979
+ if pair.len() != 2 {
980
+ return Err(Error::new(
981
+ ruby.exception_arg_error(),
982
+ "UnresolvedFuture combinator pair must be [Symbol, Array]",
983
+ ));
984
+ }
985
+ let tag: Symbol = pair.entry(0)?;
986
+ let children_arr: RArray = pair.entry(1)?;
987
+ let mut children = Vec::with_capacity(children_arr.len());
988
+ for child in children_arr.into_iter() {
989
+ children.push(parse_unresolved_future(child)?);
990
+ }
991
+ let tag_name = tag.name().map_err(|_| {
992
+ Error::new(ruby.exception_arg_error(), "UnresolvedFuture tag is not a Symbol")
993
+ })?;
994
+ match tag_name.as_ref() {
995
+ "first_completed" => Ok(UnresolvedFuture::FirstCompleted(children)),
996
+ "all_completed" => Ok(UnresolvedFuture::AllCompleted(children)),
997
+ "first_succeeded_or_all_failed" => {
998
+ Ok(UnresolvedFuture::FirstSucceededOrAllFailed(children))
999
+ }
1000
+ "all_succeeded_or_first_failed" => {
1001
+ Ok(UnresolvedFuture::AllSucceededOrFirstFailed(children))
1002
+ }
1003
+ "unknown" => Ok(UnresolvedFuture::Unknown(children)),
1004
+ other => Err(Error::new(
1005
+ ruby.exception_arg_error(),
1006
+ format!("Unknown UnresolvedFuture combinator: {other}"),
1007
+ )),
1008
+ }
1009
+ }
1010
+
929
1011
  fn parse_headers_array(ary: RArray) -> Result<Vec<Header>, Error> {
930
1012
  let mut result = Vec::new();
931
1013
  for item in ary.into_iter() {
@@ -1083,6 +1165,11 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
1083
1165
  )?;
1084
1166
  ch_class.define_method("result_handle", method!(RbCallHandle::result_handle, 0))?;
1085
1167
 
1168
+ // Run
1169
+ let run_class = internal.define_class("Run", ruby.class_object())?;
1170
+ run_class.define_method("replayed", method!(RbRun::replayed, 0))?;
1171
+ run_class.define_method("handle", method!(RbRun::handle, 0))?;
1172
+
1086
1173
  // VM - all methods use explicit arities
1087
1174
  let vm_class = internal.define_class("VM", ruby.class_object())?;
1088
1175
  vm_class.define_singleton_method("new", function!(RbVM::new, 1))?;
@@ -1093,7 +1180,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
1093
1180
  vm_class.define_method("take_output", method!(RbVM::take_output, 0))?;
1094
1181
  vm_class.define_method("is_ready_to_execute", method!(RbVM::is_ready_to_execute, 0))?;
1095
1182
  vm_class.define_method("is_completed", method!(RbVM::is_completed, 1))?;
1096
- vm_class.define_method("do_progress", method!(RbVM::do_progress, 1))?;
1183
+ vm_class.define_method("do_await", method!(RbVM::do_await, 1))?;
1097
1184
  vm_class.define_method("take_notification", method!(RbVM::take_notification, 1))?;
1098
1185
  vm_class.define_method("sys_input", method!(RbVM::sys_input, 0))?;
1099
1186
  vm_class.define_method("sys_get_state", method!(RbVM::sys_get_state, 1))?;
@@ -41,7 +41,7 @@ module Restate
41
41
  compact(
42
42
  protocolMode: protocol_mode,
43
43
  minProtocolVersion: 5,
44
- maxProtocolVersion: 6,
44
+ maxProtocolVersion: 7,
45
45
  services: services
46
46
  )
47
47
  end
@@ -15,15 +15,16 @@ module Restate
15
15
  @value = nil
16
16
  end
17
17
 
18
- # Block until the result is available and return it. Caches across calls.
18
+ # Block until the result is available and return it. Caches across calls,
19
+ # including failures — a second await on a failed future re-raises the
20
+ # same +TerminalError+ rather than re-fetching from the VM (the notification
21
+ # is single-shot).
19
22
  #
20
23
  # @return [Object] the deserialized result
21
24
  def await
22
- unless @resolved
23
- raw = @ctx.resolve_handle(@handle)
24
- @value = @serde ? @serde.deserialize(raw) : raw
25
- @resolved = true
26
- end
25
+ resolve! unless @resolved
26
+ raise @error if @error
27
+
27
28
  @value
28
29
  end
29
30
 
@@ -46,6 +47,17 @@ module Restate
46
47
 
47
48
  raise TimeoutError
48
49
  end
50
+
51
+ private
52
+
53
+ def resolve!
54
+ raw = @ctx.resolve_handle(@handle)
55
+ @value = @serde ? @serde.deserialize(raw) : raw
56
+ rescue TerminalError => e
57
+ @error = e
58
+ ensure
59
+ @resolved = true
60
+ end
49
61
  end
50
62
 
51
63
  # A durable future for service/object/workflow calls.
@@ -61,19 +73,31 @@ module Restate
61
73
  end
62
74
 
63
75
  # Block until the result is available and return it. Deserializes via +output_serde+.
76
+ # Caches both successes and TerminalError failures across calls.
64
77
  def await
65
- unless @resolved
66
- raw = @ctx.resolve_handle(@handle)
67
- @value = if raw.nil? || @output_serde.nil?
68
- raw
69
- else
70
- @output_serde.deserialize(raw)
71
- end
72
- @resolved = true
73
- end
78
+ resolve_call! unless @resolved
79
+ raise @error if @error
80
+
74
81
  @value
75
82
  end
76
83
 
84
+ private
85
+
86
+ def resolve_call!
87
+ raw = @ctx.resolve_handle(@handle)
88
+ @value = if raw.nil? || @output_serde.nil?
89
+ raw
90
+ else
91
+ @output_serde.deserialize(raw)
92
+ end
93
+ rescue TerminalError => e
94
+ @error = e
95
+ ensure
96
+ @resolved = true
97
+ end
98
+
99
+ public
100
+
77
101
  # Returns the invocation ID of the remote call. Lazily resolved.
78
102
  #
79
103
  # @return [String] the invocation ID
@@ -91,6 +115,122 @@ module Restate
91
115
  end
92
116
  end
93
117
 
118
+ # A lazy combinator over one or more child futures. The child set can mix
119
+ # +DurableFuture+ leaves (with raw handles) and nested +CombinedFuture+ nodes.
120
+ # The shared-core uses the tree shape to make suspension decisions; nothing
121
+ # blocks until +.await+ is called, so combinators are composable:
122
+ #
123
+ # Restate.race(Restate.all(a, b), c).await
124
+ #
125
+ # Supported variants (mirroring +UnresolvedFuture+ in restate-sdk-shared-core):
126
+ # :first_completed → JS Promise.race
127
+ # :all_succeeded_or_first_failed → JS Promise.all
128
+ # :first_succeeded_or_all_failed → JS Promise.any
129
+ # :all_completed → JS Promise.allSettled
130
+ class CombinedFuture
131
+ VALID_VARIANTS = %i[
132
+ first_completed
133
+ all_succeeded_or_first_failed
134
+ first_succeeded_or_all_failed
135
+ all_completed
136
+ ].freeze
137
+
138
+ def initialize(ctx, variant, children)
139
+ raise ArgumentError, "unknown combinator variant: #{variant}" unless VALID_VARIANTS.include?(variant)
140
+
141
+ @ctx = ctx
142
+ @variant = variant
143
+ @children = children
144
+ @resolved = false
145
+ @value = nil
146
+ @error = nil
147
+ end
148
+
149
+ # Recursive tree representation the native +do_await+ binding consumes.
150
+ # Leaves are integer handles; inner nodes are +[variant, [child...]]+ pairs.
151
+ def tree
152
+ [@variant, @children.map { |c| c.is_a?(CombinedFuture) ? c.tree : c.handle }]
153
+ end
154
+
155
+ # Block until this combinator settles per its variant. Caches results
156
+ # (including failures) across calls.
157
+ def await
158
+ resolve_combined! unless @resolved
159
+ raise @error if @error
160
+
161
+ @value
162
+ end
163
+
164
+ # Non-blocking introspection. True iff calling +.await+ is guaranteed not to
165
+ # block. Conservative for the variants that allow early-completion on failure
166
+ # (+:all_succeeded_or_first_failed+, +:first_succeeded_or_all_failed+) — we
167
+ # report false until every child is settled, because checking failure status
168
+ # of a leaf would require consuming its notification.
169
+ def completed?
170
+ return true if @resolved
171
+
172
+ case @variant
173
+ when :first_completed
174
+ @children.any?(&:completed?)
175
+ else
176
+ @children.all?(&:completed?)
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ def resolve_combined!
183
+ @ctx.wait_combined(tree)
184
+ @value = finalize_value
185
+ rescue TerminalError => e
186
+ @error = e
187
+ ensure
188
+ @resolved = true
189
+ end
190
+
191
+ def finalize_value
192
+ case @variant
193
+ when :first_completed then finalize_first_completed
194
+ when :all_succeeded_or_first_failed then finalize_all_succeeded
195
+ when :all_completed then finalize_all_completed
196
+ when :first_succeeded_or_all_failed then finalize_first_succeeded
197
+ end
198
+ end
199
+
200
+ def finalize_first_completed
201
+ @children.find(&:completed?).await
202
+ end
203
+
204
+ def finalize_all_succeeded
205
+ # Surface any settled-and-failed child first (short-circuit). After this
206
+ # scan, if no failure was raised, every child must be settled-and-success
207
+ # per AllSucceededOrFirstFailed semantics.
208
+ @children.each { |c| c.await if c.completed? }
209
+ @children.map(&:await)
210
+ end
211
+
212
+ def finalize_all_completed
213
+ @children.map do |c|
214
+ { status: :fulfilled, value: c.await }
215
+ rescue TerminalError => e
216
+ { status: :rejected, reason: e }
217
+ end
218
+ end
219
+
220
+ def finalize_first_succeeded
221
+ errors = [] # : Array[TerminalError]
222
+ @children.each do |c|
223
+ next unless c.completed?
224
+
225
+ return c.await
226
+ rescue TerminalError => e
227
+ errors << e
228
+ end
229
+ raise TerminalError.new("all futures failed: #{errors.map(&:message).join('; ')}",
230
+ status_code: 500)
231
+ end
232
+ end
233
+
94
234
  # A handle for fire-and-forget send operations.
95
235
  # Returned by +ctx.service_send+, +ctx.object_send+, +ctx.workflow_send+.
96
236
  class SendHandle
@@ -169,6 +169,44 @@ module Restate
169
169
  futures.partition(&:completed?)
170
170
  end
171
171
 
172
+ # Build a lazy combinator over the given futures and return it as a
173
+ # +CombinedFuture+. Nothing blocks until +.await+ is called, so the
174
+ # combinators compose: +Restate.race(Restate.all(a, b), c).await+.
175
+ #
176
+ # Semantics match JS +Promise.all+ — when awaited, returns the values in
177
+ # input order, short-circuiting on the first +TerminalError+.
178
+ def all(*futures)
179
+ futures = futures.first if futures.length == 1 && futures.first.is_a?(Array)
180
+ CombinedFuture.new(self, :all_succeeded_or_first_failed, futures)
181
+ end
182
+
183
+ # Lazy combinator. Awaiting returns the value of the first future to settle,
184
+ # or raises if it settled with a +TerminalError+. Matches JS +Promise.race+.
185
+ def race(*futures)
186
+ futures = futures.first if futures.length == 1 && futures.first.is_a?(Array)
187
+ raise ArgumentError, 'race requires at least one future' if futures.empty?
188
+
189
+ CombinedFuture.new(self, :first_completed, futures)
190
+ end
191
+
192
+ # Lazy combinator. Awaiting returns the value of the first successful future;
193
+ # raises only if every future fails terminally. Matches JS +Promise.any+.
194
+ def any(*futures)
195
+ futures = futures.first if futures.length == 1 && futures.first.is_a?(Array)
196
+ raise ArgumentError, 'any requires at least one future' if futures.empty?
197
+
198
+ CombinedFuture.new(self, :first_succeeded_or_all_failed, futures)
199
+ end
200
+
201
+ # Lazy combinator. Awaiting waits for every future to settle and returns
202
+ # an Array of +{ status: :fulfilled, value: ... }+ or
203
+ # +{ status: :rejected, reason: TerminalError }+ entries, in input order.
204
+ # Matches JS +Promise.allSettled+.
205
+ def all_settled(*futures)
206
+ futures = futures.first if futures.length == 1 && futures.first.is_a?(Array)
207
+ CombinedFuture.new(self, :all_completed, futures)
208
+ end
209
+
172
210
  # ── Durable run (side effect) ──
173
211
 
174
212
  # Executes a durable side effect. The block runs at most once; its result is
@@ -178,14 +216,18 @@ module Restate
178
216
  # fiber event loop responsive for other concurrent handlers. Use this for
179
217
  # CPU-intensive work.
180
218
  def run(name, serde: JsonSerde, retry_policy: nil, background: false, &action)
181
- handle = @vm.sys_run(name)
182
-
183
- @run_coros_to_execute[handle] =
184
- if background
185
- -> { execute_run_threaded(handle, action, serde, retry_policy) }
186
- else
187
- -> { execute_run(handle, action, serde, retry_policy) }
188
- end
219
+ run = @vm.sys_run(name)
220
+ handle = run.handle
221
+
222
+ # Schedule the run closure only if the run wasn't replayed.
223
+ unless run.replayed
224
+ @run_coros_to_execute[handle] =
225
+ if background
226
+ -> { execute_run_threaded(handle, action, serde, retry_policy) }
227
+ else
228
+ -> { execute_run(handle, action, serde, retry_policy) }
229
+ end
230
+ end
189
231
 
190
232
  DurableFuture.new(self, handle, serde: serde)
191
233
  end
@@ -401,6 +443,14 @@ module Restate
401
443
  @invocation.key
402
444
  end
403
445
 
446
+ # Drive progress over a combinator tree. Returns when the combinator
447
+ # logically completes (the shared-core decides based on the tree shape).
448
+ # +future_tree+ follows the encoding documented in lib/restate/vm.rb#do_await.
449
+ # Public so +CombinedFuture#await+ can drive it via +@ctx.wait_combined+.
450
+ def wait_combined(future_tree)
451
+ progress_loop { @vm.do_await(future_tree) }
452
+ end
453
+
404
454
  private
405
455
 
406
456
  # ── Progress loop ──
@@ -411,13 +461,24 @@ module Restate
411
461
  must_take_notification(handle, &)
412
462
  end
413
463
 
464
+ # Wait for any of the given handles to complete. Wraps the flat handle
465
+ # list into a +FirstCompleted+ subtree (or a +Single+ leaf for one handle)
466
+ # and drives the VM via +do_await+ — same path as +wait_combined+.
414
467
  def poll_or_cancel(handles)
468
+ tree = handles.length == 1 ? handles.first : [:first_completed, handles]
469
+ wait_combined(tree)
470
+ end
471
+
472
+ # Shared progress-loop body for both the simple poll_or_cancel and the
473
+ # tree-aware wait_combined. The block makes one VM call per iteration and
474
+ # returns the response; this loop interprets it.
475
+ def progress_loop
415
476
  loop do
416
477
  flush_output
417
- response = @vm.do_progress(handles)
478
+ response = yield
418
479
 
419
480
  if response.is_a?(Exception)
420
- LOGGER.error("Exception in do_progress: #{response}")
481
+ LOGGER.error("Exception in progress loop: #{response}")
421
482
  raise InternalError
422
483
  end
423
484
 
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Restate
5
- VERSION = '0.14.0'
5
+ VERSION = '1.0.0'
6
6
  end
data/lib/restate/vm.rb CHANGED
@@ -90,8 +90,12 @@ module Restate
90
90
  @vm.is_completed(handle)
91
91
  end
92
92
 
93
- def do_progress(handles)
94
- result = @vm.do_progress(handles)
93
+ # Drive the VM forward against an +UnresolvedFuture+ tree. +future+ is either
94
+ # an Integer handle (Single leaf) or a +[tag_symbol, [children...]]+ pair
95
+ # (combinator node). See the Rust-side +parse_unresolved_future+ for the
96
+ # supported tags.
97
+ def do_await(future)
98
+ result = @vm.do_await(future)
95
99
  map_do_progress(result)
96
100
  rescue Internal::VMError => e
97
101
  e
data/lib/restate.rb CHANGED
@@ -293,6 +293,34 @@ module Restate # rubocop:disable Metrics/ModuleLength
293
293
  fetch_context!.wait_any(*futures)
294
294
  end
295
295
 
296
+ # Wait for every future to complete and return their values in input order.
297
+ # Short-circuits on the first +TerminalError+. Accepts either splat futures or
298
+ # a single Array. Semantics match JS +Promise.all+.
299
+ def all(*futures)
300
+ fetch_context!.all(*futures)
301
+ end
302
+
303
+ # Wait for the first future to settle and return its value. Raises if the
304
+ # winning future failed. Accepts either splat futures or a single Array.
305
+ # Semantics match JS +Promise.race+.
306
+ def race(*futures)
307
+ fetch_context!.race(*futures)
308
+ end
309
+
310
+ # Wait for the first successful future and return its value. Raises only if
311
+ # every future failed terminally. Accepts splat or single Array.
312
+ # Semantics match JS +Promise.any+.
313
+ def any(*futures)
314
+ fetch_context!.any(*futures)
315
+ end
316
+
317
+ # Wait for every future to settle. Returns an Array of outcome descriptors
318
+ # (+{status: :fulfilled, value: ...}+ or +{status: :rejected, reason: ...}+),
319
+ # in input order. Semantics match JS +Promise.allSettled+.
320
+ def all_settled(*futures)
321
+ fetch_context!.all_settled(*futures)
322
+ end
323
+
296
324
  # ── Request metadata ──
297
325
 
298
326
  # Returns metadata about the current invocation (id, headers, raw body).
data/sig/restate.rbs CHANGED
@@ -60,6 +60,10 @@ module Restate
60
60
  # ── Futures / Metadata / Control ──
61
61
 
62
62
  def self.wait_any: (*DurableFuture futures) -> [Array[DurableFuture], Array[DurableFuture]]
63
+ def self.all: (*untyped futures) -> CombinedFuture
64
+ def self.race: (*untyped futures) -> CombinedFuture
65
+ def self.any: (*untyped futures) -> CombinedFuture
66
+ def self.all_settled: (*untyped futures) -> CombinedFuture
63
67
  def self.request: () -> untyped
64
68
  def self.key: () -> String
65
69
  def self.cancel_invocation: (String invocation_id) -> void
@@ -97,12 +101,34 @@ module Restate
97
101
  def await: () -> untyped
98
102
  def completed?: () -> bool
99
103
  def or_timeout: (Numeric duration) -> untyped
104
+
105
+ private
106
+ def resolve!: () -> void
100
107
  end
101
108
 
102
109
  class DurableCallFuture < DurableFuture
103
110
  def initialize: (untyped ctx, Integer result_handle, Integer invocation_id_handle, output_serde: untyped) -> void
104
111
  def invocation_id: () -> String
105
112
  def cancel: () -> void
113
+
114
+ private
115
+ def resolve_call!: () -> void
116
+ end
117
+
118
+ class CombinedFuture
119
+ VALID_VARIANTS: Array[Symbol]
120
+ def initialize: (untyped ctx, Symbol variant, Array[untyped] children) -> void
121
+ def tree: () -> untyped
122
+ def await: () -> untyped
123
+ def completed?: () -> bool
124
+
125
+ private
126
+ def resolve_combined!: () -> void
127
+ def finalize_value: () -> untyped
128
+ def finalize_first_completed: () -> untyped
129
+ def finalize_all_succeeded: () -> Array[untyped]
130
+ def finalize_all_completed: () -> Array[Hash[Symbol, untyped]]
131
+ def finalize_first_succeeded: () -> untyped
106
132
  end
107
133
 
108
134
  class SendHandle
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restate-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Restate Developers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-29 00:00:00.000000000 Z
11
+ date: 2026-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async