2013-04-25 21:12:17 +00:00
|
|
|
#lang scribble/manual
|
|
|
|
@require[racket/include]
|
|
|
|
@include{prelude.inc}
|
|
|
|
|
|
|
|
@title{Drivers}
|
|
|
|
|
|
|
|
@section{event-relay}
|
2013-04-30 21:03:25 +00:00
|
|
|
|
|
|
|
@defmodule[marketplace/drivers/event-relay]{
|
|
|
|
|
|
|
|
@defproc[(event-relay [self-id Symbol]) Spawn]{
|
|
|
|
|
|
|
|
Lets processes in some @racket[nested-vm] interact with the outside
|
|
|
|
world using @racket[ground-vm]-level event-based subscriptions.
|
|
|
|
|
|
|
|
Returns a @racket[spawn] which starts an event-relay process with
|
|
|
|
debug-name @racket[`(event-relay ,self-id)].
|
|
|
|
|
|
|
|
The relay process observes subscriptions matching the topic-pattern
|
|
|
|
@racket[(cons (? evt?) _)], and when one appears, constructs an
|
|
|
|
analogous one using @racket[at-meta-level] to connect to the next VM
|
|
|
|
down the stack. Messages from the meta-level will be relayed up to the
|
|
|
|
current level. When the subscription disappears, the relay withdraws
|
|
|
|
the subscription at the meta-level as well.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-04-25 21:12:17 +00:00
|
|
|
@section{tcp-bare}
|
2013-04-30 21:03:25 +00:00
|
|
|
|
|
|
|
@defmodule[marketplace/drivers/tcp-bare]{
|
|
|
|
|
|
|
|
This module is only available for use by untyped Racket processes. It
|
|
|
|
is included by default in programs using @tt{#lang marketplace}; see
|
|
|
|
@secref{hashlang-variations} for information on other language
|
|
|
|
variants.
|
|
|
|
|
|
|
|
@defproc[(tcp-driver) Spawn]{
|
|
|
|
|
|
|
|
Returns a @racket[spawn] action which starts a TCP driver. The TCP
|
|
|
|
driver should run either directly in a ground VM, or in a nested VM
|
|
|
|
with a running @racket[event-relay].
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@subsection{TCP channels}
|
|
|
|
|
|
|
|
@defstruct*[tcp-channel ([source TcpAddress]
|
|
|
|
[destination TcpAddress]
|
|
|
|
[subpacket TcpSubPacket]) #:prefab]{
|
|
|
|
|
|
|
|
A TCP channel represents a section of a unidirectional TCP flow
|
|
|
|
appearing on our local "subnet" of the full TCP network, complete with
|
|
|
|
source, destination and subpacket. Each TCP connection has two such
|
|
|
|
flows: one inbound (remote-to-local) bytestream, and one outbound
|
|
|
|
(local-to-remote) bytestream.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@deftype[TcpSubPacket (or/c eof-object? bytes?)]{
|
|
|
|
|
|
|
|
Packets carried by @racket[tcp-channel] structures are either
|
|
|
|
end-of-file objects or raw binary data represented as Racket byte
|
|
|
|
vectors.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@subsection{TCP addresses}
|
|
|
|
|
|
|
|
@deftype[TcpAddress (or/c tcp-address? tcp-handle? tcp-listener?)]{
|
|
|
|
|
|
|
|
A TCP address describes one end of a TCP connection. It can be either
|
|
|
|
|
|
|
|
@itemlist[
|
|
|
|
@item{a @racket[tcp-address], representing a remote socket;}
|
|
|
|
@item{a @racket[tcp-handle], representing a local socket on a kernel-assigned port; or}
|
|
|
|
@item{a @racket[tcp-listener], representing a local socket on a user-assigned port.}
|
|
|
|
]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@defstruct*[tcp-address ([host string?]
|
|
|
|
[port (integer-in 0 65535)]) #:prefab]{
|
|
|
|
|
|
|
|
Describes a remote half-connection. The @racket[host] part is to be a
|
|
|
|
string containing either a hostname (e.g. @racket["localhost"]) or an
|
|
|
|
ASCII representation of an IP address (e.g. @racket["127.0.0.1"]).
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@defstruct*[tcp-handle ([id any/c]) #:prefab]{
|
|
|
|
|
|
|
|
Describes a local half-connection with a kernel-assigned port number.
|
|
|
|
The port number is not directly accessible; the @racket[id] is used as
|
|
|
|
a local name for whichever underlying port number ends up being used.
|
|
|
|
|
|
|
|
The @racket[id] must be chosen carefully: it is scoped to the local
|
|
|
|
VM, i.e. shared between processes in that VM, so processes must make
|
|
|
|
sure not to accidentally clash in handle ID selection. They are also
|
|
|
|
used in TcpChannel to mean a specific @emph{instance} of a TCP
|
|
|
|
connection, so if you are likely to want to reconnect individual
|
|
|
|
flows, use different values for @racket[id].
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@defstruct*[tcp-listener ([port (integer-in 0 65535)]) #:prefab]{
|
|
|
|
|
|
|
|
Describes a local half-connection with a user-assigned port number.
|
|
|
|
Use this to describe server sockets.
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@subsection{Opening an outbound connection}
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
@subsection{Accepting inbound connections}
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
@subsection{Receiving data}
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
@subsection{Sending data}
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
2013-04-25 21:12:17 +00:00
|
|
|
@section{tcp}
|
2013-04-30 21:03:25 +00:00
|
|
|
|
|
|
|
TODO
|
|
|
|
|
2013-04-25 21:12:17 +00:00
|
|
|
@section{timer (typed and untyped)}
|
2013-04-30 21:03:25 +00:00
|
|
|
|
|
|
|
TODO
|
|
|
|
|
2013-04-25 21:12:17 +00:00
|
|
|
@section{udp (typed and untyped)}
|
2013-04-30 21:03:25 +00:00
|
|
|
|
|
|
|
TODO
|