Skip to content
This repository was archived by the owner on Aug 14, 2020. It is now read-only.

Conversation

@jonboulle
Copy link
Contributor

tl;dr: this patch:

  • fixes a panic in the Volume type's String() method
  • ensures that the serialization of a Volume to/from a string is
    reversible - i.e., s == VolumeFromString(s).String()

Full details:

The Volume type is polymorphic; it can be of several different Kinds,
and for each Kind only a select few fields are valid. When new fields
(mode, uid, gid) were added to the empty volume Kind (via
26af7ce), they were simply added as new
fields. However, this means that Volume structs of Kinds for which those
fields are not valid (e.g. the host Kind) would necessarily have
values set in those fields - since in Go any fields will be
automatically set to their zero value. To mitigate this, the previous
code set special sentinel values to those fields (e.g. -1 to the
uid/mode fields) to indicate that they were "unset"; but this is
slightly awkward since it necessitates manually setting those sentinel
values at certain points.

This patch instead change those fields to be pointers, so that it is
trivially possible to determine whether or not those fields are really
set, and disambiguate from the zeroed value case. This also means that a
"zeroed" Volume type is really unset and does not need modification to
set the sentinels appropriately.

Another change is in how exactly a Volume type is serialized to a
string. String() previously attempted to dereference the readOnly
field even if it was not necessarily set. Even though such a nil
dereference would ordinarily cause the Go runtime to panic, the
fmt.Printf function (and friends) uses a recover() to actually
catch any panic occurred, so instead this results in a weird panic
trace within the returned string, but business otherwise continues as
usual (smdh).

As well as fixing this panic (by checking the pointer before
dereferencing), we now also construct the serialized Volume string
piece-by-piece, only if fields are set; for example, if an empty
Volume's mode field is set to the default value, we will omit it from
the serialized string.

@jonboulle
Copy link
Contributor Author

/cc @iaguis

@jonboulle jonboulle added this to the v0.7.2 milestone Nov 26, 2015
@jonboulle jonboulle mentioned this pull request Nov 26, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol. I hate this language.

tl;dr: this patch:
- fixes a panic in the Volume type's String() method
- ensures that the serialization of a Volume to/from a string is
  reversible - i.e., `s == VolumeFromString(s).String()`

Full details:

The `Volume` type is polymorphic; it can be of several different Kinds,
and for each Kind only a select few fields are valid. When new fields
(`mode`, `uid`, `gid`) were added to the `empty` volume Kind (via
26af7ce), they were simply added as new
fields. However, this means that Volume structs of Kinds for which those
fields are not valid (e.g. the `host` Kind) would necessarily have
values set in those fields - since in Go any fields will be
automatically set to their zero value. To mitigate this, the previous
code set special sentinel values to those fields (e.g. -1 to the
`uid`/`mode` fields) to indicate that they were "unset"; but this is
slightly awkward since it necessitates manually setting those sentinel
values at certain points.

This patch instead change those fields to be pointers, so that it is
trivially possible to determine whether or not those fields are really
set, and disambiguate from the zeroed value case. This also means that a
"zeroed" Volume type is really unset and does not need modification to
set the sentinels appropriately.

Another change is in how exactly a Volume type is serialized to a
string. `String()` previously attempted to dereference the `readOnly`
field even if it was not necessarily set. Even though such a nil
dereference would ordinarily cause the Go runtime to panic, the
`fmt.Printf` function (and friends) uses a `recover()` to actually
_catch_ any panic occurred, so instead this results in a weird panic
trace _within the returned string_, but business otherwise continues as
usual (smdh).

As well as fixing this panic (by checking the pointer before
dereferencing), we now also construct the serialized Volume string
piece-by-piece, only if fields are set; for example, if an `empty`
Volume's `mode` field is set to the default value, we will omit it from
the serialized string.
@jonboulle jonboulle force-pushed the voltypes branch 2 times, most recently from 0f625bf to 69f4046 Compare November 26, 2015 08:14
@vcaputo
Copy link
Contributor

vcaputo commented Nov 26, 2015

lgtm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if it works this looks weird

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's idiomatic actually :/
https://golang.org/doc/effective_go.html
search for "req := req"

jonboulle added a commit that referenced this pull request Nov 26, 2015
schema/types: rework empty volume type code
@jonboulle jonboulle merged commit 6a440ba into appc:master Nov 26, 2015
@jonboulle jonboulle deleted the voltypes branch November 26, 2015 09:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants