zyre 0.1.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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
  }