Created
December 8, 2012 03:58
-
-
Save Keno/4238526 to your computer and use it in GitHub Desktop.
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
Howto and overview of new I/O system: | |
Using spawn and run | |
------------------- | |
Commands are specified with backticks as before: | |
julia> `echo test` | |
`echo test` | |
Cmd objects can be asynchronously executed using ``spawn`` or executed | |
as ususal using ``run``. However, by default spawn will not pass parent | |
STDIO to the child: | |
julia> run(`echo test`) | |
test | |
true | |
julia> spawn(`echo test`) | |
Process(`echo test`, ProcessRunning()) | |
``spawn`` and ``run`` both optionally take a Stream to be read from/written to. | |
Be careful when using these with ``spawn`` though, as julia will proceed as | |
usual and may cause strange interactions. E.g. | |
julia> spawn(`echo test`,STDIN,STDOUT,STDERR) | |
Process(`echo test`, ProcessRunning()) | |
julia> test | |
julia> run(`echo test`,STDIN,STDOUT,STDERR) | |
test | |
true | |
Note that the "test\n" that caused the second julia prompt is the one from | |
echo. The following also works: | |
julia> spawn(`echo test` > STDOUT) | |
Process(`echo test`, ProcessRunning()) | |
julia> test | |
julia> Base.spawn_nostdin(`echo test`,STDOUT) | |
Process(`echo test`, ProcessRunning()) | |
julia> test | |
``spawn_nostdin`` may or may not be exported in the future. | |
The old piping operations are supported as well. | |
Streams | |
------- | |
All streams are subtypes of ``AsyncStream``. In the examples above, STDOUT, | |
STDIN and STDERR were used though any stream should work: | |
julia> Base.connect_to_host("localhost",uint16(2000)) | |
TcpSocket(Ptr{Void} @0x0000000105488cc0,true,true,IOString([],true,true,false,true,0,9223372036854775807,1),false,[],false,[],false,[]) | |
julia> spawn(`echo test`>ans) | |
Process(`echo test`, ProcessRunning()) | |
A server running on localhost:2000 (e.g.`nc -l 2000`), receive the string "test". | |
Operations on streams are asynchronous by design (see below for API), but | |
the usual synchronous methods exist as well: | |
julia> read_from(`git status`) | |
(NamedPipe(Ptr{Void} @0x0000000107346300,IOString([],true,true,false,true,0,9223372036854775807,1),true,true,false,[],false,[]),Process(`git status`, ProcessRunning())) | |
julia> pipe = ans[1] | |
julia> a=zeros(Uint8,2000); read(pipe,a); readall(pipe) | |
"o commit but untracked files present (use \"git add\" to track)\n" | |
Asynchronous interface | |
---------------------- | |
libuv and Julia's I/O system built upon it is inherently asynchronous. | |
This asynchronous API is at the moment considered somewhat low-lvel, | |
though a high level asynchronous API (or just a cleanup and thorough | |
documentation of the current one) will certainly come at some point. The | |
following callbacks are available at the moment: | |
- connectcb(sock::AsyncStream, status::Int32) #On TcpSocks from connect | |
- connectioncb(sock::AsyncStream, status::Int32) # " " from listen | |
- readcb(stream, nreadable) #New data is available in the buffer | |
- closecb(handle) #Called when libuv has closed and is done with all | |
resources associated with the handle | |
- exitcb(proc, exit_status, term_signal) #A process has exited | |
There's also a few other ones relating to timers, etc. and a few internal | |
ones that are not listed here. These can be dealt with in a future revision | |
To see how all this work consider the following example: | |
julia> Base.open_any_tcp_port(uint16(2000),(server,status)->begin | |
if(status != 0) | |
error("Failed create server") | |
else | |
println("Client Connected") | |
client = TcpSocket() | |
client.readcb = (sock,args...)->begin | |
println("Read Callback") | |
spawn(`git status` > sock) | |
false #ignore unread buffer content | |
end | |
client.closecb = (args...)->begin | |
println("Client closed the connection") | |
end | |
accept(server,client) | |
Base.start_reading(client) | |
end | |
end) | |
Note that the second argument open_any_tcp_port is the connectioncb to be | |
set on the server. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment