shikhalev.org

DRbObject не является DRbUndumped

Что это значит? Это значит, что если мы передаем посредством dRuby из процесса A процессу B объект, принадлежащий процессу C, при работе с ним B будет обращаться непосредственно к C. Если сможет, конечно, ведь легко может статься, что и B и C имеют доступ к A, но не имеют друг к другу. Тогда получим исключение.

Впрочем, нет никаких проблем заставить A проксировать этот объект для B: obj.extend(DRbUndumped) на стороне A — и дело в шляпе.

Как проверить доступность DRbObject?

Встроенного метода, проверяющего, что объект DRbObject в действительности живой и готов к работе, почему-то нет. Но его легко написать:

class DRb::DRbObject

  def available?
    self.respond_to? :class
  rescue DRb::DRbConnError
    false
  end

end

Здесь мы пользуемся тем, что: а) DRb::DRbObject#respond_to? всегда обращается к удаленному объекту, а не проверяет сам себя; б) метод class определен у каждого объекта, т.е. при доступности вызов вернет true; и в) при недоступности генерируется вполне конкретное исключение.

Это все, может быть, неочевидное, но вполне нормальное поведение. А вот следующее наблюдение мне представляется багом…

К какому сервису относится объект?

Предположим, у нас один процесс поднимает несколько сервисов DRb. Ну, например, один основной на TCP, а второй — управляющий на UnixSockets (см. мой гем drctrl). А затем обращается по DRb куда-то наружу и передает туда undumped-объект… Так вот: объект этот будет привязан не к тому протоколу, по которому идет обращение, а к последнему запущенному сервису.

Чтобы это исправить, нужно вручную выставить свойство DRb::primary_server… Впрочем, в своем геме я сегодня это учел и исправил.