A set of scenarios so I can clarify my thoughts about how we need to integrate Mirage, Mirari, Froc, Lwt, etc.
Introduction of new "device" (typically logically via XenStore) potentially provokes app to use new device. E.g., higher performance network interface available; ARP change; existence of new, more appropriate storage.
Does libfable
just take care of all these cases?
Incoming reconfiguration to this instance triggers reconfiguration in other instances. E.g., interface change in A triggers routing change that must be propagated to routers B and C. Dustclouds.
Increase/decrease in load causes need to change scale of app. Response is to create a new instance or determine which instance to destroy, and update OpenFlow or other network config.
Data-space handled by Lwt
or other threading system. The state of a running unikernel.
Configuration-space handled by Froc
or other FRP system. Also a unikernel ultimately, but in a "manager" role.
Assumption: data-space unikernels have some communication channel back to the configuration-space.
Behaviors or Changeables (Froc
), or Signals (React
) are values that can change over time, but are defined at all times.
Events (Froc
and React
) are defined only at particular instants in time, possibly (but not necessarily) with a different value at each instant.
NB. Froc
uses signals to refer to events and behaviors when the distinction isn't important.
Need to communicate changes in data-space into the Froc
computation. The Froc
computation will then act on this, e.g., by spinning up a new VM.
How does the system, consisting of a set of unikernels including exactly (at least?) one Mirari unikernel (which itself encodes the transition function), transition from state S(t) transition to state S(t+1) following this update?
So we need mechanisms for:
- an
'a Unikernel
to deliver a signal to the Mirari unikernel; - the Mirari unikernel to transform its state as a result of that signal; and
- as a result of that transformation, the Mirari unikernel to transform the state of zero or more of the
'a Unikernels
it controls.
(1), assuming the Mirari unikernel itself uses Lwt
to handle external IO, requires a way to emit an event from an 'a Lwt
, restarting the 'a Lwt
.
(2) requires the Mirari unikernel effectively to wrap up an FRP computation.
(3) requires the Mirari unikernel to be able to construct, start and kill 'a Unikernel
s on the fly.
- support for transforming
Lwt
threads into FRP events. - support for
view each 'a Unikernel
as a type that supports certain operators. what should those operators be? can then represent this set in an FRP computation inside mirari (?)
need to bridge IO world (Lwt) into FRP (Froc) in mirari
FRP computation has nodes that may have sideeffects, one of which may be to create/destroy an 'a Unikernel
does this mean we need Froc's ability to "detach" nodes in the FRP computation, representing destruction of a unikernel?
'a
in the above really represents the feature set that's been compiled in -- the libraries that mirari chose to link to create the 'a Unikernel
in question (?)
Need to communicate config changes into data-space, i.e., to transform the current data-space configuration (set of 'a Lwt
) as a result of a change in configuration-space. This is the direction that can be mocked up via fork plus transformation function per anil's suggestion.
Need to treat reconfigurations as atomic -- so avoid yield during reconfiguration (update behaviours and propagate) -- like having well-defined time steps in a simulation. (The synchrony hypothesis.)
So do we just wrap Lwt
in a monad with some accessor functions?
This would tie together an 'a Lwt
with an 'a Behaviour
, would manage the big list of 'a Lwt
so that they can all happily co-schedule, and would lift the result when an 'a Lwt
terminates into its corresponding 'a Behaviour
.