Class: LWES::Emitter
- Inherits:
-
Object
- Object
- LWES::Emitter
- Defined in:
- lib/lwes/emitter.rb,
ext/lwes_ext/emitter.c
Overview
The LWES::Emitter is used for emitting LWES events to a multicast network or a single host. It can emit LWES::Event objects, LWES::Struct objects, and even plain Ruby hashes.
It is non-blocking and does not guarantee delivery.
emitter = LWES::Emitter.new(:address => '224.1.1.11',
:port => 12345,
:heartbeat => 30, # nil to disable
:ttl => 1) # nil for default TTL(3)
event = MyEvent.new
event.foo = "bar"
emitter << event
NON-ESF USERS
Since we can’t reliably map certain Ruby types to LWES types, you’ll have to specify them explicitly for IP addresses and all Integer types.
event = {
:time_sec => [ :int32, Time.now.to_i ],
:time_usec => [ :int32, Time.now.tv_usec ],
:remote_addr => [ :ip_addr, "192.168.0.1" ],
}
# Strings and Boolean values are easily mapped, however:
event[:field1] = "String value"
event[:boolean1] = true
event[:boolean2] = false
# finally, we just emit the hash with any given name
emitter.emit "Event3", event
Instance Method Summary collapse
-
#<<(event) ⇒ Object
Emits the given
event
which much be an LWES::Event or LWES::Struct-derived object. -
#_create(options) ⇒ Object
:nodoc: should only used internally by #initialize.
-
#close ⇒ Object
emitter.close -> nil.
-
#emit(*args) ⇒ Object
emitter.emit(“EventName”, :foo => “HI”) emitter.emit(“EventName”, :foo => [ :int32, 123 ]) emitter.emit(EventClass, :foo => “HI”) emitter.emit(event).
-
#initialize(options = {}, &block) ⇒ Emitter
constructor
creates a new Emitter object which may be used for the lifetime of the process:.
-
#initialize_copy(obj) ⇒ Object
:nodoc:.
Constructor Details
#initialize(options = {}, &block) ⇒ Emitter
creates a new Emitter object which may be used for the lifetime of the process:
LWES::Emitter.new(:address => '224.1.1.11',
:iface => '0.0.0.0',
:port => 12345,
:heartbeat => false, # Integer for frequency
:ttl => 60, # nil for no ttl)
47 48 49 50 51 |
# File 'lib/lwes/emitter.rb', line 47 def initialize( = {}, &block) [:iface] ||= '0.0.0.0' _create() block_given? end |
Instance Method Details
#<<(event) ⇒ Object
Emits the given event
which much be an LWES::Event or LWES::Struct-derived object
341 342 343 344 345 346 347 348 349 350 |
# File 'ext/lwes_ext/emitter.c', line 341
static VALUE emitter_ltlt(VALUE self, VALUE event)
{
if (rb_obj_is_kind_of(event, cLWES_Event)) {
return emit_event(self, event);
} else {
Check_Type(event, T_STRUCT);
return emit_struct(self, event);
}
}
|
#_create(options) ⇒ Object
:nodoc: should only used internally by #initialize
486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 |
# File 'ext/lwes_ext/emitter.c', line 486
static VALUE _create(VALUE self, VALUE options)
{
struct _rb_lwes_emitter *rle = _rle(self);
VALUE address, iface, port, heartbeat, ttl;
rle->emit_heartbeat = FALSE;
rle->freq = 0;
rle->ttl = UINT32_MAX; /* nobody sets a ttl this long, right? */
if (rle->emitter)
rb_raise(rb_eRuntimeError, "already created lwes_emitter");
if (TYPE(options) != T_HASH)
rb_raise(rb_eTypeError, "options must be a hash");
address = rb_hash_aref(options, ID2SYM(rb_intern("address")));
if (TYPE(address) != T_STRING)
rb_raise(rb_eTypeError, ":address must be a string");
rle->address = ruby_strdup(StringValueCStr(address));
iface = rb_hash_aref(options, ID2SYM(rb_intern("iface")));
switch (TYPE(iface)) {
case T_NIL:
rle->iface = NULL;
break;
case T_STRING:
rle->iface = ruby_strdup(StringValueCStr(iface));
break;
default:
rb_raise(rb_eTypeError, ":iface must be a String or nil");
}
port = rb_hash_aref(options, ID2SYM(rb_intern("port")));
if (TYPE(port) != T_FIXNUM)
rb_raise(rb_eTypeError, ":port must be a Fixnum");
rle->port = NUM2UINT(port);
heartbeat = rb_hash_aref(options, ID2SYM(rb_intern("heartbeat")));
if (TYPE(heartbeat) == T_FIXNUM) {
int tmp = NUM2INT(heartbeat);
if (tmp > INT16_MAX)
rb_raise(rb_eArgError,":heartbeat > INT16_MAX seconds");
rle->emit_heartbeat = TRUE;
rle->freq = (LWES_INT_16)tmp;
} else if (NIL_P(heartbeat)) { /* do nothing, use defaults */
} else
rb_raise(rb_eTypeError, ":heartbeat must be a Fixnum or nil");
ttl = rb_hash_aref(options, ID2SYM(rb_intern("ttl")));
if (TYPE(ttl) == T_FIXNUM) {
unsigned LONG_LONG tmp = NUM2ULL(ttl);
if (tmp >= UINT32_MAX)
rb_raise(rb_eArgError, ":ttl >= UINT32_MAX seconds");
rle->ttl = (LWES_U_INT_32)tmp;
} else if (NIL_P(ttl)) { /* do nothing, no ttl */
} else
rb_raise(rb_eTypeError, ":ttl must be a Fixnum or nil");
lwesrb_emitter_create(rle);
return self;
}
|
#close ⇒ Object
emitter.close -> nil
Destroys the associated lwes_emitter and the associated socket. This method is rarely needed as Ruby garbage collection will take care of closing for you, but may be useful in odd cases when it is desirable to release file descriptors ASAP.
434 435 436 437 438 439 440 441 442 443 |
# File 'ext/lwes_ext/emitter.c', line 434
static VALUE emitter_close(VALUE self)
{
struct _rb_lwes_emitter *rle = _rle(self);
if (rle->emitter)
lwes_emitter_destroy(rle->emitter);
rle->emitter = NULL;
return Qnil;
}
|
#emit(*args) ⇒ Object
emitter.emit(“EventName”, :foo => “HI”) emitter.emit(“EventName”, :foo => [ :int32, 123 ]) emitter.emit(EventClass, :foo => “HI”) emitter.emit(event)
Emits a hash. If EventName is given as a string, it will expect a hash as its second argument and will do its best to serialize a Ruby Hash to an LWES Event. If a type is ambiguous, a two-element array may be specified as its value, including the LWES type information and the Ruby value.
If an EventClass is given, the second argument should be a hash with the values given to the class. This will emit the event named by EventClass.
If only one argument is given, it behaves just like LWES::Emitter#<<
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
# File 'ext/lwes_ext/emitter.c', line 371
static VALUE emitter_emit(int argc, VALUE *argv, VALUE self)
{
volatile VALUE raise_inspect;
char *err;
VALUE name = Qnil;
VALUE event = Qnil;
argc = rb_scan_args(argc, argv, "11", &name, &event);
switch (TYPE(name)) {
case T_STRING:
if (TYPE(event) == T_HASH)
return emit_hash(self, name, event);
rb_raise(rb_eTypeError,
"second argument must be a hash when first "
"is a String");
case T_STRUCT:
if (argc >= 2)
rb_raise(rb_eArgError,
"second argument not allowed when first"
" is a Struct");
event = name;
return emit_struct(self, event);
case T_CLASS:
if (TYPE(event) != T_HASH)
rb_raise(rb_eTypeError,
"second argument must be a Hash when first"
" is a Class");
/*
* we can optimize this so there's no intermediate
* struct created
*/
event = rb_funcall(name, id_new, 1, event);
if (TYPE(event) == T_STRUCT)
return emit_struct(self, event);
if (rb_obj_is_kind_of(event, cLWES_Event))
return emit_event(self, event);
name = rb_class_name(name);
err = StringValuePtr(name);
rb_raise(rb_eArgError,
"%s created a bad event: %s",
err, RAISE_INSPECT(event));
default:
if (rb_obj_is_kind_of(name, cLWES_Event))
return emit_event(self, name);
rb_raise(rb_eArgError,
"bad argument: %s, must be a String, Struct or Class",
RAISE_INSPECT(name));
}
assert(0 && "should never get here");
return event;
}
|
#initialize_copy(obj) ⇒ Object
:nodoc:
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
# File 'ext/lwes_ext/emitter.c', line 468
static VALUE init_copy(VALUE dest, VALUE obj)
{
struct _rb_lwes_emitter *dst = _rle(dest);
struct _rb_lwes_emitter *src = _rle(obj);
memcpy(dst, src, sizeof(*dst));
dst->address = ruby_strdup(src->address);
if (dst->iface)
dst->iface = ruby_strdup(src->iface);
lwesrb_emitter_create(dst);
assert(dst->emitter && dst->emitter != src->emitter &&
"emitter not a copy");
return dest;
}
|