zyre 0.1.0 → 0.4.1

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.
data/ext/zyre_ext/event.c CHANGED
@@ -15,14 +15,13 @@ VALUE rzyre_cZyreEvent;
15
15
  static void rzyre_event_free( void *ptr );
16
16
 
17
17
  static const rb_data_type_t rzyre_event_t = {
18
- "Zyre::Event",
19
- {
20
- NULL,
21
- rzyre_event_free
18
+ .wrap_struct_name = "Zyre::Event",
19
+ .function = {
20
+ .dmark = NULL,
21
+ .dfree = rzyre_event_free,
22
22
  },
23
- 0,
24
- 0,
25
- RUBY_TYPED_FREE_IMMEDIATELY,
23
+ .data = NULL,
24
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
26
25
  };
27
26
 
28
27
 
@@ -78,7 +77,7 @@ rzyre_read_event( void *node_ptr )
78
77
  assert( node_ptr );
79
78
 
80
79
  event_ptr = zyre_event_new( (zyre_t *)node_ptr );
81
- assert( event_ptr );
80
+
82
81
  return (void *)event_ptr;
83
82
  }
84
83
 
@@ -104,7 +103,13 @@ rzyre_event_s_from_node( VALUE klass, VALUE node )
104
103
  const char *event_type = zyre_event_type( event );
105
104
  VALUE event_type_s = rb_utf8_str_new_cstr( event_type );
106
105
  VALUE event_class = rb_funcall( klass, rb_intern("type_by_name"), 1, event_type_s );
107
- VALUE event_instance = rb_class_new_instance( 0, NULL, event_class );
106
+ VALUE event_instance;
107
+
108
+ if ( !RTEST(event_class) ) {
109
+ rb_raise( rb_eRuntimeError, "Unhandled event type '%s'", event_type );
110
+ }
111
+
112
+ event_instance = rb_class_new_instance( 0, NULL, event_class );
108
113
 
109
114
  RTYPEDDATA_DATA( event_instance ) = event;
110
115
 
@@ -121,6 +126,7 @@ rzyre_copy_string( VALUE string )
121
126
  const char *c_string = StringValueCStr( string );
122
127
  char *copy = (char *) zmalloc( strnlen(c_string, BUFSIZ) + 1 );
123
128
 
129
+ rzyre_log( "debug", "Copying string `%s`.", c_string );
124
130
  assert( copy );
125
131
  stpncpy( copy, c_string, strnlen(c_string, BUFSIZ) + 1 );
126
132
 
@@ -134,6 +140,7 @@ rzyre_copy_required_string( VALUE string, const char *field_name )
134
140
  if ( RB_TYPE_P(string, T_UNDEF) ) {
135
141
  rb_raise( rb_eArgError, "missing required field :%s", field_name );
136
142
  } else {
143
+ rzyre_log( "debug", "Required field %s is defined.", field_name );
137
144
  return rzyre_copy_string( string );
138
145
  }
139
146
  }
@@ -182,27 +189,37 @@ static VALUE
182
189
  rzyre_event_s_synthesize( int argc, VALUE *argv, VALUE klass )
183
190
  {
184
191
  VALUE rval, event_type, peer_uuid, kwargs, event_class;
185
- static VALUE kwvals[5];
192
+ VALUE kwvals[5] = { Qundef, Qundef, Qundef, Qundef, Qundef };
186
193
  static ID keyword_ids[5];
187
194
  zyre_event_t *ptr = NULL;
188
195
 
189
196
  // Parse the arguments + keyword arguments
190
197
  if ( !keyword_ids[0] ) {
191
- CONST_ID( keyword_ids[0], "peer_name");
192
- CONST_ID( keyword_ids[1], "headers");
193
- CONST_ID( keyword_ids[2], "peer_addr");
194
- CONST_ID( keyword_ids[3], "group");
195
- CONST_ID( keyword_ids[4], "msg");
198
+ CONST_ID( keyword_ids[0], "peer_name" );
199
+ CONST_ID( keyword_ids[1], "headers" );
200
+ CONST_ID( keyword_ids[2], "peer_addr" );
201
+ CONST_ID( keyword_ids[3], "group" );
202
+ CONST_ID( keyword_ids[4], "msg" );
196
203
  }
197
204
 
205
+ rzyre_log( "debug", "Scanning %d synthesize args.", argc );
198
206
  rb_scan_args( argc, argv, "2:", &event_type, &peer_uuid, &kwargs );
199
207
  if ( RTEST(kwargs) ) {
208
+ rzyre_log( "debug", " scanning keyword args: %s", RSTRING_PTR(rb_inspect(kwargs)) );
200
209
  rb_get_kwargs( kwargs, keyword_ids, 0, 5, kwvals );
201
210
  }
202
211
 
203
212
  // Translate the event type argument into the appropriate class and instantiate it
213
+ rzyre_log( "debug", "Creating an instance of a %s event.", RSTRING_PTR(rb_inspect(event_type )) );
204
214
  event_class = rb_funcall( klass, rb_intern("type_by_name"), 1, event_type );
205
- event_type = rb_funcall( event_class, rb_intern("type_name"), 0 );
215
+
216
+ if ( RTEST(event_class) ) {
217
+ event_type = rb_funcall( event_class, rb_intern("type_name"), 0 );
218
+ } else {
219
+ rb_raise( rb_eArgError, "don't know how to create %s events",
220
+ RSTRING_PTR(rb_inspect(event_type)) );
221
+ }
222
+
206
223
  rval = rb_class_new_instance( 0, NULL, event_class );
207
224
 
208
225
  // Set up the zyre_event memory for the object
@@ -213,6 +230,7 @@ rzyre_event_s_synthesize( int argc, VALUE *argv, VALUE klass )
213
230
  ptr->peer_uuid = rzyre_copy_string( peer_uuid );
214
231
 
215
232
  // Set the peer_name or default it if it wasn't specified
233
+ rzyre_log( "debug", "Starting type-specific setup." );
216
234
  if ( !RB_TYPE_P(kwvals[0], T_UNDEF) ) {
217
235
  ptr->peer_name = rzyre_copy_string( kwvals[0] );
218
236
  } else {
@@ -234,27 +252,28 @@ rzyre_event_s_synthesize( int argc, VALUE *argv, VALUE klass )
234
252
  ptr->group = rzyre_copy_required_string( kwvals[3], "group" );
235
253
  }
236
254
  else if ( streq(ptr->type, "WHISPER") ) {
237
- const char *msg_str = rzyre_copy_required_string( kwvals[4], "msg" );
238
- zmsg_t *msg = zmsg_new();
255
+ if ( RB_TYPE_P(kwvals[4], T_UNDEF) )
256
+ rb_raise( rb_eArgError, "missing required field :msg" );
239
257
 
240
- zmsg_addstr( msg, msg_str );
241
- ptr->msg = msg;
242
- msg = NULL;
258
+ rzyre_log( "debug", "Making a WHISPER zmsg from the :msg value: %s",
259
+ RSTRING_PTR(rb_inspect(kwvals[4])) );
260
+ ptr->msg = rzyre_make_zmsg_from( kwvals[4] );
243
261
  }
244
262
  else if ( streq(ptr->type, "SHOUT") ) {
245
- const char *msg_str = rzyre_copy_required_string( kwvals[4], "msg" );
246
- zmsg_t *msg = zmsg_new();
247
-
248
- zmsg_addstr( msg, msg_str );
263
+ if ( RB_TYPE_P(kwvals[4], T_UNDEF) )
264
+ rb_raise( rb_eArgError, "missing required field :msg" );
249
265
 
266
+ rzyre_log( "debug", "Making a SHOUT zmsg from the :msg value: %s",
267
+ RSTRING_PTR(rb_inspect(kwvals[4])) );
250
268
  ptr->group = rzyre_copy_required_string( kwvals[3], "group" );
251
- ptr->msg = msg;
252
- msg = NULL;
269
+ ptr->msg = rzyre_make_zmsg_from( kwvals[4] );
253
270
  }
254
271
  else if ( streq(ptr->type, "LEADER") ) {
255
272
  ptr->group = rzyre_copy_required_string( kwvals[3], "group" );
256
273
  }
257
274
 
275
+ rzyre_log_obj( rval, "debug", "Synthesized a %s event.", ptr->type );
276
+
258
277
  return rval;
259
278
  }
260
279
 
@@ -397,9 +416,32 @@ rzyre_event_group( VALUE self ) {
397
416
 
398
417
  /*
399
418
  * call-seq:
400
- * event.event_msg
419
+ * event.msg_size -> int
420
+ *
421
+ * Return the number of frames present in the event's message (if it has one). Returns
422
+ * nil if there is no message.
401
423
  *
402
- * Returns the incoming message payload.
424
+ */
425
+ static VALUE
426
+ rzyre_event_msg_size( VALUE self )
427
+ {
428
+ zyre_event_t *ptr = rzyre_get_event( self );
429
+ zmsg_t *msg = zyre_event_msg( ptr );
430
+ VALUE rval = Qnil;
431
+
432
+ if ( msg ) {
433
+ rval = INT2FIX( zmsg_size(msg) );
434
+ }
435
+
436
+ return rval;
437
+ }
438
+
439
+
440
+ /*
441
+ * call-seq:
442
+ * event.msg
443
+ *
444
+ * Returns the data from the first frame of the message from the receiver.
403
445
  */
404
446
  static VALUE
405
447
  rzyre_event_msg( VALUE self ) {
@@ -407,15 +449,43 @@ rzyre_event_msg( VALUE self ) {
407
449
  zmsg_t *msg = zyre_event_msg( ptr );
408
450
  VALUE rval = Qnil;
409
451
 
410
- // :TODO: Support multipart messages when Zyre does.
411
452
  if ( msg ) {
412
453
  zframe_t *frame = zmsg_first( msg );
413
- char *str = zframe_strdup( frame );
454
+ byte *data = zframe_data( frame );
414
455
 
415
- rval = rb_utf8_str_new( str, zframe_size(frame) );
456
+ rval = rb_enc_str_new( (const char *)data, zframe_size(frame), rb_ascii8bit_encoding() );
416
457
  rb_obj_freeze( rval );
458
+ }
459
+
460
+ return rval;
461
+ }
462
+
417
463
 
418
- free( str );
464
+ /*
465
+ * call-seq:
466
+ * event.multipart_msg
467
+ *
468
+ * Returns the data from every frame of the message from the receiver.
469
+ */
470
+ static VALUE
471
+ rzyre_event_multipart_msg( VALUE self ) {
472
+ zyre_event_t *ptr = rzyre_get_event( self );
473
+ zmsg_t *msg = zyre_event_msg( ptr );
474
+ VALUE rval = rb_ary_new();
475
+
476
+ if ( msg ) {
477
+ zframe_t *frame = zmsg_first( msg );
478
+
479
+ while ( frame ) {
480
+ char *str = zframe_strdup( frame );
481
+ VALUE data = rb_enc_str_new( str, zframe_size(frame), rb_ascii8bit_encoding() );
482
+
483
+ rb_obj_freeze( data );
484
+ rb_ary_push( rval, data );
485
+
486
+ free( str );
487
+ frame = zmsg_next( msg );
488
+ }
419
489
  }
420
490
 
421
491
  return rval;
@@ -471,7 +541,9 @@ rzyre_init_event( void ) {
471
541
  rb_define_method( rzyre_cZyreEvent, "headers", rzyre_event_headers, 0 );
472
542
  rb_define_method( rzyre_cZyreEvent, "header", rzyre_event_header, 1 );
473
543
  rb_define_method( rzyre_cZyreEvent, "group", rzyre_event_group, 0 );
544
+ rb_define_method( rzyre_cZyreEvent, "msg_size", rzyre_event_msg_size, 0 );
474
545
  rb_define_method( rzyre_cZyreEvent, "msg", rzyre_event_msg, 0 );
546
+ rb_define_method( rzyre_cZyreEvent, "multipart_msg", rzyre_event_multipart_msg, 0 );
475
547
  rb_define_method( rzyre_cZyreEvent, "print", rzyre_event_print, 0 );
476
548
 
477
549
  rb_require( "zyre/event" );
@@ -19,6 +19,11 @@ have_header( 'ruby/thread.h' ) or
19
19
 
20
20
  have_func( 'zyre_set_name', 'zyre.h' )
21
21
  have_func( 'zyre_set_silent_timeout', 'zyre.h' )
22
+ have_func( 'zyre_set_beacon_peer_port', 'zyre.h' )
23
+ have_func( 'zyre_set_contest_in_group', 'zyre.h' )
24
+ have_func( 'zyre_set_zcert', 'zyre.h' )
25
+
26
+ have_func( 'zcert_unset_meta', 'czmq.h' )
22
27
 
23
28
  create_header()
24
29
  create_makefile( 'zyre_ext' )
data/ext/zyre_ext/node.c CHANGED
@@ -8,21 +8,26 @@
8
8
  */
9
9
 
10
10
  #include "zyre_ext.h"
11
+ #include "extconf.h"
11
12
 
12
13
 
13
14
  VALUE rzyre_cZyreNode;
14
15
 
16
+ // Null key; means curve isn't available or the secret side of a public cert.
17
+ #define FORTY_ZEROES "0000000000000000000000000000000000000000"
18
+
19
+
15
20
  static void rzyre_node_free( void *ptr );
16
21
 
22
+
17
23
  static const rb_data_type_t rzyre_node_t = {
18
- "Zyre::Node",
19
- {
20
- NULL,
21
- rzyre_node_free
24
+ .wrap_struct_name = "Zyre::Node",
25
+ .function = {
26
+ .dmark = NULL,
27
+ .dfree = rzyre_node_free,
22
28
  },
23
- 0,
24
- 0,
25
- RUBY_TYPED_FREE_IMMEDIATELY,
29
+ .data = NULL,
30
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
26
31
  };
27
32
 
28
33
 
@@ -38,6 +43,7 @@ rzyre_node_free( void *ptr )
38
43
  }
39
44
 
40
45
 
46
+
41
47
  /*
42
48
  * Alloc function
43
49
  */
@@ -512,9 +518,7 @@ rzyre_node_leave( VALUE self, VALUE group )
512
518
  * call-seq:
513
519
  * node.recv -> zyre_event
514
520
  *
515
- * Receive the next event from the network; the message may be a control
516
- * message (ENTER, EXIT, JOIN, LEAVE) or data (WHISPER, SHOUT).
517
- * Returns a Zyre::Event.
521
+ * Receive the next event from the network as a Zyre::Event.
518
522
  *
519
523
  */
520
524
  static VALUE
@@ -526,23 +530,26 @@ rzyre_node_recv( VALUE self )
526
530
 
527
531
  /*
528
532
  * call-seq:
529
- * node.whisper( peer_uuid, message ) -> int
533
+ * node.whisper( peer_uuid, *messages ) -> int
530
534
  *
531
535
  * Send a +message+ to a single +peer+ specified as a UUID string.
532
536
  *
533
537
  */
534
538
  static VALUE
535
- rzyre_node_whisper( VALUE self, VALUE peer_uuid, VALUE msg )
539
+ rzyre_node_whisper( int argc, VALUE *argv, VALUE self )
536
540
  {
537
541
  zyre_t *ptr = rzyre_get_node( self );
538
- const char *peer_str = StringValueCStr( peer_uuid ),
539
- *msg_str = StringValueCStr( msg );
542
+ VALUE peer_uuid, msg_parts;
543
+ char *peer_uuid_str;
544
+ zmsg_t *msg;
540
545
  int rval;
541
546
 
542
- assert( peer_str );
543
- assert( msg_str );
547
+ rb_scan_args( argc, argv, "1*", &peer_uuid, &msg_parts );
548
+
549
+ peer_uuid_str = StringValueCStr( peer_uuid );
550
+ msg = rzyre_make_zmsg_from( msg_parts );
544
551
 
545
- rval = zyre_whispers( ptr, peer_str, "%s", msg_str );
552
+ rval = zyre_whisper( ptr, peer_uuid_str, &msg );
546
553
 
547
554
  return rval ? Qtrue : Qfalse;
548
555
  }
@@ -550,23 +557,26 @@ rzyre_node_whisper( VALUE self, VALUE peer_uuid, VALUE msg )
550
557
 
551
558
  /*
552
559
  * call-seq:
553
- * node.shout( group, message ) -> int
560
+ * node.shout( group, *messages ) -> int
554
561
  *
555
562
  * Send +message+ to a named +group+.
556
563
  *
557
564
  */
558
565
  static VALUE
559
- rzyre_node_shout( VALUE self, VALUE group, VALUE msg )
566
+ rzyre_node_shout( int argc, VALUE *argv, VALUE self )
560
567
  {
561
568
  zyre_t *ptr = rzyre_get_node( self );
562
- const char *group_str = StringValueCStr( group ),
563
- *msg_str = StringValueCStr( msg );
569
+ VALUE group, msg_parts;
570
+ char *group_str;
571
+ zmsg_t *msg;
564
572
  int rval;
565
573
 
566
- assert( group_str );
567
- assert( msg_str );
574
+ rb_scan_args( argc, argv, "1*", &group, &msg_parts );
568
575
 
569
- rval = zyre_shouts( ptr, group_str, "%s", msg_str );
576
+ group_str = StringValueCStr( group );
577
+ msg = rzyre_make_zmsg_from( msg_parts );
578
+
579
+ rval = zyre_shout( ptr, group_str, &msg );
570
580
 
571
581
  return rval ? Qtrue : Qfalse;
572
582
  }
@@ -765,6 +775,241 @@ rzyre_node_print( VALUE self )
765
775
  }
766
776
 
767
777
 
778
+ /* --------------------------------------------------------------
779
+ * Draft API
780
+ * -------------------------------------------------------------- */
781
+
782
+
783
+ #define RAISE_NO_DRAFT_APIS()\
784
+ rb_raise( rb_eNotImpError, "Zyre was not built with Draft APIs!" ); \
785
+ return Qnil;
786
+
787
+ /*
788
+ * call-seq:
789
+ * node.beacon_peer_port = 16668
790
+ *
791
+ * Set the TCP port bound by the ROUTER peer-to-peer socket (beacon mode).
792
+ * Defaults to * (the port is randomly assigned by the system).
793
+ * This call overrides this, to bypass some firewall issues when ports are
794
+ * random. Has no effect after #start.
795
+ *
796
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
797
+ * removed at any time.
798
+ */
799
+ static VALUE
800
+ rzyre_node_beacon_peer_port_eq( VALUE self, VALUE port_number )
801
+ {
802
+ #ifdef ZYRE_BUILD_DRAFT_API
803
+ zyre_t *ptr = rzyre_get_node( self );
804
+
805
+ zyre_set_beacon_peer_port( ptr, FIX2INT(port_number) );
806
+
807
+ return port_number;
808
+ #else
809
+ RAISE_NO_DRAFT_APIS();
810
+ #endif // ZYRE_BUILD_DRAFT_API
811
+ }
812
+
813
+
814
+ /*
815
+ * call-seq:
816
+ * node.set_contest_in_group( group )
817
+ *
818
+ * This options enables a peer to actively contest for leadership in the
819
+ * given +group+. If this option is not set the peer will still participate in
820
+ * elections but never gets elected. This ensures that a consent for a leader
821
+ * is reached within a group even though not every peer is contesting for
822
+ * leadership.
823
+ *
824
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
825
+ * removed at any time.
826
+ */
827
+ static VALUE
828
+ rzyre_node_set_contest_in_group( VALUE self, VALUE group_name )
829
+ {
830
+ #ifdef ZYRE_BUILD_DRAFT_API
831
+ zyre_t *ptr = rzyre_get_node( self );
832
+ const char *group_str = StringValueCStr( group_name );
833
+
834
+ zyre_set_contest_in_group( ptr, group_str );
835
+
836
+ return group_name;
837
+ #else
838
+ RAISE_NO_DRAFT_APIS();
839
+ #endif // ZYRE_BUILD_DRAFT_API
840
+ }
841
+
842
+
843
+ /*
844
+ * call-seq:
845
+ * node.advertised_endpoint = endpoint
846
+ *
847
+ * Set an alternative +endpoint+ value when using GOSSIP ONLY. This is useful
848
+ * if you're advertising an endpoint behind a NAT.
849
+ *
850
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
851
+ * removed at any time.
852
+ */
853
+ static VALUE
854
+ rzyre_node_advertised_endpoint_eq( VALUE self, VALUE endpoint )
855
+ {
856
+ #ifdef ZYRE_BUILD_DRAFT_API
857
+ zyre_t *ptr = rzyre_get_node( self );
858
+ const char *endpoint_str = StringValueCStr( endpoint );
859
+
860
+ zyre_set_advertised_endpoint( ptr, endpoint_str );
861
+
862
+ return endpoint;
863
+ #else
864
+ RAISE_NO_DRAFT_APIS();
865
+ #endif // ZYRE_BUILD_DRAFT_API
866
+ }
867
+
868
+
869
+ /*
870
+ * call-seq:
871
+ * node.zcert = zcert
872
+ *
873
+ * Apply a +zcert+ to a Zyre node. See Zyre::Cert#apply and
874
+ * Authentication[rdoc-ref:Authentication].
875
+ *
876
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
877
+ * removed at any time.
878
+ */
879
+ static VALUE
880
+ rzyre_node_zcert_eq( VALUE self, VALUE cert )
881
+ {
882
+ #ifdef ZYRE_BUILD_DRAFT_API
883
+ zyre_t *ptr = rzyre_get_node( self );
884
+ zcert_t *zcert = rzyre_get_cert( cert );
885
+
886
+ if ( streq(zcert_secret_txt(zcert), FORTY_ZEROES) ) {
887
+ rb_raise( rb_eArgError,
888
+ "can't use this cert for authentication (no curve or missing secret key)" );
889
+ }
890
+
891
+ zyre_set_zcert( ptr, zcert );
892
+
893
+ return Qtrue;
894
+ #else
895
+ RAISE_NO_DRAFT_APIS();
896
+ #endif // ZYRE_BUILD_DRAFT_API
897
+ }
898
+
899
+
900
+ /*
901
+ * call-seq:
902
+ * node.zap_domain = domain
903
+ *
904
+ * Specify the ZAP domain (for use with CURVE authentication). See
905
+ * Authentication[rdoc-ref:Authentication].
906
+ *
907
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
908
+ * removed at any time.
909
+ */
910
+ static VALUE
911
+ rzyre_node_zap_domain_eq( VALUE self, VALUE domain )
912
+ {
913
+ #ifdef ZYRE_BUILD_DRAFT_API
914
+ zyre_t *ptr = rzyre_get_node( self );
915
+ const char *domain_str = StringValueCStr( domain );
916
+
917
+ zyre_set_zap_domain( ptr, domain_str );
918
+
919
+ return Qtrue;
920
+ #else
921
+ RAISE_NO_DRAFT_APIS();
922
+ #endif // ZYRE_BUILD_DRAFT_API
923
+ }
924
+
925
+
926
+ /*
927
+ * call-seq:
928
+ * node.gossip_connect_curve( public_key, endpoint )
929
+ *
930
+ * Connect to the gossip discovery endpoint with CURVE enabled. The +public_key+ is the
931
+ * Z85-armored public key of the connecting node's cert/
932
+ *
933
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
934
+ * removed at any time.
935
+ */
936
+ static VALUE
937
+ rzyre_node_gossip_connect_curve( VALUE self, VALUE public_key, VALUE endpoint )
938
+ {
939
+ #ifdef ZYRE_BUILD_DRAFT_API
940
+ zyre_t *ptr = rzyre_get_node( self );
941
+ const char *endpoint_str = StringValueCStr( endpoint );
942
+ const char *key = StringValueCStr( public_key );
943
+
944
+ assert( endpoint_str );
945
+ assert( key );
946
+
947
+ rzyre_log_obj( self, "debug", "Connecting to gossip endpoint %s (CURVE enabled).", endpoint_str );
948
+ zyre_gossip_connect_curve( ptr, key, "%s", endpoint_str );
949
+
950
+ return Qtrue;
951
+ #else
952
+ RAISE_NO_DRAFT_APIS();
953
+ #endif // ZYRE_BUILD_DRAFT_API
954
+ }
955
+
956
+
957
+ /*
958
+ * call-seq:
959
+ * node.gossip_unpublish( node_uuid )
960
+ *
961
+ * Unpublish a GOSSIP node from local list, useful in removing nodes from list
962
+ * when they EXIT.
963
+ *
964
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
965
+ * removed at any time.
966
+ */
967
+ static VALUE
968
+ rzyre_node_gossip_unpublish( VALUE self, VALUE node_uuid )
969
+ {
970
+ #ifdef ZYRE_BUILD_DRAFT_API
971
+ zyre_t *ptr = rzyre_get_node( self );
972
+ const char *node = StringValueCStr( node_uuid );
973
+
974
+ zyre_gossip_unpublish( ptr, node );
975
+
976
+ return Qtrue;
977
+ #else
978
+ RAISE_NO_DRAFT_APIS();
979
+ #endif // ZYRE_BUILD_DRAFT_API
980
+ }
981
+
982
+
983
+ /*
984
+ * call-seq:
985
+ * node.require_peer( node_uuid, router_endpoint, public_key )
986
+ *
987
+ * Explicitly connect to a peer with the given +node_uuid+ via the specified
988
+ * +router_endpoint+, using the given +public_key+ to authenticate.
989
+ *
990
+ * Note: this is part of the ZRE 43 Draft API, and may be changed or
991
+ * removed at any time.
992
+ */
993
+ static VALUE
994
+ rzyre_node_require_peer( VALUE self, VALUE uuid, VALUE endpoint, VALUE public_key )
995
+ {
996
+ #ifdef ZYRE_BUILD_DRAFT_API
997
+ zyre_t *ptr = rzyre_get_node( self );
998
+ const char *uuid_str = StringValueCStr( uuid ),
999
+ *endpoint_str = StringValueCStr( endpoint ),
1000
+ *key_str = StringValueCStr( public_key );
1001
+ int rval;
1002
+
1003
+ rval = zyre_require_peer( ptr, uuid_str, endpoint_str, key_str );
1004
+
1005
+ return rval == 0 ? Qtrue : Qfalse;
1006
+ #else
1007
+ RAISE_NO_DRAFT_APIS();
1008
+ #endif // ZYRE_BUILD_DRAFT_API
1009
+ }
1010
+
1011
+
1012
+
768
1013
  /*
769
1014
  * Node class init
770
1015
  */
@@ -785,7 +1030,11 @@ rzyre_init_node( void )
785
1030
  * Refs:
786
1031
  * - https://github.com/zeromq/zyre#readme
787
1032
  */
1033
+ #if RUBY_API_VERSION_MAJOR >= 3
1034
+ rzyre_cZyreNode = rb_define_class_under( rzyre_mZyre, "Node", rb_cObject );
1035
+ #else
788
1036
  rzyre_cZyreNode = rb_define_class_under( rzyre_mZyre, "Node", rb_cData );
1037
+ #endif
789
1038
 
790
1039
  rb_define_alloc_func( rzyre_cZyreNode, rzyre_node_alloc );
791
1040
 
@@ -819,8 +1068,8 @@ rzyre_init_node( void )
819
1068
 
820
1069
  rb_define_method( rzyre_cZyreNode, "recv", rzyre_node_recv, 0 );
821
1070
 
822
- rb_define_method( rzyre_cZyreNode, "whisper", rzyre_node_whisper, 2 );
823
- rb_define_method( rzyre_cZyreNode, "shout", rzyre_node_shout, 2 );
1071
+ rb_define_method( rzyre_cZyreNode, "whisper", rzyre_node_whisper, -1 );
1072
+ rb_define_method( rzyre_cZyreNode, "shout", rzyre_node_shout, -1 );
824
1073
 
825
1074
  rb_define_method( rzyre_cZyreNode, "peers", rzyre_node_peers, 0 );
826
1075
  rb_define_method( rzyre_cZyreNode, "peers_by_group", rzyre_node_peers_by_group, 1 );
@@ -832,18 +1081,14 @@ rzyre_init_node( void )
832
1081
  rb_define_method( rzyre_cZyreNode, "verbose!", rzyre_node_verbose_bang, 0 );
833
1082
  rb_define_method( rzyre_cZyreNode, "print", rzyre_node_print, 0 );
834
1083
 
835
- #ifdef ZYRE_BUILD_DRAFT_API
836
-
837
- rb_define_method( rzyre_cZyreNode, "set_beacon_peer_port", rzyre_node_set_beacon_peer_port, -1 );
838
- rb_define_method( rzyre_cZyreNode, "set_contest_in_group", rzyre_node_set_contest_in_group, -1 );
839
- rb_define_method( rzyre_cZyreNode, "set_advertised_endpoint", rzyre_node_set_advertised_endpoint, -1 );
840
- rb_define_method( rzyre_cZyreNode, "set_zcert", rzyre_node_set_zcert, -1 );
841
- rb_define_method( rzyre_cZyreNode, "set_zap_domain", rzyre_node_set_zap_domain, -1 );
842
- rb_define_method( rzyre_cZyreNode, "gossip_connect_curve", rzyre_node_gossip_connect_curve, -1 );
843
- rb_define_method( rzyre_cZyreNode, "gossip_unpublish", rzyre_node_gossip_unpublish, -1 );
844
- rb_define_method( rzyre_cZyreNode, "require_peer", rzyre_node_require_peer, -1 );
845
-
846
- #endif // ZYRE_BUILD_DRAFT_API
1084
+ rb_define_method( rzyre_cZyreNode, "beacon_peer_port=", rzyre_node_beacon_peer_port_eq, 1 );
1085
+ rb_define_method( rzyre_cZyreNode, "set_contest_in_group", rzyre_node_set_contest_in_group, 1 );
1086
+ rb_define_method( rzyre_cZyreNode, "advertised_endpoint=", rzyre_node_advertised_endpoint_eq, 1 );
1087
+ rb_define_method( rzyre_cZyreNode, "zcert=", rzyre_node_zcert_eq, 1 );
1088
+ rb_define_method( rzyre_cZyreNode, "zap_domain=", rzyre_node_zap_domain_eq, 1 );
1089
+ rb_define_method( rzyre_cZyreNode, "gossip_connect_curve", rzyre_node_gossip_connect_curve, 2 );
1090
+ rb_define_method( rzyre_cZyreNode, "gossip_unpublish", rzyre_node_gossip_unpublish, 1 );
1091
+ rb_define_method( rzyre_cZyreNode, "require_peer", rzyre_node_require_peer, 3 );
847
1092
 
848
1093
  rb_require( "zyre/node" );
849
1094
  }