Module: DRbRb

Defined in:
lib/drb-rb.rb,
lib/drb-rb/stable.rb

Defined Under Namespace

Modules: Stable

Class Method Summary collapse

Class Method Details

.drb_read_msg_piece(sock, include_raw: false) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/drb-rb.rb', line 75

def self.drb_read_msg_piece(sock, include_raw: false)
  len = drb_read_msg_piece_length sock

  piece = nil
  begin
    Timeout::timeout(4) {
      piece = sock.recvfrom(len)[0]
      piece << sock.recvfrom(len - piece.size)[0] while piece.size < len
    }
  rescue Timeout::Error
    raise "recvfrom timed out"
  end

  obj = Parshal.unmarshal(piece)

  if include_raw
    [obj, piece]
  else
    obj
  end
end

.drb_read_msg_piece_length(sock) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/drb-rb.rb', line 97

def self.drb_read_msg_piece_length(sock)
  len = 0
  begin
    Timeout::timeout(2) {
      len = sock.recvfrom(4)[0]
    }
  rescue Timeout::Error
    raise "recvfrom timed out"
  end

  if len.empty?
    raise 'recvfrom yielded no data'
  end

  while len.size < 4
    chunk = nil
    begin
      Timeout::timeout(2) {
        chunk = sock.recvfrom(4 - len.size)
      }
    rescue Timeout::Error
      raise "recvfrom timed out"
    end

    if chunk[0].empty?
      raise 'recvfrom yielded no data after partial read'
    end
    len << chunk[0]
  end

  len.unpack1('N')
end

.drb_read_reply(sock, include_raw: false) ⇒ Object



58
59
60
61
# File 'lib/drb-rb.rb', line 58

def self.drb_read_reply(sock, include_raw: false)
  [drb_read_msg_piece(sock), # success
   drb_read_msg_piece(sock, include_raw: include_raw)] # result
end

.drb_read_request(sock) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/drb-rb.rb', line 44

def self.drb_read_request(sock)
  id = drb_read_msg_piece(sock, include_raw: true)
  method = drb_read_msg_piece(sock, include_raw: true)
  args_len = drb_read_msg_piece(sock, include_raw: true)
  args = []
  if args_len[0] != nil && args_len[0].instance_of?(Integer) && args_len[0] > 0
    for _ in 0...args_len[0]
      args.push(drb_read_msg_piece(sock, include_raw: true))
    end
  end
  block = drb_read_msg_piece(sock, include_raw: true)
  [id, method, args, block]
end

.drb_write_reply(sock, success, result, close = false) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/drb-rb.rb', line 67

def self.drb_write_reply(sock, success, result, close=false)
  sock.send(make_reply(success, result), 0)
  if close
    sock.close
  end
  !close
end

.drb_write_request(sock, obj_id, method, args, block) ⇒ Object



63
64
65
# File 'lib/drb-rb.rb', line 63

def self.drb_write_request(sock, obj_id, method, args, block)
  sock.send(make_request(obj_id, method, args, block), 0)
end

.make_msg_piece(obj, prepend_size: true, raw: false) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/drb-rb.rb', line 145

def self.make_msg_piece(obj, prepend_size: true, raw: false)
  #piece = Parshal.marshal(obj)
  piece = if raw
    obj
  else
    Marshal.dump(obj)
  end

  piece = [piece.size].pack('N') + piece if prepend_size
  piece
end

.make_reply(success, result, raw = [false,false]) ⇒ Object



139
140
141
142
143
# File 'lib/drb-rb.rb', line 139

def self.make_reply(success, result, raw=[false,false])
  reply = make_msg_piece(success, raw: raw[0])
  reply << make_msg_piece(result, raw: raw[1])
  reply
end

.make_request(obj_id, method, args, block) ⇒ Object



130
131
132
133
134
135
136
137
# File 'lib/drb-rb.rb', line 130

def self.make_request(obj_id, method, args, block)
  request = make_msg_piece(obj_id)
  request << make_msg_piece(method)
  request << make_msg_piece(args.size)
  args.each { |arg| request << make_msg_piece(arg) }
  request << make_msg_piece(block)
  request
end

.send_request(sock, obj_id, method, args, block, include_raw: false) ⇒ Object



39
40
41
42
# File 'lib/drb-rb.rb', line 39

def self.send_request(sock, obj_id, method, args, block, include_raw: false)
  drb_write_request(sock, obj_id, method, args, block)
  drb_read_reply(sock, include_raw: include_raw)
end

.start_server(sock, &block) ⇒ Object

block must accept 4 arguments: [obj_id, obj_id_raw], [method, method_raw], [args, args_raw], and [block, block_raw] block must return 2-3 arguments: success, result, close?



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/drb-rb.rb', line 10

def self.start_server(sock, &block)
  loop do
    req = begin
      drb_read_request(sock)
    rescue => e
      if 'recvfrom yielded no data' == e.message
        break
      end
      puts "Exception raised in DRbRb handler1: #{e.inspect}\n#{e.backtrace.join("\n")}"
      break
    end
    rep = begin
      block.call(*req)
    rescue => e
      puts "Exception raised in DRbRb handler: #{e.inspect}\n#{e.backtrace.join("\n")}"
      next
    end

    begin
      if not drb_write_reply(sock, *rep)
        break
      end
    rescue => e
      puts "Exception raised in DRbRb handler3: #{e.inspect}\n#{e.backtrace.join("\n")}"
      break
    end
  end
end