zyre 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rbconfig'
4
+ require 'mkmf'
5
+
6
+ dir_config( 'libzyre' )
7
+
8
+ have_library( 'zyre' ) or
9
+ abort "No zyre library!"
10
+ have_library( 'czmq' ) or
11
+ abort "No czmq library!"
12
+
13
+ have_header( 'zyre.h' ) or
14
+ abort "No zyre.h header!"
15
+ have_header( 'czmq.h' ) or
16
+ abort "No czmq.h header!"
17
+ have_header( 'ruby/thread.h' ) or
18
+ abort "Your Ruby is too old!"
19
+
20
+ have_func( 'zyre_set_name', 'zyre.h' )
21
+ have_func( 'zyre_set_silent_timeout', 'zyre.h' )
22
+
23
+ create_header()
24
+ create_makefile( 'zyre_ext' )
25
+
@@ -0,0 +1,850 @@
1
+ /*
2
+ * node.c - A node in a Zyre cluster
3
+ * $Id$
4
+ *
5
+ * Authors:
6
+ * * Michael Granger <ged@FaerieMUD.org>
7
+ *
8
+ */
9
+
10
+ #include "zyre_ext.h"
11
+
12
+
13
+ VALUE rzyre_cZyreNode;
14
+
15
+ static void rzyre_node_free( void *ptr );
16
+
17
+ static const rb_data_type_t rzyre_node_t = {
18
+ "Zyre::Node",
19
+ {
20
+ NULL,
21
+ rzyre_node_free
22
+ },
23
+ 0,
24
+ 0,
25
+ RUBY_TYPED_FREE_IMMEDIATELY,
26
+ };
27
+
28
+
29
+ /*
30
+ * Free function
31
+ */
32
+ static void
33
+ rzyre_node_free( void *ptr )
34
+ {
35
+ if ( ptr ) {
36
+ zyre_destroy( (zyre_t **)&ptr );
37
+ }
38
+ }
39
+
40
+
41
+ /*
42
+ * Alloc function
43
+ */
44
+ static VALUE
45
+ rzyre_node_alloc( VALUE klass )
46
+ {
47
+ return TypedData_Wrap_Struct( klass, &rzyre_node_t, NULL );
48
+ }
49
+
50
+
51
+ /*
52
+ * Fetch the data pointer and check it for sanity.
53
+ */
54
+ inline zyre_t *
55
+ rzyre_get_node( VALUE self )
56
+ {
57
+ if ( !IsZyreNode(self) ) {
58
+ rb_raise( rb_eTypeError, "wrong argument type %s (expected Zyre::Node)",
59
+ rb_class2name(CLASS_OF( self )) );
60
+ }
61
+
62
+ return DATA_PTR( self );
63
+ }
64
+
65
+
66
+ /*
67
+ * call-seq:
68
+ * Zyre::Node.new -> node
69
+ * Zyre::Node.new( name ) -> node
70
+ *
71
+ * Create a new (unstarted) Zyre node. If the +name+ is not given, Zyre generates a
72
+ * randomized node name from the UUID
73
+ *
74
+ */
75
+ static VALUE
76
+ rzyre_node_initialize( int argc, VALUE *argv, VALUE self )
77
+ {
78
+ zyre_t *ptr;
79
+ VALUE name;
80
+ char *name_str = NULL;
81
+
82
+ rb_scan_args( argc, argv, "01", &name );
83
+
84
+ if ( !NIL_P(name) ) {
85
+ name_str = StringValueCStr( name );
86
+ }
87
+
88
+ TypedData_Get_Struct( self, zyre_t, &rzyre_node_t, ptr );
89
+ if ( !ptr ) {
90
+ RTYPEDDATA_DATA( self ) = ptr = zyre_new( name_str );
91
+ assert( ptr );
92
+ }
93
+
94
+ return self;
95
+ }
96
+
97
+
98
+ /*
99
+ * call-seq:
100
+ * node.uuid -> str
101
+ *
102
+ * Return the node's UUID as a String.
103
+ *
104
+ */
105
+ static VALUE
106
+ rzyre_node_uuid( VALUE self )
107
+ {
108
+ zyre_t *ptr = rzyre_get_node( self );
109
+ const char *uuid_str = zyre_uuid( ptr );
110
+ VALUE uuid = rb_str_new2( uuid_str );
111
+
112
+ return rb_str_freeze( uuid );
113
+ }
114
+
115
+
116
+ /*
117
+ * call-seq:
118
+ * node.name -> str
119
+ *
120
+ * Return the node name.
121
+ *
122
+ */
123
+ static VALUE
124
+ rzyre_node_name( VALUE self )
125
+ {
126
+ zyre_t *ptr = rzyre_get_node( self );
127
+ const char *name_str = zyre_name( ptr );
128
+ VALUE name = rb_str_new2( name_str );
129
+
130
+ return rb_str_freeze( name );
131
+ }
132
+
133
+
134
+ /*
135
+ * call-seq:
136
+ * node.name = str
137
+ *
138
+ * Set the public name of this node overriding the default. The name is
139
+ * provided during discovery and come in each ENTER message.
140
+ *
141
+ */
142
+ static VALUE
143
+ rzyre_node_name_eq( VALUE self, VALUE new_name )
144
+ {
145
+ zyre_t *ptr = rzyre_get_node( self );
146
+ const char *name_str = StringValueCStr( new_name );
147
+
148
+ zyre_set_name( ptr, name_str );
149
+
150
+ return Qtrue;
151
+ }
152
+
153
+
154
+ /*
155
+ * call-seq:
156
+ * node.port = integer
157
+ *
158
+ * Set UDP beacon discovery port. Defaults to 5670. This call overrides
159
+ * the default so that you can create independent clusters on the same network, for
160
+ * e.g. development vs. production. Has no effect after #start.
161
+ *
162
+ */
163
+ static VALUE
164
+ rzyre_node_port_eq( VALUE self, VALUE new_port )
165
+ {
166
+ zyre_t *ptr = rzyre_get_node( self );
167
+ int port_nbr = FIX2INT( new_port );
168
+
169
+ zyre_set_port( ptr, port_nbr );
170
+
171
+ return Qtrue;
172
+ }
173
+
174
+
175
+ /*
176
+ * call-seq:
177
+ * node.evasive_timeout = milliseconds
178
+ *
179
+ * Set the peer evasiveness timeout in milliseconds. Default is 5000.
180
+ * This can be tuned in order to deal with expected network conditions
181
+ * and the response time expected by the application. This is tied to
182
+ * the beacon interval and rate of messages received.
183
+ *
184
+ */
185
+ static VALUE
186
+ rzyre_node_evasive_timeout_eq( VALUE self, VALUE timeout )
187
+ {
188
+ zyre_t *ptr = rzyre_get_node( self );
189
+ int timeout_ms = FIX2INT( timeout );
190
+
191
+ zyre_set_evasive_timeout( ptr, timeout_ms );
192
+
193
+ return Qtrue;
194
+ }
195
+
196
+
197
+ /*
198
+ * call-seq:
199
+ * node.silent_timeout = milliseconds
200
+ *
201
+ * Set the peer silence timeout, in milliseconds. Default is 5000.
202
+ * This can be tuned in order to deal with expected network conditions
203
+ * and the response time expected by the application. This is tied to
204
+ * the beacon interval and rate of messages received.
205
+ * Silence is triggered one second after the timeout if peer has not
206
+ * answered ping and has not sent any message.
207
+ *
208
+ * NB: this is currently redundant with the evasiveness timeout. Both
209
+ * affect the same timeout value.
210
+ *
211
+ */
212
+ #ifdef HAVE_ZYRE_SET_SILENT_TIMEOUT
213
+ static VALUE
214
+ rzyre_node_silent_timeout_eq( VALUE self, VALUE timeout )
215
+ {
216
+ zyre_t *ptr = rzyre_get_node( self );
217
+ int timeout_ms = FIX2INT( timeout );
218
+
219
+ zyre_set_silent_timeout( ptr, timeout_ms );
220
+
221
+ return Qtrue;
222
+ }
223
+ #endif // HAVE_ZYRE_SET_SILENT_TIMEOUT
224
+
225
+
226
+ /*
227
+ * call-seq:
228
+ * node.expired_timeout = milliseconds
229
+ *
230
+ * Set the peer expiration timeout, in milliseconds. Default is 30000.
231
+ * This can be tuned in order to deal with expected network conditions
232
+ * and the response time expected by the application. This is tied to
233
+ * the beacon interval and rate of messages received.
234
+ *
235
+ */
236
+ static VALUE
237
+ rzyre_node_expired_timeout_eq( VALUE self, VALUE timeout )
238
+ {
239
+ zyre_t *ptr = rzyre_get_node( self );
240
+ int timeout_ms = FIX2INT( timeout );
241
+
242
+ zyre_set_expired_timeout( ptr, timeout_ms );
243
+
244
+ return Qtrue;
245
+ }
246
+
247
+
248
+ /*
249
+ * call-seq:
250
+ * node.interval = milliseconds
251
+ *
252
+ * Set UDP beacon discovery interval in milliseconds. Default is instant
253
+ * beacon exploration followed by pinging every 1000 msecs.
254
+ *
255
+ */
256
+ static VALUE
257
+ rzyre_node_interval_eq( VALUE self, VALUE interval )
258
+ {
259
+ zyre_t *ptr = rzyre_get_node( self );
260
+ size_t interval_ms = FIX2INT( interval );
261
+
262
+ zyre_set_interval( ptr, interval_ms );
263
+
264
+ return Qtrue;
265
+ }
266
+
267
+
268
+ /*
269
+ * call-seq:
270
+ * node.interface = string
271
+ *
272
+ * Set network interface for UDP beacons. If you do not set this, CZMQ will
273
+ * choose an interface for you. On boxes with several interfaces you should
274
+ * specify which one you want to use, or strange things can happen.
275
+ *
276
+ */
277
+ static VALUE
278
+ rzyre_node_interface_eq( VALUE self, VALUE interface )
279
+ {
280
+ zyre_t *ptr = rzyre_get_node( self );
281
+ const char *interface_str = StringValueCStr( interface );
282
+
283
+ zyre_set_interface( ptr, interface_str );
284
+
285
+ return Qtrue;
286
+ }
287
+
288
+
289
+ /*
290
+ * call-seq:
291
+ * node.endpoint = string
292
+ *
293
+ * By default, Zyre binds to an ephemeral TCP port and broadcasts the local
294
+ * host name using UDP beaconing. When you call this method, Zyre will use
295
+ * gossip discovery instead of UDP beaconing. You MUST set up the gossip
296
+ * service separately using #gossip_bind and #gossip_connect. Note that the
297
+ * endpoint MUST be valid for both bind and connect operations. You can use
298
+ * `inproc://`, `ipc://`, or `tcp://` transports (for `tcp://`, use an IP
299
+ * address that is meaningful to remote as well as local nodes). Returns
300
+ * +true+ if the bind was successful.
301
+ *
302
+ */
303
+ static VALUE
304
+ rzyre_node_endpoint_eq( VALUE self, VALUE endpoint )
305
+ {
306
+ zyre_t *ptr = rzyre_get_node( self );
307
+ const char *endpoint_str = StringValueCStr( endpoint );
308
+ int res;
309
+
310
+ res = zyre_set_endpoint( ptr, "%s", endpoint_str );
311
+
312
+ if ( res == 0 ) return Qtrue;
313
+ return Qfalse;
314
+ }
315
+
316
+
317
+ /*
318
+ * call-seq:
319
+ * node.endpoint -> str
320
+ *
321
+ * Return the endpoint being used by the Node if there is one.
322
+ *
323
+ */
324
+ static VALUE
325
+ rzyre_node_endpoint( VALUE self )
326
+ {
327
+ zyre_t *ptr = rzyre_get_node( self );
328
+ zsock_t *sock = zyre_socket( ptr );
329
+ const char *endpoint_str = zsock_endpoint( sock );
330
+
331
+ return rb_str_new2( endpoint_str );
332
+ }
333
+
334
+
335
+ /*
336
+ * call-seq:
337
+ * node.verbose!
338
+ *
339
+ * Set verbose mode; this tells the node to log all traffic as well as
340
+ * all major events.
341
+ *
342
+ */
343
+ static VALUE
344
+ rzyre_node_verbose_bang( VALUE self )
345
+ {
346
+ zyre_t *ptr = rzyre_get_node( self );
347
+
348
+ zyre_set_verbose( ptr );
349
+
350
+ return Qtrue;
351
+ }
352
+
353
+
354
+ /*
355
+ * call-seq:
356
+ * node.set_header( name, value )
357
+ *
358
+ * Set node header; these are provided to other nodes during discovery
359
+ * and come in each `ENTER` message.
360
+ *
361
+ */
362
+ static VALUE
363
+ rzyre_node_set_header( VALUE self, VALUE name, VALUE value )
364
+ {
365
+ zyre_t *ptr = rzyre_get_node( self );
366
+ const char *name_str = StringValueCStr( name );
367
+ const char *value_str = StringValueCStr( value );
368
+
369
+ rzyre_log_obj( self, "debug", "Setting header `%s` to `%s`", name_str, value_str );
370
+ zyre_set_header( ptr, name_str, "%s", value_str );
371
+
372
+ return Qtrue;
373
+ }
374
+
375
+
376
+ /*
377
+ * call-seq:
378
+ * node.gossip_bind( endpoint )
379
+ *
380
+ * Set-up gossip discovery of other nodes. At least one node in the cluster
381
+ * must bind to a well-known gossip endpoint, so other nodes can connect to
382
+ * it. Note that gossip endpoints are completely distinct from Zyre node
383
+ * endpoints, and should not overlap (they can use the same transport).
384
+ *
385
+ */
386
+ static VALUE
387
+ rzyre_node_gossip_bind( VALUE self, VALUE endpoint )
388
+ {
389
+ zyre_t *ptr = rzyre_get_node( self );
390
+ const char *endpoint_str = StringValueCStr( endpoint );
391
+
392
+ assert( endpoint_str );
393
+ rzyre_log_obj( self, "debug", "Binding to gossip endpoint %s.", endpoint_str );
394
+ zyre_gossip_bind( ptr, "%s", endpoint_str );
395
+
396
+ return Qtrue;
397
+ }
398
+
399
+
400
+ /*
401
+ * call-seq:
402
+ * node.gossip_connect( endpoint )
403
+ *
404
+ * Set-up gossip discovery of other nodes. A node may connect to multiple
405
+ * other nodes, for redundancy paths. For details of the gossip network
406
+ * design, see the CZMQ zgossip class.
407
+ *
408
+ */
409
+ static VALUE
410
+ rzyre_node_gossip_connect( VALUE self, VALUE endpoint )
411
+ {
412
+ zyre_t *ptr = rzyre_get_node( self );
413
+ const char *endpoint_str = StringValueCStr( endpoint );
414
+
415
+ assert( endpoint_str );
416
+ rzyre_log_obj( self, "debug", "Connecting to gossip endpoint %s.", endpoint_str );
417
+ zyre_gossip_connect( ptr, "%s", endpoint_str );
418
+
419
+ return Qtrue;
420
+ }
421
+
422
+
423
+ /*
424
+ * call-seq:
425
+ * node.start -> bool
426
+ *
427
+ * Start node, after setting header values. When you start a node it
428
+ * begins discovery and connection. Returns +true+ if the node was started
429
+ * successfully.
430
+ *
431
+ */
432
+ static VALUE
433
+ rzyre_node_start( VALUE self )
434
+ {
435
+ zyre_t *ptr = rzyre_get_node( self );
436
+ int res;
437
+
438
+ rzyre_log_obj( self, "debug", "Starting." );
439
+ res = zyre_start( ptr );
440
+
441
+ if ( res == 0 ) return Qtrue;
442
+ return Qfalse;
443
+ }
444
+
445
+
446
+ /*
447
+ * call-seq:
448
+ * node.stop
449
+ *
450
+ * Stop node; this signals to other peers that this node will go away.
451
+ * This is polite; however you can also just destroy the node without
452
+ * stopping it.
453
+ *
454
+ */
455
+ static VALUE
456
+ rzyre_node_stop( VALUE self )
457
+ {
458
+ zyre_t *ptr = rzyre_get_node( self );
459
+
460
+ assert( ptr );
461
+ rzyre_log_obj( self, "debug", "Stopping." );
462
+ zyre_stop( ptr );
463
+
464
+ return Qtrue;
465
+ }
466
+
467
+
468
+ /*
469
+ * call-seq:
470
+ * node.join( group_name ) -> int
471
+ *
472
+ * Join a named group; after joining a group you can send messages to
473
+ * the group and all Zyre nodes in that group will receive them.
474
+ *
475
+ */
476
+ static VALUE
477
+ rzyre_node_join( VALUE self, VALUE group )
478
+ {
479
+ zyre_t *ptr = rzyre_get_node( self );
480
+ const char *group_str = StringValueCStr( group );
481
+ int res;
482
+
483
+ rzyre_log_obj( self, "debug", "Joining group %s.", group_str );
484
+ res = zyre_join( ptr, group_str );
485
+
486
+ return INT2FIX( res );
487
+ }
488
+
489
+
490
+ /*
491
+ * call-seq:
492
+ * node.leave( group_name ) -> int
493
+ *
494
+ * Leave a group.
495
+ *
496
+ */
497
+ static VALUE
498
+ rzyre_node_leave( VALUE self, VALUE group )
499
+ {
500
+ zyre_t *ptr = rzyre_get_node( self );
501
+ const char *group_str = StringValueCStr( group );
502
+ int res;
503
+
504
+ rzyre_log_obj( self, "debug", "Leaving group %s.", group_str );
505
+ res = zyre_leave( ptr, group_str );
506
+
507
+ return INT2FIX( res );
508
+ }
509
+
510
+
511
+ /*
512
+ * call-seq:
513
+ * node.recv -> zyre_event
514
+ *
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.
518
+ *
519
+ */
520
+ static VALUE
521
+ rzyre_node_recv( VALUE self )
522
+ {
523
+ return rb_funcall( rzyre_cZyreEvent, rb_intern("from_node"), 1, self );
524
+ }
525
+
526
+
527
+ /*
528
+ * call-seq:
529
+ * node.whisper( peer_uuid, message ) -> int
530
+ *
531
+ * Send a +message+ to a single +peer+ specified as a UUID string.
532
+ *
533
+ */
534
+ static VALUE
535
+ rzyre_node_whisper( VALUE self, VALUE peer_uuid, VALUE msg )
536
+ {
537
+ zyre_t *ptr = rzyre_get_node( self );
538
+ const char *peer_str = StringValueCStr( peer_uuid ),
539
+ *msg_str = StringValueCStr( msg );
540
+ int rval;
541
+
542
+ assert( peer_str );
543
+ assert( msg_str );
544
+
545
+ rval = zyre_whispers( ptr, peer_str, "%s", msg_str );
546
+
547
+ return rval ? Qtrue : Qfalse;
548
+ }
549
+
550
+
551
+ /*
552
+ * call-seq:
553
+ * node.shout( group, message ) -> int
554
+ *
555
+ * Send +message+ to a named +group+.
556
+ *
557
+ */
558
+ static VALUE
559
+ rzyre_node_shout( VALUE self, VALUE group, VALUE msg )
560
+ {
561
+ zyre_t *ptr = rzyre_get_node( self );
562
+ const char *group_str = StringValueCStr( group ),
563
+ *msg_str = StringValueCStr( msg );
564
+ int rval;
565
+
566
+ assert( group_str );
567
+ assert( msg_str );
568
+
569
+ rval = zyre_shouts( ptr, group_str, "%s", msg_str );
570
+
571
+ return rval ? Qtrue : Qfalse;
572
+ }
573
+
574
+
575
+ /*
576
+ * call-seq:
577
+ * node.peers -> array
578
+ *
579
+ * Return an Array of current peer UUIDs.
580
+ *
581
+ */
582
+ static VALUE
583
+ rzyre_node_peers( VALUE self )
584
+ {
585
+ zyre_t *ptr;
586
+ zlist_t *peers;
587
+ VALUE rary = rb_ary_new();
588
+ char *item = NULL;
589
+
590
+ ptr = rzyre_get_node( self );
591
+ assert( ptr );
592
+
593
+ peers = zyre_peers( ptr );
594
+ assert( peers );
595
+
596
+ item = zlist_first( peers );
597
+ while ( item ) {
598
+ rb_ary_push( rary, rb_str_new2(item) );
599
+ item = zlist_next( peers );
600
+ }
601
+
602
+ zlist_destroy( &peers );
603
+ return rary;
604
+ }
605
+
606
+
607
+ /*
608
+ * call-seq:
609
+ * node.peers_by_group( group ) -> array
610
+ *
611
+ * Return an Array of the current peers in the specified +group+.
612
+ *
613
+ */
614
+ static VALUE
615
+ rzyre_node_peers_by_group( VALUE self, VALUE group )
616
+ {
617
+ zyre_t *ptr;
618
+ const char *group_str = StringValueCStr( group );
619
+ zlist_t *peers;
620
+ VALUE rary = rb_ary_new();
621
+ char *item = NULL;
622
+
623
+ ptr = rzyre_get_node( self );
624
+ assert( ptr );
625
+
626
+ peers = zyre_peers_by_group( ptr, group_str );
627
+ assert( peers );
628
+
629
+ item = zlist_first( peers );
630
+ while ( item ) {
631
+ rb_ary_push( rary, rb_str_new2(item) );
632
+ item = zlist_next( peers );
633
+ }
634
+
635
+ zlist_destroy( &peers );
636
+ return rary;
637
+ }
638
+
639
+
640
+ /*
641
+ * call-seq:
642
+ * node.own_groups -> array
643
+ *
644
+ * Return an Array of the names of the receiving node's current groups.
645
+ *
646
+ */
647
+ static VALUE
648
+ rzyre_node_own_groups( VALUE self )
649
+ {
650
+ zyre_t *ptr = rzyre_get_node( self );
651
+ zlist_t *groups = zyre_own_groups( ptr );
652
+ VALUE rary = rb_ary_new();
653
+ char *item = NULL;
654
+
655
+ assert( groups );
656
+
657
+ item = zlist_first( groups );
658
+ while ( item ) {
659
+ rb_ary_push( rary, rb_str_new2(item) );
660
+ item = zlist_next( groups );
661
+ }
662
+
663
+ zlist_destroy( &groups );
664
+ return rary;
665
+ }
666
+
667
+
668
+ /*
669
+ * call-seq:
670
+ * node.peer_groups -> array
671
+ *
672
+ * Return an Array of the names of groups known through connected peers.
673
+ *
674
+ */
675
+ static VALUE
676
+ rzyre_node_peer_groups( VALUE self )
677
+ {
678
+ zyre_t *ptr = rzyre_get_node( self );
679
+ zlist_t *groups = zyre_peer_groups( ptr );
680
+ VALUE rary = rb_ary_new();
681
+ char *item = NULL;
682
+
683
+ assert( groups );
684
+
685
+ item = zlist_first( groups );
686
+ while ( item ) {
687
+ rb_ary_push( rary, rb_str_new2(item) );
688
+ item = zlist_next( groups );
689
+ }
690
+
691
+ zlist_destroy( &groups );
692
+ return rary;
693
+ }
694
+
695
+
696
+ /*
697
+ * call-seq:
698
+ * node.peer_address( peer_uuid ) -> str
699
+ *
700
+ * Return the endpoint of a connected +peer+.
701
+ * Returns nil if peer does not exist.
702
+ *
703
+ */
704
+ static VALUE
705
+ rzyre_node_peer_address( VALUE self, VALUE peer_uuid )
706
+ {
707
+ zyre_t *ptr = rzyre_get_node( self );
708
+ const char *peer = StringValueCStr( peer_uuid );
709
+ char *address = zyre_peer_address( ptr, peer );
710
+ VALUE rval = Qnil;
711
+
712
+ if ( strnlen(address, BUFSIZ) ) {
713
+ rval = rb_str_new2( address );
714
+ }
715
+
716
+ free( address );
717
+ return rval;
718
+ }
719
+
720
+
721
+ /*
722
+ * call-seq:
723
+ * node.peer_header_value( peer_id, header_name ) -> str
724
+ *
725
+ * Return the value of a header of a conected peer. Returns nil if
726
+ * peer or key doesn't exist.
727
+ *
728
+ */
729
+ static VALUE
730
+ rzyre_node_peer_header_value( VALUE self, VALUE peer_id, VALUE header_name )
731
+ {
732
+ zyre_t *ptr = rzyre_get_node( self );
733
+ const char *peer_id_str = StringValueCStr( peer_id );
734
+ const char *header_name_str = StringValueCStr( header_name );
735
+ char *res;
736
+ VALUE rval = Qnil;
737
+
738
+ res = zyre_peer_header_value( ptr, peer_id_str, header_name_str );
739
+
740
+ // TODO: Encoding + frozen
741
+ if ( res ) {
742
+ rval = rb_str_new2( res );
743
+ xfree( res );
744
+ }
745
+
746
+ return rval;
747
+ }
748
+
749
+
750
+ /*
751
+ * call-seq:
752
+ * node.print
753
+ *
754
+ * Print zyre node information to stdout.
755
+ *
756
+ */
757
+ static VALUE
758
+ rzyre_node_print( VALUE self )
759
+ {
760
+ zyre_t *ptr = rzyre_get_node( self );
761
+
762
+ zyre_print( ptr );
763
+
764
+ return Qtrue;
765
+ }
766
+
767
+
768
+ /*
769
+ * Node class init
770
+ */
771
+ void
772
+ rzyre_init_node( void )
773
+ {
774
+
775
+ #ifdef FOR_RDOC
776
+ rb_cData = rb_define_class( "Data" );
777
+ rzyre_mZyre = rb_define_module( "Zyre" );
778
+ #endif
779
+
780
+ /*
781
+ * Document-class: Zyre::Node
782
+ *
783
+ * A node in a Zyre cluster.
784
+ *
785
+ * Refs:
786
+ * - https://github.com/zeromq/zyre#readme
787
+ */
788
+ rzyre_cZyreNode = rb_define_class_under( rzyre_mZyre, "Node", rb_cData );
789
+
790
+ rb_define_alloc_func( rzyre_cZyreNode, rzyre_node_alloc );
791
+
792
+ rb_define_protected_method( rzyre_cZyreNode, "initialize", rzyre_node_initialize, -1 );
793
+
794
+ rb_define_method( rzyre_cZyreNode, "uuid", rzyre_node_uuid, 0 );
795
+ rb_define_method( rzyre_cZyreNode, "name", rzyre_node_name, 0 );
796
+
797
+ rb_define_method( rzyre_cZyreNode, "name=", rzyre_node_name_eq, 1 );
798
+ rb_define_method( rzyre_cZyreNode, "port=", rzyre_node_port_eq, 1 );
799
+ rb_define_method( rzyre_cZyreNode, "evasive_timeout=", rzyre_node_evasive_timeout_eq, 1 );
800
+ #ifdef HAVE_ZYRE_SET_SILENT_TIMEOUT
801
+ rb_define_method( rzyre_cZyreNode, "silent_timeout=", rzyre_node_silent_timeout_eq, 1 );
802
+ #endif
803
+ rb_define_method( rzyre_cZyreNode, "expired_timeout=", rzyre_node_expired_timeout_eq, 1 );
804
+ rb_define_method( rzyre_cZyreNode, "interval=", rzyre_node_interval_eq, 1 );
805
+ rb_define_method( rzyre_cZyreNode, "interface=", rzyre_node_interface_eq, 1 );
806
+ rb_define_method( rzyre_cZyreNode, "endpoint=", rzyre_node_endpoint_eq, 1 );
807
+ rb_define_method( rzyre_cZyreNode, "endpoint", rzyre_node_endpoint, 0 );
808
+
809
+ rb_define_method( rzyre_cZyreNode, "set_header", rzyre_node_set_header, 2 );
810
+
811
+ rb_define_method( rzyre_cZyreNode, "gossip_bind", rzyre_node_gossip_bind, 1 );
812
+ rb_define_method( rzyre_cZyreNode, "gossip_connect", rzyre_node_gossip_connect, 1 );
813
+
814
+ rb_define_method( rzyre_cZyreNode, "start", rzyre_node_start, 0 );
815
+ rb_define_method( rzyre_cZyreNode, "stop", rzyre_node_stop, 0 );
816
+
817
+ rb_define_method( rzyre_cZyreNode, "join", rzyre_node_join, 1 );
818
+ rb_define_method( rzyre_cZyreNode, "leave", rzyre_node_leave, 1 );
819
+
820
+ rb_define_method( rzyre_cZyreNode, "recv", rzyre_node_recv, 0 );
821
+
822
+ rb_define_method( rzyre_cZyreNode, "whisper", rzyre_node_whisper, 2 );
823
+ rb_define_method( rzyre_cZyreNode, "shout", rzyre_node_shout, 2 );
824
+
825
+ rb_define_method( rzyre_cZyreNode, "peers", rzyre_node_peers, 0 );
826
+ rb_define_method( rzyre_cZyreNode, "peers_by_group", rzyre_node_peers_by_group, 1 );
827
+ rb_define_method( rzyre_cZyreNode, "own_groups", rzyre_node_own_groups, 0 );
828
+ rb_define_method( rzyre_cZyreNode, "peer_groups", rzyre_node_peer_groups, 0 );
829
+ rb_define_method( rzyre_cZyreNode, "peer_address", rzyre_node_peer_address, 1 );
830
+ rb_define_method( rzyre_cZyreNode, "peer_header_value", rzyre_node_peer_header_value, 2 );
831
+
832
+ rb_define_method( rzyre_cZyreNode, "verbose!", rzyre_node_verbose_bang, 0 );
833
+ rb_define_method( rzyre_cZyreNode, "print", rzyre_node_print, 0 );
834
+
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
847
+
848
+ rb_require( "zyre/node" );
849
+ }
850
+