Class: Dispatch::BackgroundDispatch

Inherits:
Object
  • Object
show all
Defined in:
lib/carat-dev/detach/detach.rb

Overview

Attached as the front object to a DRb, and given it’s own front object, method calls on this object spin a new thread to handle the method and returns a BackgroundObject right away. Future usage of said BackgroundObject causes it to request the real object from the Dispatch (via DRb), at which time operations may block. This allows for the time between object creation and object usage for the real remote object to do it’s working, not blocking the local objects.

Defined Under Namespace

Classes: Stats

Instance Method Summary collapse

Constructor Details

#initialize(front, drb = false) ⇒ BackgroundDispatch

Returns a new instance of BackgroundDispatch.



87
88
89
90
91
# File 'lib/carat-dev/detach/detach.rb', line 87

def initialize(front,drb=false)
    @front = front
    @units = Hash.new
    @drb = drb
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(msg_id, *a, &b) ⇒ Object

Someone has requested an operation on this front object to be performed. Ok, lets spin of the method to do it’s working and return a BackgroundObject as a stand in.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/carat-dev/detach/detach.rb', line 105

def method_missing(msg_id, *a, &b)
    # puts "Calling #{msg_id}..."
    if @drb
        obj = BackgroundObject.new(DRbObject.new(self))
    else
        obj = BackgroundObject.new(self)
    end
    
    unit = BackgroundUnit.new(obj.index)
    unit.thread = Thread.new(unit) { |u|
        # puts " >> In thread, sending method to real object (#{obj.index})"
        u.value = @front.__send__(msg_id, *a, &b)
        # puts " >> Finished operation (#{obj.index})"
    }
    @units[obj.index] = unit
    # puts "Returning a BO for #{obj.index}"
    return obj
end

Instance Method Details

#_dump(d) ⇒ Object

This is defined to keep DRb and such from trying to move a the Dispatcher, which must remain in the same context as the called method. Though, having Thread objects referenced with @units makes that true as well.

Raises:

  • (TypeError)


97
98
99
# File 'lib/carat-dev/detach/detach.rb', line 97

def _dump(d)
    raise TypeError, "can't be moved"
end

#_get_obj(index) ⇒ Object

Used fetch the value of the work unit associated with the BackgroundObject at index. This method blocks, waiting until the value is ready before returning it.



127
128
129
130
131
132
133
134
135
# File 'lib/carat-dev/detach/detach.rb', line 127

def _get_obj(index)
    # puts "Fetching object #{index} in #{Process.pid}"
    # puts "Unit is #{@units[index].inspect}"
    if not @units[index].ready?
        @units[index].thread.join
    end
    # puts "Returning value.."
    return @units[index].value
end

#_obj_ready?(uid) ⇒ Boolean

Used to check if the work unit is ready.

Returns:

  • (Boolean)


138
139
140
141
# File 'lib/carat-dev/detach/detach.rb', line 138

def _obj_ready?(uid)
    # puts "Checking for readiness in #{Process.pid}"
    @units[uid].ready?
end

#_obj_stats(uid) ⇒ Object

Returns the stats for a work unit.



150
151
152
153
154
155
156
# File 'lib/carat-dev/detach/detach.rb', line 150

def _obj_stats(uid)
    unit = @units[uid]
    if unit.nil?
        return Stats.new
    end
    return Stats.new(unit.start,unit.stop,unit.thread.alive?)
end