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.2.0'.freeze
Class Method Summary collapse
- .count ⇒ Object
-
.listen(port, handler) ⇒ Object
Sets up a listenning 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
547 |
# File 'ext/iodine/iodine_core.c', line 547 static VALUE iodine_count(VALUE self) { return ULONG2NUM(server_count(NULL)); } |
.listen(port, handler) ⇒ Object
Sets up a listenning socket. Conncetions received at the assigned port will be handled by the assigned handler.
Multiple services (listenning sockets) can be registered before starting the Iodine event loop.
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
# File 'ext/iodine/iodine_core.c', line 394
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);
// listen
server_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.
46 47 48 |
# File 'lib/iodine.rb', line 46 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.
51 52 53 |
# File 'lib/iodine.rb', line 51 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).
471 472 473 474 475 476 477 478 479 480 481 482 483 |
# File 'ext/iodine/iodine_core.c', line 471
static VALUE iodine_run_async(VALUE self) {
// requires a block to be passed
rb_need_block();
VALUE block = rb_block_proc();
if (block == Qnil)
return Qfalse;
Registry.add(block);
if (async_run(iodine_run_once, (void *)block)) {
server_run_after(1, iodine_run_once, (void *)block);
;
}
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.
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
# File 'ext/iodine/iodine_core.c', line 491
static VALUE iodine_run_after(VALUE self, VALUE milliseconds) {
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);
server_run_after(milli, iodine_run_once, (void *)block);
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.
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'ext/iodine/iodine_core.c', line 523
static VALUE iodine_run_every(int argc, VALUE *argv, VALUE 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);
server_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.
568 569 570 571 572 573 574 575 576 |
# File 'ext/iodine/iodine_core.c', line 568
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, unblck, 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).
36 37 38 |
# File 'lib/iodine.rb', line 36 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).
41 42 43 |
# File 'lib/iodine.rb', line 41 def self.threads=(count) @threads = count.to_i end |
.warmup ⇒ Object
59 60 61 62 63 64 65 66 67 |
# File 'lib/iodine.rb', line 59 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 |