Created
February 6, 2018 17:03
-
-
Save agrare/d9484884bd297b1615814128129cfc5c to your computer and use it in GitHub Desktop.
DRb Fork Reproducer Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This script demonstrates the issue with mixing DRb calls and | |
# forking child processes. | |
# | |
# If the parent process calls a remote DRb method prior to forking | |
# a child process it appears there is still a connection in the | |
# DRbConn global connection pool. This seems to cause messages to | |
# be sent to the wrong client and typically leads to one of three | |
# symptoms: | |
# | |
# 1. A message is sent to the wrong client | |
# Ex: 'Failure! expected BBBB but got AAAA' | |
# | |
# 2. A message is spliced and what should be the message size is another string | |
# Ex: 'Failure! too large packet 1090927110' | |
# | |
# 3. A message is spliced and what should be the Marshal version is another string | |
# Ex: 'Failure! incompatible marshal file format (can't be read) | |
# format version 4.8 required; 14.4 given' | |
# | |
# For this case we added some client-side logging to dump the hex_bytes of the string: | |
# [TypeError]: incompatible marshal file format (can't be read) | |
# format version 4.8 required; 58.12 given | |
# 0x00000000 3a 0c 56 69 6d 48 61 73 68 7b 09 49 22 0b 65 6e :.VimHash{.I".en | |
# 0x00000010 74 69 74 79 06 3a 06 45 54 49 43 3a 0e 56 69 6d tity.:.ETIC:.Vim | |
# 0x00000020 53 74 72 69 6e 67 22 0d 76 6d 2d 31 38 37 35 37 String".vm-18757 | |
# | |
# The first bytes here which should be the marshal version look like the middle of | |
# another message. | |
require 'drb/drb' | |
def echo_client(str) | |
echo_obj = DRbObject.new_with_uri('druby://localhost:9999') | |
1_000.times do | |
begin | |
ret = echo_obj.echo(str) | |
if ret != str | |
puts "PID #{Process.pid}: Failure! expected #{str} but got #{ret}" | |
exit 1 | |
end | |
rescue TypeError, DRb::DRbConnError => err | |
puts "PID #{Process.pid}: Failure! #{err}" | |
exit 1 | |
end | |
end | |
puts "PID #{Process.pid}: Succeded." | |
end | |
# Execute a DRb call in the parent process prior to forking the children | |
echo_obj = DRbObject.new_with_uri('druby://localhost:9999') | |
echo_obj.echo("CCCC") # Comment this out and the script passes | |
# Create 20 child processes to echo some string to the server and verify | |
# the same string was returned | |
child_pids = [] | |
%w(AAAA BBBB).each do |str| | |
10.times do | |
child_pids << Kernel.fork { echo_client(str) } | |
end | |
end | |
child_pids.each { |pid| Process.wait(pid) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'drb/drb' | |
class Echo | |
def echo(str) | |
str | |
end | |
end | |
DRb.start_service('druby://localhost:9999', Echo.new) | |
DRb.thread.join |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ruby echo_server.rb & | |
[1] 28111 | |
$ ruby echo_client.rb | |
PID 28134: Failure! too large packet 67654656 | |
PID 28128: Failure! incompatible marshal file format (can't be read) | |
format version 4.8 required; 0.0 given | |
PID 28125: Failure! too large packet 67651874 | |
PID 28144: Succeded. | |
PID 28147: Succeded. | |
PID 28192: Succeded. | |
PID 28176: Succeded. | |
PID 28167: Succeded. | |
PID 28186: Succeded. | |
PID 28152: Succeded. | |
PID 28150: Succeded. | |
PID 28131: Succeded. | |
PID 28170: Succeded. | |
PID 28137: Succeded. | |
PID 28173: Succeded. | |
PID 28164: Succeded. | |
PID 28179: Succeded. | |
PID 28182: Succeded. | |
PID 28139: Succeded. | |
PID 28158: Succeded. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment