Class: Iodine::PubSub::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/iodine/pubsub.rb,
ext/iodine/iodine_pubsub.c

Overview

The Engine class makes it easy to use leverage Iodine’s pub/sub system using external services.

Iodine comes with two built-in engines:

  • ‘Iodine::PubSub::Engine::CLUSTER` will distribute messages to all subscribers in the process cluster.

  • ‘Iodine::PubSub::Engine::SINGLE_PROCESS` will distribute messages to all subscribers sharing the same process.

Engine instances should be initialized only after Iodine started running (or the ‘fork`ing of the engine’s connection will introduce communication issues).

For this reason, the best approcah to initialization would be:

class MyEngineClass < Iodine::PubSub::Engine
     # ...
end

Iodine.run do
   MyEngine = MyEngineClass.new
end

Engine child classes MUST override the #subscribe, #unsubscribe and #publish in order to perform this actions using the backend service (i.e. using Redis).

Once an Engine instance receives a message from the backend service, it should forward the message to the Iodine distribution layer using the #distribute method.

Iodine will than distribute the message to all registered clients.

IMPORTANT:

Connections shouldn’t call any of the Engine or Iodine::PubSub methods directly, since connections might be disconnected at any time, at which point their memory will become corrupted or recycled.

The connection pub/sub methods (coming soon) keep the application safe from these risks by performing specific checks for connection related pub/sub actions.

Direct Known Subclasses

RedisEngine

Instance Method Summary collapse

Constructor Details

#initializeObject



237
238
239
240
241
242
# File 'ext/iodine/iodine_pubsub.c', line 237

static VALUE engine_initialize(VALUE self) {
  iodine_engine_s *engine;
  Data_Get_Struct(self, iodine_engine_s, engine);
  engine->handler = self;
  return self;
}

Instance Method Details

#distribute(*args) ⇒ Object

Called by the engine to distribute a ‘message` to a `channel`. Supports `pattern` channel matching as well.

i.e.

# Regular message distribution
self.distribute "My Channel", "Hello!"
# Pattern message distribution
self.distribute "My Ch*", "Hello!", true

Returns ‘self`, always.

This is the ONLY method inherited from Iodine::PubSub::Engine that should be called from within your code (by the engine itself).

Notice:*

Message distribution requires both the Iodine::PubSub::Engine instance and the channel to be the same.

If a client subscribed to “channel 1” on engine A, they will NOT receive messages from “channel 1” on engine B.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'ext/iodine/iodine_pubsub.c', line 92

static VALUE engine_distribute(int argc, VALUE *argv, VALUE self) {
  if (argc < 2 || argc > 3)
    rb_raise(rb_eArgError,
             "wrong number of arguments (given %d, expected 2..3).", argc);
  VALUE channel = argv[0];
  VALUE msg = argv[1];
  VALUE pattern = argc >= 3 ? argv[2] : Qnil;
  Check_Type(channel, T_STRING);
  Check_Type(msg, T_STRING);

  iodine_engine_s *engine;
  Data_Get_Struct(self, iodine_engine_s, engine);

  pubsub_engine_distribute(.engine = engine->p,
                           .channel.name = RSTRING_PTR(channel),
                           .channel.len = RSTRING_LEN(channel),
                           .msg.data = RSTRING_PTR(msg),
                           .msg.len = RSTRING_LEN(msg),
                           .use_pattern =
                               (pattern != Qnil && pattern != Qfalse));
  return self;
}

#publish(channel, msg, use_pattern) ⇒ Object

Override this method to handle message publishing to the underlying engine (i.e. from Ruby to Redis or from Ruby to MongoDB).

This function will be called by Iodine during pub/sub publication. Don’t call this function from your own code / application.

The function should return ‘true` on success and `nil` or `false` on failure.



55
56
57
58
59
60
61
62
# File 'ext/iodine/iodine_pubsub.c', line 55

static VALUE engine_pub_placeholder(VALUE self, VALUE channel, VALUE msg,
                                    VALUE use_pattern) {
  return Qnil;
  (void)self;
  (void)msg;
  (void)channel;
  (void)use_pattern;
}

#subscribe(channel, use_pattern) ⇒ Object

Override this method to handle (un)subscription requests.

This function will be called by Iodine during pub/sub (un)subscription. Don’t call this function from your own code / application.

The function should return ‘true` on success and `nil` or `false` on failure.



38
39
40
41
42
43
44
# File 'ext/iodine/iodine_pubsub.c', line 38

static VALUE engine_sub_placeholder(VALUE self, VALUE channel,
                                    VALUE use_pattern) {
  return Qnil;
  (void)self;
  (void)channel;
  (void)use_pattern;
}

#unsubscribe(channel, use_pattern) ⇒ Object

Override this method to handle (un)subscription requests.

This function will be called by Iodine during pub/sub (un)subscription. Don’t call this function from your own code / application.

The function should return ‘true` on success and `nil` or `false` on failure.



38
39
40
41
42
43
44
# File 'ext/iodine/iodine_pubsub.c', line 38

static VALUE engine_sub_placeholder(VALUE self, VALUE channel,
                                    VALUE use_pattern) {
  return Qnil;
  (void)self;
  (void)channel;
  (void)use_pattern;
}