OVERVIEW

Project interprocess_attribute
Homepage https://github.com/robgleeson/interprocess_attribute
Documentation http://rubydoc.info/gems/interprocess_attribute/frames
CI Build Status
Author Robert Gleeson

DESCRIPTION

interprocess_attribute persists attributes between processes. That's to say you can set the 'name' attribute to "Rob" in the child process and see that change propagate in the parent process with very little code.

Attributes are defined through the interprocess_attribute method. It behaves just like the attr_accessor method in that it defines a getter and a setter. The difference is that attributes set through interprocess_attribute persist between processes.

EXAMPLES

1.

The example shows a simple scenario of how you might use interprocess_attribute to persist the 'name' attribute among a parent process & a subprocess. A monkey patch on Class is used but it is opt-in and can be avoided if you really want.

require "interprocess_attribute"
require "interprocess_attribute/core_ext/class"
class Person
  interprocess_attribute :name  
end

person = Person.new
pid = fork do
  person.name = "Rob"
end
Process.wait pid
p person.name # => "Rob"

2.

Monkey-patching Class is not everybodys cup of tea, so in that case there is a module you can use with extend(…).

require "interprocess_attribute"
class Person
  extend InterProcessAttribute
  interprocess_attribute :name,:age
end

person = Person.new
pid = fork do
  person.name = "Rob"
  person.age = 27
end
Process.wait pid
p person.name # => "Rob"
p person.age # => 27

3.

So far all these examples have defined public attributes but it might just be that you don't want to expose attributes at all, you could just want persistence, and to compensate for that it is possible to mark attributes as private or protected:

class Person
  extend InterProcessAttribute
  interprocess_attribute :name, {visibility: :private}

  def initialize
    self.name = "Rob"
  end
end

person = Person.new
person.name = "John" # NoMethodError

4.

The last example is a bit like inception: what happens when you fork inside a fork and both of those forks call a setter? The behavior for this case is to discard all values but the last one to be set. For example, person.name will be "Rob" here:

class Person
  extend InterProcessAttribute
  interprocess_attribute :name
end

person = Person.new
pid = fork do
  person.name = "John"
  pid = fork do
    person.name = "Rob"
  end
  Process.wait pid
end
Process.wait pid
p person.name # => "Rob"

GOTCHAS

1.

Methods that mutate the receiver won't have their changes persist between processes. You must use the setter if you want persistence. For example:

class Person
  extend InterProcessAttribute
  interprocess_attribute :name
end

person = Person.new
person.name = "John"
person.name.sub! /J/, "" # does not persist
person.name = person.name.sub! /J/, "" # persists

2.

The transport of Ruby objects happens through serialization and communication on a UNIXSocket. The serializer being used is Marshal, and it can serialize most Ruby objects but there is a few it can't, so be wary.

PLATFORM SUPPORT

supported

  • CRuby (1.9+)

unsupported

  • CRuby 1.8
  • MacRuby
  • JRuby
  • Rubinius (support for Rubinius will come sometime in the future).

INSTALL

$ gem install interprocess_attribute

LICENSE

MIT. See LICENSE.txt.