Method: Flor::Scheduler#add_branches

Defined in:
lib/flor/unit/scheduler.rb

#add_branches(exid, *as) ⇒ Object Also known as: add_branch



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/flor/unit/scheduler.rb', line 285

def add_branches(exid, *as)

  msg, opts = prepare_message('add-branches', [ exid, *as ])

  msg['point'] = 'add'
  msg['trees'] = prepare_trees(opts)

  msg['tnid'] = tnid =
    opts.delete(:tnid) || msg.delete('nid')
  msg['nid'] =
    msg.delete('nid') || opts.delete(:pnid) || Flor.parent_nid(tnid)

  exe = @storage.executions[exid: msg['exid']]
  pnid = msg['nid']
  ptree = exe.lookup_tree(pnid)

  fail ArgumentError.new(
    "parent #{pnid} is a leaf, cannot add branch at #{tnid}"
  ) unless ptree[1].is_a?(Array)
    #
    # not likely to happen, since leaves reply immediately

  size = ptree[1].size
  tnid = (msg['tnid'] ||= Flor.make_child_nid(pnid, size))

  cid = Flor.child_id(tnid)

  tide, tcid = nil
    (0..size - 1).reverse_each do |i|
      tcid = Flor.make_child_nid(pnid, i)
      next unless exe.nodes[tcid]
      tide = i; break
    end

  fail ArgumentError.new(
    "target #{tnid} too low, execution has already reached #{tcid}"
  ) if tide && cid < tide

  fail ArgumentError.new(
    "target #{tnid} is off by #{cid - size}, " +
    "node #{pnid} has #{size} branch#{size == 1 ? '' : 'es'}"
  ) if cid > size

  queue(msg, opts)
end