task1) task1_value = ether.receive result = do_it(request, task1_value) ether.send(request.from, result) end SFDFJWF✳א 2種類のメッセージ When you work with the results
ether.receive ether.send(:choro_matz, task1) while true message = ether.receive if message.reply? task1_value = message break end pending << message end result = do_it(request, task1_value) ether.send(request.from, result) end 欲しいものを待つ あとでやるリスト Do it Later - wait for reply message - with list of Do it Later あとでやるリスト
multiple messages, including replies, are held by workers - e.g. Query for the results between Future and Promise - e.g. Start processing when some events finish - Not only messages but the other shared resources
do_request(event) when :reply_choro_matz do_reply_choro_matz(event) .... end end callback はこの分岐が 動的になっただけ Ah, callbacks - This branch just turned dynamic for callback
RPC ether.send(:choro_matz, task1) task1_value = ether.receive result = do_it(request, task1_value) ether.send(request.from, result) end 元は単純だったのに Difficult to write the process naturally - It was simple originally... (but become complex)
|reader, writer| begin while true _, msg, argv = req_drb(reader) case msg when 'push' value = @rdv.push(argv) else value = @rdv.pop end reply_drb(writer, true, value) end rescue p $! end end end not important
data = reader.read(sz) return data unless marshal begin Marshal.load(data) rescue DRb::DRbUnknown.new($!, data) end end def req_drb(reader) ref = load(reader, false) msg = load(reader) argc = load(reader) argv = argc.times.collect { load(reader) } block = load(reader, false) [ref, msg, argv] end ブロックを気にせずreadし まくる Don't care about I/O blocking and context switch Just read it sequentially
Thread.new(actor) do catch(actor) do while true msg, arg, blk = @queue.pop actor.__send__(msg, *arg, &blk) end end end end def __thread__; @thread; end def method_missing(m, *a, &b) @queue.push([m, a, b]) end end