Module: Iodine
- Defined in:
- lib/iodine.rb,
lib/iodine/http.rb,
lib/iodine/version.rb,
lib/iodine/protocol.rb,
lib/rack/handler/iodine.rb,
ext/iodine/iodine_core.c
Overview
Iodine is both a Rack server and a platform for writing evented network services on Ruby.
Here is a sample Echo server using Iodine:
# define the protocol for our service
class EchoProtocol
@timeout = 10
# this is just one possible callback with a recyclable buffer
def buffer
# write the data we received
write "echo: #{buffer}"
# close the connection when the time comes
close if buffer =~ /^bye[\n\r]/
end
end
# create the service instance
Iodine.listen 3000, EchoProtocol
# start the service
Iodine.start
Please read the README file for an introduction to Iodine and an overview of it’s API.
Defined Under Namespace
Modules: Base, Protocol, Rack, Websocket
Constant Summary collapse
- VERSION =
'0.3.0'.freeze
Class Method Summary collapse
- .count ⇒ Object
-
.listen(port, handler) ⇒ Object
Sets up a listening socket.
-
.processes ⇒ Object
Get/Set the number of worker processes.
-
.processes=(count) ⇒ Object
Get/Set the number of worker processes.
-
.run ⇒ Object
Runs the required block later.
-
.run_after(milliseconds) ⇒ Object
Runs the required block after the specified number of milliseconds have passed.
-
.run_every(*args) ⇒ Object
Runs the required block after the specified number of milliseconds have passed.
-
.start ⇒ Object
Starts the Iodine event loop.
-
.threads ⇒ Object
Get/Set the number of threads used in the thread pool (a static thread pool).
-
.threads=(count) ⇒ Object
Get/Set the number of threads used in the thread pool (a static thread pool).
-
.warmup ⇒ Object
Runs the warmup sequence.
Class Method Details
.count ⇒ Object
605 606 607 608 |
# File 'ext/iodine/iodine_core.c', line 605 static VALUE iodine_count(VALUE self) { (void)(self); return ULONG2NUM(facil_count(NULL)); } |
.listen(port, handler) ⇒ Object
Sets up a listening socket. Conncetions received at the assigned port will be handled by the assigned handler.
Multiple services (listening sockets) can be registered before starting the Iodine event loop.
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'ext/iodine/iodine_core.c', line 445 static VALUE iodine_listen_dyn_protocol(VALUE self, VALUE port, VALUE handler) { // validate that the handler is a class and include the Iodine::Protocol if (TYPE(handler) == T_CLASS) { // include the Protocol module // // do we neet to check? // if (rb_mod_include_p(protocol, rDynProtocol) == Qfalse) rb_include_module(handler, DynamicProtocol); rb_extend_object(handler, DynamicProtocolClass); } else { rb_raise(rb_eTypeError, "The connection handler MUST be of type Class."); return Qnil; } if (TYPE(port) != T_FIXNUM && TYPE(port) != T_STRING) rb_raise(rb_eTypeError, "The port variable must be a Fixnum or a String."); if (TYPE(port) == T_FIXNUM) port = rb_funcall2(port, to_s_method_id, 0, NULL); rb_ivar_set(self, rb_intern("_port"), port); // listen facil_listen(.port = StringValueCStr(port), .udata = (void *)handler, .on_open = on_open_dyn_protocol, .on_start = on_server_start_for_handler, .on_finish = on_server_on_finish_for_handler); return self; } |
.processes ⇒ Object
Get/Set the number of worker processes. A value greater then 1 will cause the Iodine to “fork” any extra worker processes needed.
54 55 56 |
# File 'lib/iodine.rb', line 54 def self.processes @processes end |
.processes=(count) ⇒ Object
Get/Set the number of worker processes. A value greater then 1 will cause the Iodine to “fork” any extra worker processes needed.
59 60 61 |
# File 'lib/iodine.rb', line 59 def self.processes=(count) @processes = count.to_i end |
.run ⇒ Object
Runs the required block later. The block might run concurrently with the existing code (depending on the amount and availability of worker threads).
Returns the block object. The block will run only while Iodine is running (run will be delayed until Iodine.start is called, unless Iodine’s event loop is active).
528 529 530 531 532 533 534 535 536 537 538 539 |
# File 'ext/iodine/iodine_core.c', line 528 static VALUE iodine_run_async(VALUE self) { (void)(self); // requires a block to be passed rb_need_block(); VALUE block = rb_block_proc(); if (block == Qnil) return Qfalse; Registry.add(block); if (defer(iodine_run_once2, (void *)block, NULL)) perror("ERROR: dropped defered task"); return block; } |
.run_after(milliseconds) ⇒ Object
Runs the required block after the specified number of milliseconds have passed. Time is counted only once Iodine started running (using start).
Always returns a copy of the block object.
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'ext/iodine/iodine_core.c', line 547 static VALUE iodine_run_after(VALUE self, VALUE milliseconds) { (void)(self); if (TYPE(milliseconds) != T_FIXNUM) { rb_raise(rb_eTypeError, "milliseconds must be a number"); return Qnil; } size_t milli = FIX2UINT(milliseconds); // requires a block to be passed rb_need_block(); VALUE block = rb_block_proc(); if (block == Qnil) return Qfalse; Registry.add(block); facil_run_every(milli, 1, iodine_run_once, (void *)block, NULL); return block; } |
.run_every(*args) ⇒ Object
Runs the required block after the specified number of milliseconds have passed. Time is counted only once Iodine started running (using start).
Accepts:
- milliseconds
-
the number of milliseconds between event repetitions.
- repetitions
-
the number of event repetitions. Defaults to 0 (never ending).
- block
-
(required) a block is required, as otherwise there is nothing to
perform.
The event will repeat itself until the number of repetitions had been delpeted.
Always returns a copy of the block object.
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
# File 'ext/iodine/iodine_core.c', line 580 static VALUE iodine_run_every(int argc, VALUE *argv, VALUE self) { (void)(self); VALUE milliseconds, repetitions, block; rb_scan_args(argc, argv, "11&", &milliseconds, &repetitions, &block); if (TYPE(milliseconds) != T_FIXNUM) { rb_raise(rb_eTypeError, "milliseconds must be a number."); return Qnil; } if (repetitions != Qnil && TYPE(repetitions) != T_FIXNUM) { rb_raise(rb_eTypeError, "repetitions must be a number or `nil`."); return Qnil; } size_t milli = FIX2UINT(milliseconds); size_t repeat = (repetitions == Qnil) ? 0 : FIX2UINT(repetitions); // requires a block to be passed rb_need_block(); Registry.add(block); facil_run_every(milli, repeat, iodine_run_always, (void *)block, (void (*)(void *))Registry.remove); return block; } |
.start ⇒ Object
Starts the Iodine event loop. This will hang the thread until an interrupt (‘^C`) signal is received.
Returns the Iodine module.
685 686 687 688 689 690 691 692 693 |
# File 'ext/iodine/iodine_core.c', line 685 static VALUE iodine_start(VALUE self) { if (iodine_http_review() == -1) { perror("Iodine couldn't start HTTP service... port busy? "); return Qnil; } rb_thread_call_without_gvl2(srv_start_no_gvl, (void *)self, NULL, NULL); return self; } |
.threads ⇒ Object
Get/Set the number of threads used in the thread pool (a static thread pool). Can be 1 (single working thread, the main thread will sleep) and can be 0 (the main thread will be used as the only active thread).
44 45 46 |
# File 'lib/iodine.rb', line 44 def self.threads @threads end |
.threads=(count) ⇒ Object
Get/Set the number of threads used in the thread pool (a static thread pool). Can be 1 (single working thread, the main thread will sleep) and can be 0 (the main thread will be used as the only active thread).
49 50 51 |
# File 'lib/iodine.rb', line 49 def self.threads=(count) @threads = count.to_i end |
.warmup ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/iodine.rb', line 67 def self.warmup # load anything marked with `autoload`, since autoload isn't thread safe nor fork friendly. Module.constants.each do |n| begin Object.const_get(n) rescue Exception => _e end end end |