Elixir/Ports and external process wiring: Difference between revisions
more aside |
No edit summary |
||
| Line 46: | Line 46: | ||
] | ] | ||
) | ) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 67: | Line 62: | ||
}} | }} | ||
Rsync outputs progress lines in a fairly self-explanatory format:<syntaxhighlight lang="text"> | |||
3,342,336 33% 3.14MB/s 0:00:02 | |||
</syntaxhighlight> | |||
Our Port captures output and each line is sent to the library's <code>handle_info</code> callback as <code>{:data, line}</code>. After the transfer is finished we receive a conclusive <code>{:exit_status, status_code}</code> message. | |||
As a first step, we extract the percent_done column and log any unrecognized output: | |||
<syntaxhighlight lang="elixir"> | <syntaxhighlight lang="elixir"> | ||
with terms when terms != [] <- String.split(line, ~r"\s", trim: true), | with terms when terms != [] <- String.split(line, ~r"\s", trim: true), | ||
| Line 79: | Line 78: | ||
{:unknown, line} | {:unknown, line} | ||
end | end | ||
</syntaxhighlight>The <code>trim</code> lets us ignore spacing and newline | </syntaxhighlight>The <code>trim</code> is lifting more than its weight here: it lets us completely ignore spacing and newline trickery—and even a leading carriage return that we can see in the rsync source code, | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s", ...); | rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s", ...); | ||
</syntaxhighlight> | </syntaxhighlight>Carriage return <code>\r</code> deserves a special mention: this "control" character is just a byte in the binary data coming over the pipe from rsync, but its normal role is playing a control function because of how the terminal emulator responds to it. On a terminal the effect is to rewind the cursor and overwrite the current line! | ||
A repeated theme in inter-process communication is that data and control are leaky categories. We come to the more formal control side channels later. | |||
{{Aside|text= | {{Aside|text= | ||
[[File:Chinese typewriter 03.jpg|right|200x200px]] | [[File:Chinese typewriter 03.jpg|right|200x200px]] | ||
| Line 90: | Line 90: | ||
On the terminal, rsync progress lines are updated in place by emitting a [[w:Carriage return|carriage return]] control character, <code>\r</code>, <code>0x0d</code> sometimes rendered as <code>^M</code>. The character seems to be named after pushing the physical paper carriage of a typewriter back to the beginning of the line without feeding the roller. | On the terminal, rsync progress lines are updated in place by emitting a [[w:Carriage return|carriage return]] control character, <code>\r</code>, <code>0x0d</code> sometimes rendered as <code>^M</code>. The character seems to be named after pushing the physical paper carriage of a typewriter back to the beginning of the line without feeding the roller. | ||
[[w:https://en.wikipedia.org/wiki/Newline#Issues_with_different_newline_formats|Disagreement about carriage return]] vs. | [[w:https://en.wikipedia.org/wiki/Newline#Issues_with_different_newline_formats|Disagreement about carriage return]] vs. line feed has caused eye-rolling since the dawn of personal computing. | ||
[[File:Nilgais fighting, Lakeshwari, Gwalior district, India.jpg|left|200x200px]] | [[File:Nilgais fighting, Lakeshwari, Gwalior district, India.jpg|left|200x200px]] | ||