asterism-zenoh 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +89 -0
- data/README.md +69 -18
- data/docs/feature_coverage.md +5 -4
- data/ext/asterism_zenoh/zenoh.c +136 -58
- data/lib/asterism/zenoh/common.rb +221 -0
- data/lib/asterism/zenoh/cruby.rb +128 -0
- data/lib/asterism/zenoh/values.rb +13 -6
- data/lib/asterism/zenoh/version.rb +1 -1
- data/lib/asterism/zenoh.rb +2 -0
- metadata +5 -2
data/ext/asterism_zenoh/zenoh.c
CHANGED
|
@@ -43,11 +43,13 @@
|
|
|
43
43
|
* undeclared or the get is finished); whichever lets go last frees it.
|
|
44
44
|
*/
|
|
45
45
|
#include <pthread.h>
|
|
46
|
+
#include <stdarg.h>
|
|
46
47
|
#include <stdatomic.h>
|
|
47
48
|
#include <stdbool.h>
|
|
48
49
|
#include <stdint.h>
|
|
49
50
|
#include <stdlib.h>
|
|
50
51
|
#include <string.h>
|
|
52
|
+
#include <unistd.h>
|
|
51
53
|
|
|
52
54
|
#include <ruby.h>
|
|
53
55
|
#include <ruby/encoding.h>
|
|
@@ -56,7 +58,13 @@
|
|
|
56
58
|
#include <zenoh.h>
|
|
57
59
|
|
|
58
60
|
#define ZRB_DEFAULT_DEPTH 16
|
|
59
|
-
|
|
61
|
+
/* A get, a liveliness get and a liveliness watch hold every reply or token
|
|
62
|
+
* a router sends in one burst (a wildcard over a busy network). On a PC the
|
|
63
|
+
* queue costs nothing until it fills: zenoh-c's FIFO and the gem's lists
|
|
64
|
+
* grow as entries come. */
|
|
65
|
+
#define ZRB_DEFAULT_GET_DEPTH 1024
|
|
66
|
+
#define ZRB_DEFAULT_WATCH_DEPTH 1024
|
|
67
|
+
#define ZRB_MAX_DEPTH 65536
|
|
60
68
|
#define ZRB_DEFAULT_POLL_STEPS 8
|
|
61
69
|
#define ZRB_DEFAULT_GET_TIMEOUT_MS 2000
|
|
62
70
|
#define ZRB_MAX_GET_TIMEOUT_MS 600000
|
|
@@ -64,13 +72,13 @@
|
|
|
64
72
|
#define ZRB_CONNECT_TIMEOUT_MS 3000
|
|
65
73
|
#define ZRB_SEND_TIMEOUT_MS 3000
|
|
66
74
|
|
|
67
|
-
static VALUE mAsterism, mZenoh, eZenohError;
|
|
75
|
+
static VALUE mAsterism, mZenoh, eAsterismError, eZenohError, eClosedError;
|
|
68
76
|
static VALUE cSession, cSubscriber, cWatch, cQueryable, cQuery, cGet, cToken;
|
|
69
77
|
static VALUE cAdvSubscriber, cPublisher, cAdvPublisher, cQuerier, cKeyExpr, cTimestamp;
|
|
70
78
|
static VALUE cMatchingListener, cEventListener;
|
|
71
79
|
static ID id_attachment, id_target, id_consolidation, id_complete, id_mode, id_listen;
|
|
72
80
|
static ID id_config, id_config_file, id_scouting, id_history, id_new;
|
|
73
|
-
static ID id_iv_session, id_iv_key, id_iv_parent;
|
|
81
|
+
static ID id_iv_session, id_iv_key, id_iv_parent, id_iv_code, id_iv_qkey;
|
|
74
82
|
static ID id_client, id_peer, id_router, id_all, id_all_complete, id_best_matching;
|
|
75
83
|
static ID id_none, id_latest, id_monotonic, id_auto;
|
|
76
84
|
|
|
@@ -347,14 +355,16 @@ static void zrb_owned_key(z_owned_keyexpr_t *ke, const char *key) {
|
|
|
347
355
|
}
|
|
348
356
|
}
|
|
349
357
|
|
|
350
|
-
static long
|
|
351
|
-
long depth = NIL_P(v) ?
|
|
358
|
+
static long zrb_check_depth_or(VALUE v, long def) {
|
|
359
|
+
long depth = NIL_P(v) ? def : NUM2LONG(v);
|
|
352
360
|
if (depth < 1 || depth > ZRB_MAX_DEPTH) {
|
|
353
361
|
rb_raise(rb_eArgError, "depth must be 1..%d", ZRB_MAX_DEPTH);
|
|
354
362
|
}
|
|
355
363
|
return depth;
|
|
356
364
|
}
|
|
357
365
|
|
|
366
|
+
static long zrb_check_depth(VALUE v) { return zrb_check_depth_or(v, ZRB_DEFAULT_DEPTH); }
|
|
367
|
+
|
|
358
368
|
static long zrb_check_timeout(VALUE v) {
|
|
359
369
|
long t = NIL_P(v) ? ZRB_DEFAULT_GET_TIMEOUT_MS : NUM2LONG(v);
|
|
360
370
|
if (t < 1 || t > ZRB_MAX_GET_TIMEOUT_MS) {
|
|
@@ -407,6 +417,22 @@ static void zrb_hold_session(VALUE obj, VALUE session, VALUE key) {
|
|
|
407
417
|
}
|
|
408
418
|
}
|
|
409
419
|
|
|
420
|
+
/* Raises klass with the zenoh-c result code as the exception's code
|
|
421
|
+
* (Asterism::Zenoh::Error#code) as well as in the message. */
|
|
422
|
+
#ifdef RBIMPL_ATTR_FORMAT
|
|
423
|
+
RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 4)
|
|
424
|
+
#endif
|
|
425
|
+
NORETURN(static void zrb_raise_code(VALUE klass, int code, const char *fmt, ...));
|
|
426
|
+
static void zrb_raise_code(VALUE klass, int code, const char *fmt, ...) {
|
|
427
|
+
va_list ap;
|
|
428
|
+
va_start(ap, fmt);
|
|
429
|
+
VALUE msg = rb_vsprintf(fmt, ap);
|
|
430
|
+
va_end(ap);
|
|
431
|
+
VALUE exc = rb_exc_new_str(klass, msg);
|
|
432
|
+
rb_ivar_set(exc, id_iv_code, INT2NUM(code));
|
|
433
|
+
rb_exc_raise(exc);
|
|
434
|
+
}
|
|
435
|
+
|
|
410
436
|
/* ------------------------------------------------------- object structs */
|
|
411
437
|
|
|
412
438
|
typedef struct zrb_session zrb_session;
|
|
@@ -441,6 +467,7 @@ struct zrb_session {
|
|
|
441
467
|
zrb_qable *qables;
|
|
442
468
|
zrb_token *tokens;
|
|
443
469
|
zrb_ent *ents; /* the rest (0.3.0) */
|
|
470
|
+
pid_t pid; /* the process that opened it (zenoh-c's threads do not survive fork) */
|
|
444
471
|
};
|
|
445
472
|
|
|
446
473
|
typedef enum { ZSUB_PLAIN, ZSUB_LIVELINESS, ZSUB_ADVANCED } zsub_type;
|
|
@@ -913,6 +940,7 @@ typedef struct {
|
|
|
913
940
|
int accept_replies;
|
|
914
941
|
VALUE target, consolidation, timeout;
|
|
915
942
|
bool has_target, has_consolidation, has_timeout;
|
|
943
|
+
VALUE depth; /* gets: nil (the default) or the queue depth */
|
|
916
944
|
} zrb_opts;
|
|
917
945
|
|
|
918
946
|
static int zrb_priority_arg(VALUE v) {
|
|
@@ -1018,6 +1046,7 @@ static void zrb_opts_parse(VALUE hash, const char *const *names, int n, zrb_opts
|
|
|
1018
1046
|
o->priority = o->congestion_control = o->express = o->reliability = o->destination = o->accept_replies = -1;
|
|
1019
1047
|
o->target = o->consolidation = o->timeout = Qnil;
|
|
1020
1048
|
o->has_target = o->has_consolidation = o->has_timeout = false;
|
|
1049
|
+
o->depth = Qnil;
|
|
1021
1050
|
if (NIL_P(hash)) {
|
|
1022
1051
|
return;
|
|
1023
1052
|
}
|
|
@@ -1079,6 +1108,8 @@ static void zrb_opts_parse(VALUE hash, const char *const *names, int n, zrb_opts
|
|
|
1079
1108
|
} else if (strcmp(k, "timeout_ms") == 0) {
|
|
1080
1109
|
o->timeout = v;
|
|
1081
1110
|
o->has_timeout = true;
|
|
1111
|
+
} else if (strcmp(k, "depth") == 0) {
|
|
1112
|
+
o->depth = v;
|
|
1082
1113
|
}
|
|
1083
1114
|
}
|
|
1084
1115
|
}
|
|
@@ -1670,6 +1701,9 @@ static VALUE zrb_query_yield_ensure(VALUE obj) {
|
|
|
1670
1701
|
static VALUE zrb_qable_each_pending(VALUE self) {
|
|
1671
1702
|
zrb_qable *q = zrb_qable_get(self);
|
|
1672
1703
|
bool collect = !rb_block_given_p();
|
|
1704
|
+
/* The queryable's own key goes with each query (Query#reply with one
|
|
1705
|
+
* argument looks at it). */
|
|
1706
|
+
VALUE qkey = rb_attr_get(self, id_iv_key);
|
|
1673
1707
|
VALUE out = collect ? rb_ary_new() : Qnil;
|
|
1674
1708
|
long taken = 0;
|
|
1675
1709
|
unsigned todo = atomic_load(&q->ch->queued);
|
|
@@ -1680,6 +1714,9 @@ static VALUE zrb_qable_each_pending(VALUE self) {
|
|
|
1680
1714
|
break;
|
|
1681
1715
|
}
|
|
1682
1716
|
VALUE obj = zrb_query_wrap(&oq);
|
|
1717
|
+
if (!NIL_P(qkey)) {
|
|
1718
|
+
rb_ivar_set(obj, id_iv_qkey, qkey);
|
|
1719
|
+
}
|
|
1683
1720
|
taken++;
|
|
1684
1721
|
if (collect) {
|
|
1685
1722
|
rb_ary_push(out, obj);
|
|
@@ -1806,7 +1843,7 @@ static VALUE zrb_query_reply(int argc, VALUE *argv, VALUE self) {
|
|
|
1806
1843
|
zrb_bytes_from_str(&bytes, payload, "payload");
|
|
1807
1844
|
z_result_t ret = z_query_reply(z_loan(zq->query), kp, z_move(bytes), &ro);
|
|
1808
1845
|
if (ret != Z_OK) {
|
|
1809
|
-
|
|
1846
|
+
zrb_raise_code(eZenohError, (int)ret, "reply failed (%d)%" PRIsVALUE, (int)ret, zrb_last_error());
|
|
1810
1847
|
}
|
|
1811
1848
|
return Qnil;
|
|
1812
1849
|
}
|
|
@@ -1833,7 +1870,7 @@ static VALUE zrb_query_reply_err(int argc, VALUE *argv, VALUE self) {
|
|
|
1833
1870
|
zrb_bytes_from_str(&bytes, payload, "payload");
|
|
1834
1871
|
z_result_t ret = z_query_reply_err(z_loan(zq->query), z_move(bytes), &eo);
|
|
1835
1872
|
if (ret != Z_OK) {
|
|
1836
|
-
|
|
1873
|
+
zrb_raise_code(eZenohError, (int)ret, "reply_err failed (%d)%" PRIsVALUE, (int)ret, zrb_last_error());
|
|
1837
1874
|
}
|
|
1838
1875
|
return Qnil;
|
|
1839
1876
|
}
|
|
@@ -1876,7 +1913,7 @@ static VALUE zrb_query_reply_del(int argc, VALUE *argv, VALUE self) {
|
|
|
1876
1913
|
}
|
|
1877
1914
|
z_result_t ret = z_query_reply_del(z_loan(zq->query), kp, &d);
|
|
1878
1915
|
if (ret != Z_OK) {
|
|
1879
|
-
|
|
1916
|
+
zrb_raise_code(eZenohError, (int)ret, "reply_del failed (%d)%" PRIsVALUE, (int)ret, zrb_last_error());
|
|
1880
1917
|
}
|
|
1881
1918
|
return Qnil;
|
|
1882
1919
|
}
|
|
@@ -1915,10 +1952,12 @@ static zrb_get *zrb_get_get(VALUE self) {
|
|
|
1915
1952
|
return g;
|
|
1916
1953
|
}
|
|
1917
1954
|
|
|
1918
|
-
|
|
1955
|
+
/* depth: how many replies wait to be taken; past it the oldest go (and
|
|
1956
|
+
* are counted in dropped). */
|
|
1957
|
+
static VALUE zrb_get_new(long depth, zrb_get **out) {
|
|
1919
1958
|
zrb_get *g;
|
|
1920
1959
|
VALUE obj = TypedData_Make_Struct(cGet, zrb_get, &zrb_get_type, g);
|
|
1921
|
-
g->ch = zch_new(ZCH_REPLY,
|
|
1960
|
+
g->ch = zch_new(ZCH_REPLY, (uint32_t)depth);
|
|
1922
1961
|
*out = g;
|
|
1923
1962
|
return obj;
|
|
1924
1963
|
}
|
|
@@ -2084,6 +2123,12 @@ static void *zrb_session_close_nogvl(void *p) {
|
|
|
2084
2123
|
}
|
|
2085
2124
|
|
|
2086
2125
|
static void zrb_session_shutdown(zrb_session *z, bool with_gvl_release) {
|
|
2126
|
+
if (z->open && z->pid != getpid()) {
|
|
2127
|
+
/* Opened before a fork: zenoh-c's threads are in the parent. Leave
|
|
2128
|
+
* the session to it; only this process's view is closed. */
|
|
2129
|
+
z->open = false;
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2087
2132
|
zrb_session_detach_all(z);
|
|
2088
2133
|
if (!z->open) {
|
|
2089
2134
|
return;
|
|
@@ -2142,6 +2187,9 @@ static bool zrb_session_check_link(zrb_session *z) {
|
|
|
2142
2187
|
if (!z->open) {
|
|
2143
2188
|
return true;
|
|
2144
2189
|
}
|
|
2190
|
+
if (z->pid != getpid()) {
|
|
2191
|
+
return true;
|
|
2192
|
+
}
|
|
2145
2193
|
if (z_session_is_closed(z_loan(z->session))) {
|
|
2146
2194
|
zrb_session_shutdown(z, true);
|
|
2147
2195
|
return true;
|
|
@@ -2158,8 +2206,12 @@ static bool zrb_session_check_link(zrb_session *z) {
|
|
|
2158
2206
|
|
|
2159
2207
|
static zrb_session *zrb_session_get_open(VALUE self) {
|
|
2160
2208
|
zrb_session *z = zrb_session_get(self);
|
|
2209
|
+
if (z->open && z->pid != getpid()) {
|
|
2210
|
+
rb_raise(eClosedError, "the session was opened in process %ld; open a new session after fork",
|
|
2211
|
+
(long)z->pid);
|
|
2212
|
+
}
|
|
2161
2213
|
if (zrb_session_check_link(z)) {
|
|
2162
|
-
rb_raise(
|
|
2214
|
+
rb_raise(eClosedError, "session is closed");
|
|
2163
2215
|
}
|
|
2164
2216
|
return z;
|
|
2165
2217
|
}
|
|
@@ -2441,13 +2493,14 @@ static VALUE zrb_session_s_open(int argc, VALUE *argv, VALUE klass) {
|
|
|
2441
2493
|
|
|
2442
2494
|
rb_thread_call_without_gvl(zrb_open_nogvl, &a, RUBY_UBF_IO, NULL);
|
|
2443
2495
|
if (a.ret != Z_OK) {
|
|
2444
|
-
|
|
2496
|
+
zrb_raise_code(eZenohError, (int)a.ret, "cannot open a session to %s (%d)%" PRIsVALUE,
|
|
2445
2497
|
locator != NULL ? locator : (listen != NULL ? listen : "the configured endpoints"), (int)a.ret,
|
|
2446
2498
|
zrb_last_error());
|
|
2447
2499
|
}
|
|
2448
2500
|
z->open = true;
|
|
2449
2501
|
z->live = true;
|
|
2450
2502
|
z->peer = peer;
|
|
2503
|
+
z->pid = getpid();
|
|
2451
2504
|
/* A peer that listens (or finds the others by scouting) stays open
|
|
2452
2505
|
* without peers; one that only connects closes when it has none. */
|
|
2453
2506
|
z->listening = peer && (is_router || listens || scouts);
|
|
@@ -2483,7 +2536,7 @@ static VALUE zrb_sub_new(VALUE self, zrb_session *z, VALUE key_v, long depth, bo
|
|
|
2483
2536
|
ret = z_declare_subscriber(z_loan(z->session), &s->u.sub, z_loan(ke), z_move(cb), &so);
|
|
2484
2537
|
}
|
|
2485
2538
|
if (ret != Z_OK) {
|
|
2486
|
-
|
|
2539
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot subscribe to %s (%d)%" PRIsVALUE, key, (int)ret, zrb_last_error());
|
|
2487
2540
|
}
|
|
2488
2541
|
s->declared = true;
|
|
2489
2542
|
s->owner = z;
|
|
@@ -2503,11 +2556,12 @@ static VALUE zrb_session_subscribe(int argc, VALUE *argv, VALUE self) {
|
|
|
2503
2556
|
return zrb_sub_new(self, z, key_v, depth, false);
|
|
2504
2557
|
}
|
|
2505
2558
|
|
|
2506
|
-
/* session.liveliness_watch(key, depth =
|
|
2559
|
+
/* session.liveliness_watch(key, depth = 1024) -> LivelinessWatch. The
|
|
2560
|
+
* tokens alive when it is declared come in one burst. */
|
|
2507
2561
|
static VALUE zrb_session_liveliness_watch(int argc, VALUE *argv, VALUE self) {
|
|
2508
2562
|
VALUE key_v, depth_v = Qnil;
|
|
2509
2563
|
rb_scan_args(argc, argv, "11", &key_v, &depth_v);
|
|
2510
|
-
long depth =
|
|
2564
|
+
long depth = zrb_check_depth_or(depth_v, ZRB_DEFAULT_WATCH_DEPTH);
|
|
2511
2565
|
StringValueCStr(key_v);
|
|
2512
2566
|
zrb_session *z = zrb_session_get_open(self);
|
|
2513
2567
|
return zrb_sub_new(self, z, key_v, depth, true);
|
|
@@ -2541,7 +2595,7 @@ static VALUE zrb_session_queryable(int argc, VALUE *argv, VALUE self) {
|
|
|
2541
2595
|
qo.allowed_origin = Z_LOCALITY_REMOTE;
|
|
2542
2596
|
z_result_t ret = z_declare_queryable(z_loan(z->session), &q->qable, z_loan(ke), z_move(cb), &qo);
|
|
2543
2597
|
if (ret != Z_OK) {
|
|
2544
|
-
|
|
2598
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare a queryable on %s (%d)%" PRIsVALUE, key, (int)ret, zrb_last_error());
|
|
2545
2599
|
}
|
|
2546
2600
|
q->declared = true;
|
|
2547
2601
|
q->owner = z;
|
|
@@ -2626,29 +2680,31 @@ static VALUE zrb_run_get(VALUE self, zrb_session *z, zrb_get_args *a, VALUE obj,
|
|
|
2626
2680
|
z_drop(z_move(a->key));
|
|
2627
2681
|
free(a->params);
|
|
2628
2682
|
if (zrb_session_check_link(z)) {
|
|
2629
|
-
|
|
2683
|
+
zrb_raise_code(eClosedError, (int)a->ret, "%s failed: the connection is lost (%d)", what, (int)a->ret);
|
|
2630
2684
|
}
|
|
2631
2685
|
if (a->ret != Z_OK) {
|
|
2632
|
-
|
|
2686
|
+
zrb_raise_code(eZenohError, (int)a->ret, "%s failed (%d)", what, (int)a->ret);
|
|
2633
2687
|
}
|
|
2634
2688
|
zrb_hold_session(obj, self, key_v);
|
|
2635
2689
|
return obj;
|
|
2636
2690
|
}
|
|
2637
2691
|
|
|
2638
|
-
static const char *const zrb_get_kw[] = {"attachment", "target", "consolidation", "encoding",
|
|
2639
|
-
"
|
|
2692
|
+
static const char *const zrb_get_kw[] = {"attachment", "target", "consolidation", "encoding", "priority",
|
|
2693
|
+
"congestion_control", "express", "accept_replies", "depth"};
|
|
2640
2694
|
|
|
2641
2695
|
/* session.get(key, timeout_ms = 2000, params = nil, payload = nil,
|
|
2642
2696
|
* attachment: nil, target: :all, consolidation: :none,
|
|
2643
2697
|
* encoding: nil, priority: nil, congestion_control: nil,
|
|
2644
|
-
* express: nil, accept_replies: nil) -> Get.
|
|
2698
|
+
* express: nil, accept_replies: nil, depth: 1024) -> Get.
|
|
2645
2699
|
* Returns at once; the replies come in on zenoh's threads. key: a String
|
|
2646
|
-
* or a KeyExpr. accept_replies: :matching_query (zenoh's default) or :any.
|
|
2700
|
+
* or a KeyExpr. accept_replies: :matching_query (zenoh's default) or :any.
|
|
2701
|
+
* depth: the replies kept until taken (the oldest go past it; dropped). */
|
|
2647
2702
|
static VALUE zrb_session_get_m(int argc, VALUE *argv, VALUE self) {
|
|
2648
2703
|
VALUE key_v, timeout_v = Qnil, params_v = Qnil, payload = Qnil, opts = Qnil;
|
|
2649
2704
|
rb_scan_args(argc, argv, "13:", &key_v, &timeout_v, ¶ms_v, &payload, &opts);
|
|
2650
2705
|
zrb_opts o;
|
|
2651
|
-
zrb_opts_parse(opts, zrb_get_kw,
|
|
2706
|
+
zrb_opts_parse(opts, zrb_get_kw, 9, &o);
|
|
2707
|
+
long depth = zrb_check_depth_or(o.depth, ZRB_DEFAULT_GET_DEPTH);
|
|
2652
2708
|
VALUE key_str = zrb_key_string(key_v);
|
|
2653
2709
|
long timeout_ms = zrb_check_timeout(timeout_v);
|
|
2654
2710
|
const char *params = NIL_P(params_v) ? NULL : StringValueCStr(params_v);
|
|
@@ -2664,7 +2720,7 @@ static VALUE zrb_session_get_m(int argc, VALUE *argv, VALUE self) {
|
|
|
2664
2720
|
a.z = z;
|
|
2665
2721
|
zrb_key_owned(key_v, &a.key);
|
|
2666
2722
|
zrb_get *g;
|
|
2667
|
-
VALUE obj = zrb_get_new(&g);
|
|
2723
|
+
VALUE obj = zrb_get_new(depth, &g);
|
|
2668
2724
|
z_get_options_default(&a.opts);
|
|
2669
2725
|
a.opts.timeout_ms = (uint64_t)timeout_ms;
|
|
2670
2726
|
a.opts.target = target;
|
|
@@ -2714,7 +2770,7 @@ static VALUE zrb_session_liveliness(VALUE self, VALUE key_v) {
|
|
|
2714
2770
|
VALUE obj = TypedData_Make_Struct(cToken, zrb_token, &zrb_token_type, t);
|
|
2715
2771
|
z_result_t ret = z_liveliness_declare_token(z_loan(z->session), &t->token, z_loan(ke), NULL);
|
|
2716
2772
|
if (ret != Z_OK) {
|
|
2717
|
-
|
|
2773
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare a liveliness token on %s (%d)%" PRIsVALUE, key, (int)ret, zrb_last_error());
|
|
2718
2774
|
}
|
|
2719
2775
|
t->declared = true;
|
|
2720
2776
|
t->owner = z;
|
|
@@ -2724,10 +2780,15 @@ static VALUE zrb_session_liveliness(VALUE self, VALUE key_v) {
|
|
|
2724
2780
|
return obj;
|
|
2725
2781
|
}
|
|
2726
2782
|
|
|
2727
|
-
|
|
2783
|
+
static const char *const zrb_lget_kw[] = {"depth"};
|
|
2784
|
+
|
|
2785
|
+
/* session.liveliness_get(key, timeout_ms = 2000, depth: 1024) -> Get */
|
|
2728
2786
|
static VALUE zrb_session_liveliness_get(int argc, VALUE *argv, VALUE self) {
|
|
2729
|
-
VALUE key_v, timeout_v = Qnil;
|
|
2730
|
-
rb_scan_args(argc, argv, "11", &key_v, &timeout_v);
|
|
2787
|
+
VALUE key_v, timeout_v = Qnil, opts = Qnil;
|
|
2788
|
+
rb_scan_args(argc, argv, "11:", &key_v, &timeout_v, &opts);
|
|
2789
|
+
zrb_opts o;
|
|
2790
|
+
zrb_opts_parse(opts, zrb_lget_kw, 1, &o);
|
|
2791
|
+
long depth = zrb_check_depth_or(o.depth, ZRB_DEFAULT_GET_DEPTH);
|
|
2731
2792
|
const char *key = StringValueCStr(key_v);
|
|
2732
2793
|
long timeout_ms = zrb_check_timeout(timeout_v);
|
|
2733
2794
|
zrb_session *z = zrb_session_get_open(self);
|
|
@@ -2738,7 +2799,7 @@ static VALUE zrb_session_liveliness_get(int argc, VALUE *argv, VALUE self) {
|
|
|
2738
2799
|
a.liveliness = true;
|
|
2739
2800
|
zrb_owned_key(&a.key, key);
|
|
2740
2801
|
zrb_get *g;
|
|
2741
|
-
VALUE obj = zrb_get_new(&g);
|
|
2802
|
+
VALUE obj = zrb_get_new(depth, &g);
|
|
2742
2803
|
z_liveliness_get_options_default(&a.lopts);
|
|
2743
2804
|
a.lopts.timeout_ms = (uint64_t)timeout_ms;
|
|
2744
2805
|
zch_closure_reply(g->ch, &a.cb);
|
|
@@ -2778,8 +2839,9 @@ static VALUE zrb_session_zid(VALUE self) {
|
|
|
2778
2839
|
return out;
|
|
2779
2840
|
}
|
|
2780
2841
|
|
|
2781
|
-
/* session.
|
|
2782
|
-
* normally) for a client session; 0 once closed.
|
|
2842
|
+
/* session.connection_count -> Integer: connected peers (peer mode), or
|
|
2843
|
+
* routers (1 normally) for a client session; 0 once closed. (peers, its
|
|
2844
|
+
* old name, is defined in Ruby with a deprecation warning.) */
|
|
2783
2845
|
static VALUE zrb_session_peers(VALUE self) {
|
|
2784
2846
|
zrb_session *z = zrb_session_get(self);
|
|
2785
2847
|
if (zrb_session_check_link(z)) {
|
|
@@ -2901,13 +2963,13 @@ static void zrb_send_run(zrb_send *s, const char *what) {
|
|
|
2901
2963
|
z_drop(z_move(s->att));
|
|
2902
2964
|
z_drop(z_move(s->enc));
|
|
2903
2965
|
if (zrb_session_check_link(s->z)) {
|
|
2904
|
-
|
|
2966
|
+
zrb_raise_code(eClosedError, (int)s->ret, "%s failed: the connection is lost (%d)", what, (int)s->ret);
|
|
2905
2967
|
}
|
|
2906
2968
|
if (s->undeclared) {
|
|
2907
2969
|
rb_raise(eZenohError, "%s failed: the publisher is closed", what);
|
|
2908
2970
|
}
|
|
2909
2971
|
if (s->ret != Z_OK) {
|
|
2910
|
-
|
|
2972
|
+
zrb_raise_code(eZenohError, (int)s->ret, "%s failed (%d)", what, (int)s->ret);
|
|
2911
2973
|
}
|
|
2912
2974
|
}
|
|
2913
2975
|
|
|
@@ -3059,7 +3121,7 @@ static zrb_pub *zrb_pub_get_open(VALUE self) {
|
|
|
3059
3121
|
rb_raise(eZenohError, "the publisher is closed");
|
|
3060
3122
|
}
|
|
3061
3123
|
if (zrb_session_check_link(p->ent.owner)) {
|
|
3062
|
-
rb_raise(
|
|
3124
|
+
rb_raise(eClosedError, "session is closed");
|
|
3063
3125
|
}
|
|
3064
3126
|
return p;
|
|
3065
3127
|
}
|
|
@@ -3153,7 +3215,7 @@ static VALUE zrb_session_publisher(int argc, VALUE *argv, VALUE self) {
|
|
|
3153
3215
|
}
|
|
3154
3216
|
z_result_t ret = z_declare_publisher(z_loan(z->session), &p->u.p, ke, &po);
|
|
3155
3217
|
if (ret != Z_OK) {
|
|
3156
|
-
|
|
3218
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare a publisher on %" PRIsVALUE " (%d)%" PRIsVALUE, key_str, (int)ret, zrb_last_error());
|
|
3157
3219
|
}
|
|
3158
3220
|
return zrb_pub_wrap(self, z, p, obj, key_str);
|
|
3159
3221
|
}
|
|
@@ -3259,7 +3321,7 @@ static VALUE zrb_session_advanced_publisher(int argc, VALUE *argv, VALUE self) {
|
|
|
3259
3321
|
}
|
|
3260
3322
|
z_result_t ret = ze_declare_advanced_publisher(z_loan(z->session), &p->u.a, ke, &ao);
|
|
3261
3323
|
if (ret != Z_OK) {
|
|
3262
|
-
|
|
3324
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare an advanced publisher on %" PRIsVALUE " (%d)%" PRIsVALUE, key_str, (int)ret, zrb_last_error());
|
|
3263
3325
|
}
|
|
3264
3326
|
return zrb_pub_wrap(self, z, p, obj, key_str);
|
|
3265
3327
|
}
|
|
@@ -3326,7 +3388,7 @@ static VALUE zrb_pub_matching_p(VALUE self) {
|
|
|
3326
3388
|
z_result_t r = p->advanced ? ze_advanced_publisher_get_matching_status(z_loan(p->u.a), &st)
|
|
3327
3389
|
: z_publisher_get_matching_status(z_loan(p->u.p), &st);
|
|
3328
3390
|
if (r != Z_OK) {
|
|
3329
|
-
|
|
3391
|
+
zrb_raise_code(eZenohError, (int)r, "cannot get the matching status (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3330
3392
|
}
|
|
3331
3393
|
return st.matching ? Qtrue : Qfalse;
|
|
3332
3394
|
}
|
|
@@ -3370,7 +3432,7 @@ static zrb_querier *zrb_querier_get_open(VALUE self) {
|
|
|
3370
3432
|
rb_raise(eZenohError, "the querier is closed");
|
|
3371
3433
|
}
|
|
3372
3434
|
if (zrb_session_check_link(q->ent.owner)) {
|
|
3373
|
-
rb_raise(
|
|
3435
|
+
rb_raise(eClosedError, "session is closed");
|
|
3374
3436
|
}
|
|
3375
3437
|
return q;
|
|
3376
3438
|
}
|
|
@@ -3415,7 +3477,7 @@ static VALUE zrb_session_querier(int argc, VALUE *argv, VALUE self) {
|
|
|
3415
3477
|
VALUE obj = TypedData_Make_Struct(cQuerier, zrb_querier, &zrb_querier_type, q);
|
|
3416
3478
|
z_result_t ret = z_declare_querier(z_loan(z->session), &q->q, ke, &qo);
|
|
3417
3479
|
if (ret != Z_OK) {
|
|
3418
|
-
|
|
3480
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare a querier on %" PRIsVALUE " (%d)%" PRIsVALUE, key_str, (int)ret, zrb_last_error());
|
|
3419
3481
|
}
|
|
3420
3482
|
zrb_ent_link(&q->ent, z, ZENT_ENTITY, true, zrb_querier_undeclare);
|
|
3421
3483
|
zrb_hold_session(obj, self, key_str);
|
|
@@ -3449,14 +3511,16 @@ static void *zrb_qget_nogvl(void *p) {
|
|
|
3449
3511
|
return NULL;
|
|
3450
3512
|
}
|
|
3451
3513
|
|
|
3452
|
-
static const char *const zrb_qget_kw[] = {"attachment", "encoding"};
|
|
3514
|
+
static const char *const zrb_qget_kw[] = {"attachment", "encoding", "depth"};
|
|
3453
3515
|
|
|
3454
|
-
/* querier.get(params = nil, payload = nil, attachment: nil, encoding: nil
|
|
3516
|
+
/* querier.get(params = nil, payload = nil, attachment: nil, encoding: nil,
|
|
3517
|
+
* depth: 1024) -> Get */
|
|
3455
3518
|
static VALUE zrb_querier_get_m(int argc, VALUE *argv, VALUE self) {
|
|
3456
3519
|
VALUE params_v = Qnil, payload = Qnil, opts = Qnil;
|
|
3457
3520
|
rb_scan_args(argc, argv, "02:", ¶ms_v, &payload, &opts);
|
|
3458
3521
|
zrb_opts o;
|
|
3459
|
-
zrb_opts_parse(opts, zrb_qget_kw,
|
|
3522
|
+
zrb_opts_parse(opts, zrb_qget_kw, 3, &o);
|
|
3523
|
+
long depth = zrb_check_depth_or(o.depth, ZRB_DEFAULT_GET_DEPTH);
|
|
3460
3524
|
const char *params = NIL_P(params_v) ? NULL : StringValueCStr(params_v);
|
|
3461
3525
|
if (!NIL_P(payload) && !RB_TYPE_P(payload, T_STRING)) {
|
|
3462
3526
|
rb_raise(rb_eTypeError, "payload must be a String");
|
|
@@ -3470,7 +3534,7 @@ static VALUE zrb_querier_get_m(int argc, VALUE *argv, VALUE self) {
|
|
|
3470
3534
|
z_internal_bytes_null(&a.att);
|
|
3471
3535
|
z_internal_encoding_null(&a.enc);
|
|
3472
3536
|
zrb_get *g;
|
|
3473
|
-
VALUE obj = zrb_get_new(&g);
|
|
3537
|
+
VALUE obj = zrb_get_new(depth, &g);
|
|
3474
3538
|
z_querier_get_options_default(&a.opts);
|
|
3475
3539
|
if (!NIL_P(payload)) {
|
|
3476
3540
|
zrb_bytes_from_str(&a.payload, payload, "payload");
|
|
@@ -3493,13 +3557,13 @@ static VALUE zrb_querier_get_m(int argc, VALUE *argv, VALUE self) {
|
|
|
3493
3557
|
z_drop(z_move(a.att));
|
|
3494
3558
|
z_drop(z_move(a.enc));
|
|
3495
3559
|
if (zrb_session_check_link(a.z)) {
|
|
3496
|
-
|
|
3560
|
+
zrb_raise_code(eClosedError, (int)a.ret, "get failed: the connection is lost (%d)", (int)a.ret);
|
|
3497
3561
|
}
|
|
3498
3562
|
if (a.undeclared) {
|
|
3499
3563
|
rb_raise(eZenohError, "get failed: the querier is closed");
|
|
3500
3564
|
}
|
|
3501
3565
|
if (a.ret != Z_OK) {
|
|
3502
|
-
|
|
3566
|
+
zrb_raise_code(eZenohError, (int)a.ret, "get failed (%d)", (int)a.ret);
|
|
3503
3567
|
}
|
|
3504
3568
|
rb_ivar_set(obj, id_iv_session, rb_ivar_get(self, id_iv_session));
|
|
3505
3569
|
return obj;
|
|
@@ -3510,7 +3574,7 @@ static VALUE zrb_querier_matching_p(VALUE self) {
|
|
|
3510
3574
|
z_matching_status_t st = {false};
|
|
3511
3575
|
z_result_t r = z_querier_get_matching_status(z_loan(q->q), &st);
|
|
3512
3576
|
if (r != Z_OK) {
|
|
3513
|
-
|
|
3577
|
+
zrb_raise_code(eZenohError, (int)r, "cannot get the matching status (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3514
3578
|
}
|
|
3515
3579
|
return st.matching ? Qtrue : Qfalse;
|
|
3516
3580
|
}
|
|
@@ -3618,7 +3682,7 @@ static VALUE zrb_pub_matching_listener(int argc, VALUE *argv, VALUE self) {
|
|
|
3618
3682
|
? ze_advanced_publisher_declare_matching_listener(z_loan(p->u.a), &l->u.m, z_move(cb))
|
|
3619
3683
|
: z_publisher_declare_matching_listener(z_loan(p->u.p), &l->u.m, z_move(cb));
|
|
3620
3684
|
if (r != Z_OK) {
|
|
3621
|
-
|
|
3685
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare a matching listener (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3622
3686
|
}
|
|
3623
3687
|
zrb_lst_linked(obj, l, p->ent.owner, self);
|
|
3624
3688
|
return obj;
|
|
@@ -3634,7 +3698,7 @@ static VALUE zrb_querier_matching_listener(int argc, VALUE *argv, VALUE self) {
|
|
|
3634
3698
|
z_closure_matching_status(&cb, zev_on_matching, zevq_on_drop, zevq_ref(l->q));
|
|
3635
3699
|
z_result_t r = z_querier_declare_matching_listener(z_loan(q->q), &l->u.m, z_move(cb));
|
|
3636
3700
|
if (r != Z_OK) {
|
|
3637
|
-
|
|
3701
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare a matching listener (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3638
3702
|
}
|
|
3639
3703
|
zrb_lst_linked(obj, l, q->ent.owner, self);
|
|
3640
3704
|
return obj;
|
|
@@ -3666,7 +3730,7 @@ static VALUE zrb_session_transport_events(int argc, VALUE *argv, VALUE self) {
|
|
|
3666
3730
|
to.history = history;
|
|
3667
3731
|
z_result_t r = z_declare_transport_events_listener(z_loan(z->session), &l->u.t, z_move(cb), &to);
|
|
3668
3732
|
if (r != Z_OK) {
|
|
3669
|
-
|
|
3733
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare a transport events listener (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3670
3734
|
}
|
|
3671
3735
|
zrb_lst_linked(obj, l, z, self);
|
|
3672
3736
|
return obj;
|
|
@@ -3689,7 +3753,7 @@ static VALUE zrb_session_link_events(int argc, VALUE *argv, VALUE self) {
|
|
|
3689
3753
|
lo.history = history;
|
|
3690
3754
|
z_result_t r = z_declare_link_events_listener(z_loan(z->session), &l->u.l, z_move(cb), &lo);
|
|
3691
3755
|
if (r != Z_OK) {
|
|
3692
|
-
|
|
3756
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare a link events listener (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3693
3757
|
}
|
|
3694
3758
|
zrb_lst_linked(obj, l, z, self);
|
|
3695
3759
|
return obj;
|
|
@@ -3777,7 +3841,7 @@ static VALUE zrb_session_advanced_subscriber(int argc, VALUE *argv, VALUE self)
|
|
|
3777
3841
|
zch_closure_sample(s->ch, &cb);
|
|
3778
3842
|
z_result_t ret = ze_declare_advanced_subscriber(z_loan(z->session), &s->u.adv, ke, z_move(cb), &ao);
|
|
3779
3843
|
if (ret != Z_OK) {
|
|
3780
|
-
|
|
3844
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot declare an advanced subscriber on %" PRIsVALUE " (%d)%" PRIsVALUE, key_str, (int)ret, zrb_last_error());
|
|
3781
3845
|
}
|
|
3782
3846
|
s->declared = true;
|
|
3783
3847
|
s->owner = z;
|
|
@@ -3793,7 +3857,7 @@ static zrb_sub *zrb_advsub_get_open(VALUE self) {
|
|
|
3793
3857
|
rb_raise(eZenohError, "the subscriber is closed");
|
|
3794
3858
|
}
|
|
3795
3859
|
if (zrb_session_check_link(s->owner)) {
|
|
3796
|
-
rb_raise(
|
|
3860
|
+
rb_raise(eClosedError, "session is closed");
|
|
3797
3861
|
}
|
|
3798
3862
|
return s;
|
|
3799
3863
|
}
|
|
@@ -3811,7 +3875,7 @@ static VALUE zrb_advsub_miss_listener(int argc, VALUE *argv, VALUE self) {
|
|
|
3811
3875
|
ze_closure_miss(&cb, zev_on_miss, zevq_on_drop, zevq_ref(l->q));
|
|
3812
3876
|
z_result_t r = ze_advanced_subscriber_declare_sample_miss_listener(z_loan(s->u.adv), &l->u.s, z_move(cb));
|
|
3813
3877
|
if (r != Z_OK) {
|
|
3814
|
-
|
|
3878
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare a sample miss listener (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3815
3879
|
}
|
|
3816
3880
|
zrb_lst_linked(obj, l, s->owner, self);
|
|
3817
3881
|
return obj;
|
|
@@ -3842,7 +3906,7 @@ static VALUE zrb_advsub_detect_publishers(int argc, VALUE *argv, VALUE self) {
|
|
|
3842
3906
|
lo.history = history;
|
|
3843
3907
|
z_result_t ret = ze_advanced_subscriber_detect_publishers(z_loan(as->u.adv), &s->u.sub, z_move(cb), &lo);
|
|
3844
3908
|
if (ret != Z_OK) {
|
|
3845
|
-
|
|
3909
|
+
zrb_raise_code(eZenohError, (int)ret, "cannot detect publishers (%d)%" PRIsVALUE, (int)ret, zrb_last_error());
|
|
3846
3910
|
}
|
|
3847
3911
|
s->declared = true;
|
|
3848
3912
|
s->owner = as->owner;
|
|
@@ -3970,7 +4034,7 @@ static VALUE zrb_session_declare_keyexpr(VALUE self, VALUE key_v) {
|
|
|
3970
4034
|
z_internal_keyexpr_null(&k->decl);
|
|
3971
4035
|
z_result_t r = z_declare_keyexpr(z_loan(z->session), &k->decl, ke);
|
|
3972
4036
|
if (r != Z_OK) {
|
|
3973
|
-
|
|
4037
|
+
zrb_raise_code(eZenohError, (int)r, "cannot declare the key expression (%d)%" PRIsVALUE, (int)r, zrb_last_error());
|
|
3974
4038
|
}
|
|
3975
4039
|
zrb_ent_link(&k->ent, z, ZENT_KEYEXPR, true, zrb_ke_undeclare);
|
|
3976
4040
|
rb_ivar_set(obj, id_iv_session, self);
|
|
@@ -4032,7 +4096,7 @@ static VALUE zrb_s_scout(VALUE mod, VALUE what_v, VALUE timeout_v, VALUE config_
|
|
|
4032
4096
|
VALUE out = zevq_each_pending_noblock(q, false);
|
|
4033
4097
|
zevq_unref(q);
|
|
4034
4098
|
if (a.ret != Z_OK) {
|
|
4035
|
-
|
|
4099
|
+
zrb_raise_code(eZenohError, (int)a.ret, "scouting failed (%d)", (int)a.ret);
|
|
4036
4100
|
}
|
|
4037
4101
|
return out;
|
|
4038
4102
|
}
|
|
@@ -4063,11 +4127,23 @@ void Init_asterism_zenoh(void) {
|
|
|
4063
4127
|
/* Asterism::Zenoh. No top-level Zenoh (require "asterism/zenoh/global"). */
|
|
4064
4128
|
mAsterism = rb_define_module("Asterism");
|
|
4065
4129
|
mZenoh = rb_define_module_under(mAsterism, "Zenoh");
|
|
4066
|
-
|
|
4130
|
+
/* The root of every Asterism error. Defined here because this binding
|
|
4131
|
+
* loads first; the asterism gem reopens it (same superclass). */
|
|
4132
|
+
eAsterismError = rb_define_class_under(mAsterism, "Error", rb_eStandardError);
|
|
4133
|
+
eZenohError = rb_define_class_under(mZenoh, "Error", eAsterismError);
|
|
4134
|
+
/* The session is closed, or its connection was lost. */
|
|
4135
|
+
eClosedError = rb_define_class_under(mZenoh, "ClosedError", eZenohError);
|
|
4067
4136
|
rb_define_const(mZenoh, "C_VERSION", rb_str_freeze(rb_str_new_cstr(ZENOH_C)));
|
|
4068
4137
|
rb_define_const(mZenoh, "CONNECT_TIMEOUT_MS", INT2FIX(ZRB_CONNECT_TIMEOUT_MS));
|
|
4069
4138
|
rb_define_const(mZenoh, "SEND_TIMEOUT_MS", INT2FIX(ZRB_SEND_TIMEOUT_MS));
|
|
4070
4139
|
rb_define_const(mZenoh, "PEER", Qtrue);
|
|
4140
|
+
/* Queue depths: the default of subscribe, queryable and the listeners;
|
|
4141
|
+
* of get, liveliness_get and querier.get; of liveliness_watch; and the
|
|
4142
|
+
* largest accepted. */
|
|
4143
|
+
rb_define_const(mZenoh, "DEFAULT_DEPTH", INT2FIX(ZRB_DEFAULT_DEPTH));
|
|
4144
|
+
rb_define_const(mZenoh, "DEFAULT_GET_DEPTH", INT2FIX(ZRB_DEFAULT_GET_DEPTH));
|
|
4145
|
+
rb_define_const(mZenoh, "DEFAULT_WATCH_DEPTH", INT2FIX(ZRB_DEFAULT_WATCH_DEPTH));
|
|
4146
|
+
rb_define_const(mZenoh, "MAX_DEPTH", INT2FIX(ZRB_MAX_DEPTH));
|
|
4071
4147
|
rb_define_const(mZenoh, "MAX_PEERS", LONG2NUM(zrb_default_max_sessions()));
|
|
4072
4148
|
|
|
4073
4149
|
id_attachment = rb_intern("attachment");
|
|
@@ -4078,6 +4154,8 @@ void Init_asterism_zenoh(void) {
|
|
|
4078
4154
|
id_listen = rb_intern("listen");
|
|
4079
4155
|
id_iv_session = rb_intern("@session");
|
|
4080
4156
|
id_iv_key = rb_intern("@key");
|
|
4157
|
+
id_iv_code = rb_intern("@code");
|
|
4158
|
+
id_iv_qkey = rb_intern("@asterism_queryable_key");
|
|
4081
4159
|
id_iv_parent = rb_intern("@parent");
|
|
4082
4160
|
id_config = rb_intern("config");
|
|
4083
4161
|
id_config_file = rb_intern("config_file");
|
|
@@ -4119,7 +4197,7 @@ void Init_asterism_zenoh(void) {
|
|
|
4119
4197
|
rb_define_method(cSession, "liveliness_watch", zrb_session_liveliness_watch, -1);
|
|
4120
4198
|
rb_define_method(cSession, "liveliness_get", zrb_session_liveliness_get, -1);
|
|
4121
4199
|
rb_define_method(cSession, "poll", zrb_session_poll, -1);
|
|
4122
|
-
rb_define_method(cSession, "
|
|
4200
|
+
rb_define_method(cSession, "connection_count", zrb_session_peers, 0);
|
|
4123
4201
|
rb_define_method(cSession, "zid", zrb_session_zid, 0);
|
|
4124
4202
|
rb_define_method(cSession, "closed?", zrb_session_closed_p, 0);
|
|
4125
4203
|
rb_define_method(cSession, "close", zrb_session_close, 0);
|