[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MirageOS-devel] mirageos 3.0 : let's break some APIs


On Mon, May 30, 2016 at 1:49 PM, Thomas Leonard <talex5@xxxxxxxxx> wrote:
On 18 May 2016 at 17:28, Mindy <mindy@xxxxxxxxxxxxxxxxxxx> wrote:
> Hi folks!
> With some exciting new developments (OCaml 4.03 with flambda, `result`,
> `logs`) and users, it's probably time to think about the broad world of
> possibilities unlocked by big changes to mirage-types. Here are some things
> that recently have been mentioned:
> * rename the `V1` and `V1_LWT` modules to something unversioned, like `S` or
> * replace or augment the `error` types with Result.result
> * break up `mirage-types` into a package per module type, so module types
> can be independently changed and released
> * changes to the semantics of functions in low-level module type definitions
> like `FS` and `NETWORK`
> I'm surely missing many things folks would want to incorporate in a big
> API-breaking release -- please do let us know what they are. :)
> Also, if you have any long-standing PRs or issues that are blocked because
> you don't want to do a big API-breaking change, links to them would be
> appreciated.

I'd very much like to make it easier to do API changes without having
to update everything at once. These issues are probably related to

https://github.com/mirage/mirage/pull/383 (Add `pp_error` to FLOW and
use a result type, from 2015)
https://github.com/mirage/mirage/pull/286 (Support checksum offload, from 2014)

Looking at the git logs for mirage-types, in the last 12 months we
only made one change to an existing module type, which was to remove

  val input_arpv4: t -> buffer -> unit io
  (** {b FIXME} *)

from IPV4. I guess this API had only one user (tcpip, which provides
both IP and ARP implementations).

This could mean that our APIs are nearly perfect and we can't think of
any improvements. But it could also mean that updating them is too
hard. The more implementations of an interface we have (e.g. Unix,
Xen, Solo5, _javascript_, etc) the harder it becomes to get them all
updated and released together.

If we could include multiple versions of an API in mirage-types, we
could release things in stages. e.g.

1. Add MIRAGE.NET.V2 to mirage-types.
2. Release mirage-net-xen, mirage-net-unix, mirage-net-... providing
V1 and V2 implementations. 
3. Release tcpip with support for V2. 
4. Update the mirage tool to use V2 to connect tcpip to net.

One of the things that puts me off making backwards-compatible changes today is that I fear I might not be able to complete the whole thing in one go and I might leave the world in an inconsistent state which then confuses other people and wastes their time. For example if I changed the `V1.NET` in mirage/types, and then didn't manage to finish updating and releasing everything, and then someone else comes along needing to make an urgent change in `mirage-net-xen` to fix a security issue then they might not spot the problem initially and waste time trying to fix and release master. IIRC when I left big unreleased code changes in ocaml-xenstore people kept tripping over them, assuming they had something in common with the current code in opam.

I could make the incompatible change to mirage/types and release that and simultaneously add upper-bounds to all the opam packages which depend on the old API. However if I'm thorough and add the bounds to old packages, inevitably I discover some of them fail `opam lint` checks :/ Inevitably I discover some of their dependencies also are missing bounds on other packages which have since been released. The more packages I touch the more the probability of a travis failure (e.g. timeout) tends towards 1 :( The removal of cstruct.syntax took much longer than I initially expected. I think this could be fixed with better tooling around opam -- if I could run the CI checks (including REVDEPS) entirely locally (e.g. in a container), iterate quickly and then supply a transcript of the local CI run in the PR to "prove" it's all fine, that would be much easier.

I quite like the idea of being able to implement 2 versions of an interface simultaneously -- it was very convenient that cstruct.1.9.0 supported both camlp4 and ppx at the same time.

I wonder whether we should split some of the API definitions out from the mirage/mirage repo. Instead we could depend on:

both of which have functions which operate over `BLOCK` and `FLOW`, and provide "enhanced" versions of the signatures e.g.

defines extra functions for resizable block devices (useful when dealing with qcow2 or vhd or similar) and block devices which can report sparseness information through `SEEK_HOLE` and `SEEK_DATA`. Perhaps the `BLOCK` API should be versioned with the mirage-block package?



Note that providing both versions of an interface is typically very
easy. In this case, V1.write would call V2.write with the default
flags, and V1.listen would wrap the callback argument with one that
discarded the flags.

Dr Thomas Leonard        http://roscidus.com/blog/
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

MirageOS-devel mailing list

Dave Scott
MirageOS-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.