Talk outline

This commit is contained in:
Tony Garnock-Jones 2012-07-11 09:35:20 -04:00
parent 0dc11f7ccb
commit 07922cec64
1 changed files with 316 additions and 0 deletions

View File

@ -0,0 +1,316 @@
#lang racket/base
(require "../os2.rkt")
(require "../os2-tcp.rkt")
#|
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.
---------------------------------------------------------------------------
Desperately needs a name - "os-big-bang", "os2"
Intro:
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?
Acknowledgement
Nacks
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.
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.
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
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 = ...
---------------------------------------------------------------------------
|#
(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))])))
#|
---------------------------------------------------------------------------
Messages include their topics: topics are after all just sets of messages
- This means 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.
Contracts
- for process state (implemented)
- for messages across the bus at each level
- between processes / within conversations
Functional pub/sub
Motivate nested VM model
- Helper subprograms that have internal communication actions should
not have those actions manifest in their interface: what would be
stateful/side-effecting subroutine calls in Scheme should retain
that RPC-like request/response flavour in our system.
- Either the states of a subprogram and its callers should remain
separate, or some powerful help should be provided by the system to
make sure they are combined in a clean, manageable,
arbitrarily-composable fashion.
- The system should make it possible to invoke a subprogram without
needing to be aware of whether and how that subprogram in turn
chooses to invoke sub-subprograms.
Motivate roles 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.
Can represent the "natural" structure of SSH in terms of nested VMs
Whiteboard
Diagram of 14 Oct 2011 from my research journal
Ground-level events and a ground-level VM bottom out the recursion
Examples
HTTP Load Balancer
Bank Teller
Weaknesses
- The Wart
- Glitching
- Theres maybe a kind of continuousness (in the calculus sense)
at play here: well-behaved presence apps dont 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
Not just roles and sets, but *participation levels*
- participant
- observer/monitor
- "super"-observer/monitor
This got me thinking: the presence/messaging system Ive 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
|#