2012-07-11 13:35:20 +00:00
|
|
|
|
#lang racket/base
|
|
|
|
|
(require "../os2.rkt")
|
|
|
|
|
(require "../os2-tcp.rkt")
|
|
|
|
|
|
|
|
|
|
#|
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Desperately needs a name - "os-big-bang", "os2"
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
Outline ideas:
|
|
|
|
|
- the core of the idea is pubsub and presence. conversational
|
|
|
|
|
context - not raw messaging and actors.
|
|
|
|
|
- (frequently first-order-)functional programming of networked systems.
|
|
|
|
|
- similar to a generalisation of big-bang
|
|
|
|
|
- similar advantages obtain
|
|
|
|
|
- show code. Stuff that looks nice and illustrates the features of os2.
|
|
|
|
|
- transitions
|
|
|
|
|
- then the actions (spawn, roles, presence, messaging)
|
|
|
|
|
- then ground-vm
|
|
|
|
|
- then nested-vm
|
|
|
|
|
- then at-meta-level
|
|
|
|
|
|
|
|
|
|
Prepare for whiteboard + showing code. Light on the slides, if any.
|
|
|
|
|
|
|
|
|
|
Recent work in Network Application Architecture.
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Lots of systems, both formal models and practical implementations,
|
|
|
|
|
work with messaging between actors or actor-like entities. Notably
|
|
|
|
|
Erlang and the π-calculus.
|
|
|
|
|
|
|
|
|
|
In these systems, actors/processes have conversations with one
|
|
|
|
|
another, but the programming languages themselves don't talk about
|
|
|
|
|
conversations or patterns of interaction larger than a single exchange
|
|
|
|
|
of a message from a single sender to a single receiver.
|
|
|
|
|
|
|
|
|
|
Whiteboard
|
|
|
|
|
First point: receivers = 1 i.e. point-to-point/unicast
|
|
|
|
|
Second point: granularity = single message
|
|
|
|
|
|
|
|
|
|
By contrast, lots of the communicating systems we want to model have
|
|
|
|
|
more interesting conversational patterns.
|
|
|
|
|
|
|
|
|
|
HTTP: request/response; streaming; authentication; sessions
|
|
|
|
|
TCP: bidirectional; ongoing stream; connected
|
|
|
|
|
Bittorrent: multiparty; cooperative; unordered
|
|
|
|
|
Mailing lists: pub/sub; subscription management
|
|
|
|
|
|
|
|
|
|
So generally we can say that communication is instead
|
|
|
|
|
|
|
|
|
|
Whiteboard
|
|
|
|
|
receivers = many i.e. multicast/broadcast/M-of-N
|
|
|
|
|
granularity = session/conversation/connection
|
|
|
|
|
|
|
|
|
|
The research I've been doing has been examining the idea of a
|
|
|
|
|
conversational context: the envelope within which a group of
|
|
|
|
|
communicating actors/processes work together to achieve some shared
|
|
|
|
|
task.
|
|
|
|
|
|
|
|
|
|
There's a rich area of work dealing with describing the patterns of
|
|
|
|
|
message exchange themselves, for example session types and behavioural
|
|
|
|
|
contracts, but I'm looking at it from a different angle:
|
|
|
|
|
|
|
|
|
|
- how do actors interested in communicating find each other?
|
|
|
|
|
Whiteboard
|
|
|
|
|
Discovery
|
|
|
|
|
Synchronisation
|
|
|
|
|
- how does a conversation start?
|
|
|
|
|
Resource allocation
|
|
|
|
|
- how are resources managed during a conversation?
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Responsibility
|
|
|
|
|
Error control
|
2012-07-11 13:35:20 +00:00
|
|
|
|
Flow control
|
|
|
|
|
- how do participants know when a conversation is over?
|
|
|
|
|
Error/crash/exit signalling
|
|
|
|
|
Resource release
|
|
|
|
|
- how do conversations fit in to the underlying network system?
|
|
|
|
|
Routing
|
|
|
|
|
- what are the roles involved in various kinds of conversation?
|
|
|
|
|
Sender/Receiver
|
|
|
|
|
Scribe? Archivist? Statistician? Auditor?
|
|
|
|
|
|
|
|
|
|
To experiment with this I've come up with a model operating system,
|
|
|
|
|
and used it to implement a DNS caching proxy and an SSH server.
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Whiteboard
|
|
|
|
|
Functional pub/sub + presence
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
The model operating system is based on multicast/pubsub, and also
|
|
|
|
|
includes a construct for working with conversational context. I've
|
|
|
|
|
been calling it "presence", since it's a generalisation of an idea
|
|
|
|
|
from the XMPP/Jabber world, but you could equally well call it
|
|
|
|
|
"interest" or "subscription".
|
|
|
|
|
|
|
|
|
|
It's pure functional and event-based - very reminiscent of big-bang,
|
|
|
|
|
and so has similar characteristics, including processes usually having
|
|
|
|
|
first-order state - and recursive, meaning that instances of the
|
|
|
|
|
kernel can run as user processes within another kernel instance.
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
- Gives a "thread" equivalent that composes
|
|
|
|
|
- Hide implementation detail: hide threads away in a nested-vm
|
|
|
|
|
with a private language
|
|
|
|
|
|
|
|
|
|
There's a kind of hypervisor - which I'm calling a ground-vm - which
|
|
|
|
|
connects to the real world using Racket's CML-inspired event
|
|
|
|
|
mechanism.
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
Each process within an instance of the system has private state, and a
|
|
|
|
|
collection of active endpoints. Again the terminology here is a bit
|
|
|
|
|
loose, and while I usually think of endpoints as subscriptions or
|
|
|
|
|
event sources, they also make sense as TCP-like half-connections or
|
|
|
|
|
more loosely as representing participation in a particular (set of)
|
|
|
|
|
conversation(s).
|
|
|
|
|
|
|
|
|
|
Whiteboard
|
|
|
|
|
|
|
|
|
|
Process = ∃State . State × [Endpoint]
|
|
|
|
|
where
|
|
|
|
|
Endpoint = Topic × Role × InterestType
|
|
|
|
|
× PresenceHandler
|
|
|
|
|
× AbsenceHandler
|
|
|
|
|
× MessageHandler
|
|
|
|
|
|
|
|
|
|
PresenceHandler = Topic → State → Transition
|
|
|
|
|
AbsenceHandler = Topic × Reason → State → Transition
|
|
|
|
|
MessageHandler = Message → State → Transition
|
|
|
|
|
|
|
|
|
|
Transition = State × [Action]
|
|
|
|
|
|
|
|
|
|
Topic = notional set of Messages
|
|
|
|
|
Role = 'Subscriber + 'Publisher + ...
|
|
|
|
|
InterestType = 'Participant + 'Observer + 'SuperObserver
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Motivate endpoints vs Erlang-style single mailbox
|
|
|
|
|
- The system should make it possible for programs that would
|
|
|
|
|
otherwise block on some external operation to remain responsive to
|
|
|
|
|
their normal inputs while waiting for the external operation to
|
|
|
|
|
complete.
|
|
|
|
|
|
|
|
|
|
Topics are /just/ sets of messages. Hence, messages include their
|
|
|
|
|
topic. This is like packets being wrapped in a header to become a
|
|
|
|
|
packet at the next layer down.
|
|
|
|
|
|
|
|
|
|
An endpoint includes not just a role and a set of messages, but also an /interest type/.
|
|
|
|
|
- participant
|
|
|
|
|
- observer/monitor
|
|
|
|
|
- "super"-observer/monitor
|
|
|
|
|
|
|
|
|
|
Observers are useful for resource management.
|
|
|
|
|
|
|
|
|
|
Example: Bank teller
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
The kernel runs a process in response to some external event, and it
|
|
|
|
|
expects back a new process state and a list of actions that the
|
|
|
|
|
process wishes the kernel to perform on its behalf.
|
|
|
|
|
|
|
|
|
|
Process = ∃State . State × [Endpoint]
|
|
|
|
|
where (...)
|
|
|
|
|
Action = 'Yield (State → Transition)
|
|
|
|
|
+ 'AtMetaLevel Preaction
|
|
|
|
|
+ Preaction
|
|
|
|
|
Preaction = 'AddRole Endpoint
|
|
|
|
|
+ 'DeleteRole Endpoint
|
|
|
|
|
+ 'SendMessage Message
|
|
|
|
|
+ 'Spawn (∃State . State × [Action])
|
|
|
|
|
|
|
|
|
|
VMState = Process × [Action]
|
|
|
|
|
|
|
|
|
|
runVM :: VMState → VMState × [Action]
|
|
|
|
|
|
|
|
|
|
nestedVM :: (∃State . State × [Action]) → (VMState × [Action])
|
|
|
|
|
nestedVM bootProcess = ...
|
|
|
|
|
|
|
|
|
|
groundVM :: (∃State . State × [Action]) → 0
|
|
|
|
|
groundVM bootProcess = ...
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Example: TCP. Talk about the roles of observers.
|
|
|
|
|
- listener-factory: #:monitor 'everything
|
|
|
|
|
- connection-factory: #:monitor #t
|
|
|
|
|
- listener: #:monitor 'everything (to detect when counterpart goes away)
|
|
|
|
|
- connections: #:monitor #f
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (main)
|
|
|
|
|
(ground-vm
|
|
|
|
|
(transition 'none
|
|
|
|
|
(spawn tcp-driver)
|
|
|
|
|
(spawn listener))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define listener
|
|
|
|
|
(let ((local-addr (tcp-listener 5999)))
|
|
|
|
|
(transition 'no-state
|
|
|
|
|
(role 'inbound-handler
|
|
|
|
|
(topic-subscriber (tcp-channel (wild) local-addr (wild))
|
|
|
|
|
#:monitor? #t)
|
|
|
|
|
#:state state
|
|
|
|
|
#:topic t
|
|
|
|
|
#:on-presence
|
|
|
|
|
(match t
|
|
|
|
|
[(topic 'publisher (tcp-channel remote-addr (== local-addr) _) #f)
|
|
|
|
|
(transition state
|
|
|
|
|
(spawn (connection-handler local-addr remote-addr)))])))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (connection-handler local-addr remote-addr)
|
|
|
|
|
(transition 'no-state
|
|
|
|
|
(send-feedback (tcp-channel remote-addr local-addr (tcp-mode 'lines)))
|
|
|
|
|
(send-feedback (tcp-channel remote-addr local-addr (tcp-credit 1)))
|
|
|
|
|
(role 'echoer
|
|
|
|
|
(topic-subscriber (tcp-channel remote-addr local-addr (wild)))
|
|
|
|
|
#:state state
|
|
|
|
|
#:on-absence (transition state
|
|
|
|
|
(kill))
|
|
|
|
|
[(tcp-channel _ _ (? bytes? line))
|
|
|
|
|
(define reply (bytes-append #"You said: " line #"\n"))
|
|
|
|
|
(transition state
|
|
|
|
|
(send-feedback (tcp-channel remote-addr local-addr (tcp-credit 1)))
|
|
|
|
|
(send-message (tcp-channel local-addr remote-addr reply)))]
|
|
|
|
|
[(tcp-channel _ _ (? eof-object?))
|
|
|
|
|
(transition state
|
|
|
|
|
(kill))])))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (connection-handler local-addr remote-addr)
|
|
|
|
|
(transition 'no-state
|
|
|
|
|
(role 'date-sender (topic-publisher (tcp-channel local-addr remote-addr (wild)))
|
|
|
|
|
#:state state
|
|
|
|
|
[(tcp-channel _ _ (tcp-credit _))
|
|
|
|
|
(transition state
|
|
|
|
|
(kill))])
|
|
|
|
|
(send-message (tcp-channel local-addr remote-addr
|
|
|
|
|
(string->bytes/utf-8
|
|
|
|
|
(format "~a\n" (current-inexact-milliseconds)))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-11 13:35:20 +00:00
|
|
|
|
#|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
2012-07-11 15:57:25 +00:00
|
|
|
|
Talk about DNS and SSH
|
|
|
|
|
|
|
|
|
|
DNS structure:
|
|
|
|
|
- timer
|
|
|
|
|
- udp
|
|
|
|
|
- server
|
|
|
|
|
- timer-relay
|
|
|
|
|
- query-id-allocator
|
|
|
|
|
- reader (server)
|
|
|
|
|
- writer (server)
|
|
|
|
|
|
|
|
|
|
(server)
|
|
|
|
|
- error-logger
|
|
|
|
|
- respondent
|
|
|
|
|
|
|
|
|
|
(proxy)
|
|
|
|
|
- reader (client)
|
|
|
|
|
- writer (client)
|
|
|
|
|
- packet-dispatcher
|
|
|
|
|
+ packet-relay
|
|
|
|
|
- question-dispatcher
|
|
|
|
|
+ question-handler
|
|
|
|
|
+ glueless-question-handler
|
|
|
|
|
+ network-query
|
|
|
|
|
|
|
|
|
|
SSH structure:
|
|
|
|
|
- timer
|
|
|
|
|
- tcp
|
|
|
|
|
- listener
|
|
|
|
|
+ session
|
|
|
|
|
- exception-handler
|
|
|
|
|
- event-relay
|
|
|
|
|
- timer-relay
|
|
|
|
|
- reader
|
|
|
|
|
- writer
|
|
|
|
|
- session
|
|
|
|
|
- application
|
|
|
|
|
- boot process
|
|
|
|
|
- ... any others
|
|
|
|
|
|
|
|
|
|
Compare the "natural" structure of SSH with the structure using nested VMs
|
|
|
|
|
Whiteboard
|
|
|
|
|
Diagram of 14 Oct 2011 from my research journal
|
2012-07-11 13:35:20 +00:00
|
|
|
|
|
|
|
|
|
Contracts
|
|
|
|
|
- for process state (implemented)
|
|
|
|
|
- for messages across the bus at each level
|
|
|
|
|
- between processes / within conversations
|
|
|
|
|
|
|
|
|
|
Weaknesses
|
|
|
|
|
- The Wart
|
|
|
|
|
- Glitching
|
|
|
|
|
- There’s maybe a kind of continuousness (in the calculus sense)
|
|
|
|
|
at play here: well-behaved presence apps don’t glitch in their
|
|
|
|
|
presence. Sets of interests smoothly evolve without transient
|
|
|
|
|
drops of interest potentially leading to confusion on the part
|
|
|
|
|
of the peer.
|
|
|
|
|
- Handoff of responsibility
|
|
|
|
|
- the manager can take responsibility, spawn, and then drop when
|
|
|
|
|
it sees the child is up or crashed; or
|
|
|
|
|
- the manager can spawn without taking, and blip on crash; or
|
|
|
|
|
- the manager can spawn and then treat like an established service
|
|
|
|
|
instance
|
|
|
|
|
- Querying the routing table
|
|
|
|
|
- e.g. for sending SSH channel opens: is the channel type
|
|
|
|
|
supported? querying the routing table would let us find out
|
|
|
|
|
without explicitly sending a message
|
2012-07-11 15:57:25 +00:00
|
|
|
|
- Careful protocol design at all levels
|
|
|
|
|
- Ground events are (cons/c evt/c any/c)
|
|
|
|
|
- This is the set of all possible responses to sync'ing on that event!
|
|
|
|
|
- I've scraped by with this so far, but because sync'ing has
|
|
|
|
|
side-effects, I'll eventually need better names for event
|
|
|
|
|
requests and responsibility transfer.
|
2012-07-11 13:35:20 +00:00
|
|
|
|
|
|
|
|
|
This got me thinking: the presence/messaging system I’ve been building
|
|
|
|
|
looks like a hybrid between synchronous and asynchronous messaging. Is
|
|
|
|
|
it fair to say you can use the presence mechanism to synchronise, and
|
|
|
|
|
then the messaging mechanism to communicate?
|
|
|
|
|
|
|
|
|
|
Rendezvous via presence: this makes temporal dependencies between
|
|
|
|
|
processes during system startup resolve themselves automatically. No
|
|
|
|
|
more races at boot time!
|
|
|
|
|
|
|
|
|
|
Exceptions and errors are propagated via loss of presence.
|
|
|
|
|
- Erlang's process links and monitors can be seen as a special case
|
|
|
|
|
of this mechanism.
|
|
|
|
|
- Erlang/OTP-like supervisors fit naturally into this picture
|
|
|
|
|
|
|
|
|
|
|#
|