[04:15] <Aram> good morning.
[07:46] <fwereade> yay, I has power
[08:15] <fwereade> going out to get some coffee and a pastry, still recovering from broken fridge :/
[09:02] <fwereade> heya TheMue
[09:02] <TheMue> Hi fwereade
[09:03] <TheMue> Hmm, I hope my line gets more stable when the new provider has set it up.
[09:15] <TheMue> Just seen, need a new watcher.
[09:44] <fwereade> TheMue, sorry, what watcher is that now? :)
[09:45] <TheMue> fwereade: The ServiceWatcher for added or removed services. It's needed by the firewall.
[09:45] <fwereade> TheMue, ah, cool
[09:46] <TheMue> fwereade: Thx to your watcher changes it's pretty simple now.
[09:46] <fwereade> TheMue, I kinda suspect that about 50% of juju will actually just be watchers of one sort or another by the time we're done :)
[09:46] <fwereade> TheMue, awesome
[09:46] <TheMue> fwereade: Yes, we're a kind of event-driven
[09:47] <fwereade> TheMue, yeah, totally
[09:49] <TheMue> fwereade: So one architecture alternative could have been that all those watchers publish their changes to a kind of bus where interested listeners subscribe to those events.
[09:50] <fwereade> TheMue, not sure, there are a number of subtle ordering interactions in a couple of places
[09:51] <fwereade> TheMue, we only want to watch X in between a specific pair of events on Y, for example
[09:51] <fwereade> TheMue, and we don't want to just watch ALL THE CHANGES all the time
[09:51] <fwereade> TheMue, I guess it could be done
[09:52] <TheMue> fwereade: That's depending on the subscription mechanism, would be possible
[09:52] <fwereade> TheMue, but I think unwatching X at the right time, in the example above, would be a bit fiddly
[09:54] <fwereade> TheMue, offhand, do you know whether we currently have any mechanism for putting *valid* environment configs into /environment?
[09:54] <fwereade> TheMue, I know we can poo an arbitrary map[string]interface{} in but I don't think there's yet any way to push a real env config implemented in real code
[09:57] <TheMue> fwereade: No, that doesn't sound real got.
[09:58] <TheMue> fwereade: The environment fields depend on the chosen environment?
[09:58] <fwereade> TheMue, yeah
[09:58] <fwereade> TheMue, I'm implementing bits and pieces in that area right now
[09:59] <fwereade> TheMue, I'm just trying to figure out whether I will break things *any worse than they currently are* if I follow my preferred path
[09:59] <TheMue> fwereade: So I would setup a type hierarchy per environment and implement a Validate() on each type working top-down.
[09:59] <fwereade> TheMue, whoa, hierarchy?>
[09:59] <TheMue> fwereade: I'm doing so for my private RSS and Atom implementation.
[09:59] <TheMue> fwereade: And that could be marshaled to e.g. JSON inside the node.
[09:59] <fwereade> TheMue, we already have code for validating them
[09:59] <fwereade> TheMue, NewConfig :)
[10:01] <TheMue> fwereade: Just see it, very generic.
[10:14] <niemeyer> Morning!
[10:19] <fwereade> niemeyer, heyhey
[10:19] <niemeyer> fwereade: Heya!
[10:20] <fwereade> niemeyer, how's it going?
[10:20] <niemeyer> fwereade: Great
[10:20] <niemeyer> fwereade: A little bit on the short side in terms of sleep, but hopefully will fix that tomorrow :)
[10:20] <fwereade> niemeyer, awesome; thanks again for the conversation yesterday, everything seems to be lining up really neatly now
[10:20] <niemeyer> fwereade: My pleasure!  Appreciated too.
[10:21] <fwereade> niemeyer, I have a couple of CLs that should be short/sweet: https://codereview.appspot.com/6345071/ and https://codereview.appspot.com/6351068/
[10:23] <TheMue> niemeyer: Morning
[10:23] <niemeyer> TheMue: Heya
[10:23] <niemeyer> fwereade: Looking
[10:39] <niemeyer> fwereade: https://codereview.appspot.com/6345071/ done
[10:43] <fwereade> niemeyer, cheers
[10:43] <niemeyer> fwereade: I'm not sure about the other one.. what's the benefit?
[10:52] <niemeyer> Aram: ping
[10:54] <TheMue> Hmm, sh**, have to reboot. Back in a moment.
[11:06] <fwereade> niemeyer, sorry, was making lunch
[11:06] <fwereade> niemeyer, benefit is that we can make State.EnvironConfig return an environs.EnvironConfig
[11:07] <fwereade> niemeyer, which really feels like the Right Thing now I've started implementing it
[11:12] <fwereade> niemeyer, (but incorporating the move in the forthcoming CL for EnvironConfig felt a bit much)
[11:12] <niemeyer> fwereade: How about moving EnvironConfig to state instead?
[11:13] <fwereade> niemeyer, don't think so offhand -- we also need NewConfig, and IMO that's unquestionably part of environs
[11:13] <fwereade> niemeyer, besides, the environs are meant to not depend on state, right?
[11:13] <niemeyer> fwereade: Why do we need NewConfig on State?
[11:14] <niemeyer> fwereade: Or is the state supposed to not depend on environs? ;-)
[11:14] <fwereade> niemeyer, because if we try to do environs.NewConfig from state we get an import cycle
[11:14] <niemeyer> fwereade: Why do we *need* NewConfig on state?
[11:15] <niemeyer> fwereade:
[11:15] <niemeyer> [niemeyer@gopher ..juju-core/state]% grep -r environs *
[11:15] <niemeyer> [niemeyer@gopher ..juju-core/state]%
[11:16] <fwereade_> niemeyer, sorry, don't know what happened there
[11:16] <fwereade_> niemeyer, because State.EnvironConfig wants to return an EnvironConfig, and all it has is a map[string]interface{}
[11:17] <niemeyer> fwereade_: Hmm.. something else seems wrong then
[11:17] <niemeyer> Thinking
[11:18] <niemeyer> fwereade_: Not sure if you've seen this, btw:
[11:18] <niemeyer> niemeyer> fwereade:
 [niemeyer@gopher ..juju-core/state]% grep -r environs *
 [niemeyer@gopher ..juju-core/state]%
[11:18] <fwereade_> niemeyer, yeah, tautologically so; environs was importing from state
[11:19] <niemeyer> fwereade_: Yes, which is a point worth bringing into the discussion
[11:20] <niemeyer> fwereade_: You say it's uncontroversial. It would be if we were simply taking a dependency down, but we're inverting a dependency
[11:20] <niemeyer> fwereade_: Some of the purpose of the Conn, for example, is precisely to integrate an environ with a state
[11:20] <fwereade_> niemeyer, environs is responsible for creating every known (non-test) instance of the types it imports from state
[11:21] <fwereade_> niemeyer, from a certain perspective, environs is the only "source" of those types
[11:22] <fwereade_> niemeyer, you were once very firm that environs must not depend on state -- do you recall something specific that changed your perspective?
[11:23] <fwereade_> niemeyer, another thought; if InstanceId were a type, that would be another one that would naturally live in environs and be used by state
[11:24] <niemeyer> fwereade_: That's not a relevant point.. the only purpose of state.Info is to provide it onto the state package as an argument to Dial. Of course it won't be *created* by the state package.
[11:26] <fwereade_> niemeyer, fair point indeed
[11:29] <fwereade_> niemeyer, the heart of it is that if we want State.EnvironConfig to return an environs.EnvironConfig, or even to be able to check the sanity of environment config changes, state needs to use environs
[11:30] <TheMue> So, new ServicesWatcher for review is in.
[11:30] <niemeyer> fwereade_: I'm not sure we do.. let's look at the overall issue without an established dogma to make sure we're doing the right thing
[11:32] <niemeyer> fwereade_: Here is an idea..
[11:33] <niemeyer> fwereade_: Configuration always comes in the form of keys, right?
[11:33] <fwereade_> niemeyer, yes
[11:33] <niemeyer> fwereade_: In state, in environments.yaml, and from the cmdline
[11:33] <fwereade_> niemeyer, agreed
[11:34] <niemeyer> fwereade_: We actually have infrastructure to deal with that information as keys even, in the form of the schema package
[11:34] <fwereade_> niemeyer, right...
[11:34] <niemeyer> fwereade_: So, it's at least interesting that we chose to transform that information onto a type so early on
[11:35] <niemeyer> fwereade_: What if..
[11:35] <niemeyer> fwereade_: EnvironsConfig was not an interface..
[11:35] <niemeyer> fwereade_: EnvironConfig, that is
[11:35] <niemeyer> fwereade_: But rather, *state.EnvironConfig
[11:35] <niemeyer> ?
[11:36] <fwereade_> niemeyer, how will that end up being noticeably different from the python-style data-bag?
[11:37] <niemeyer> fwereade_: I don't know what's the underlying statement you're making with that. The configuration of an environment *is* a data bag.
[11:38] <niemeyer> fwereade_: And this is quite bogus:
[11:38] <niemeyer> / EnvironConfig represents an environment's configuration.
[11:38] <niemeyer> type EnvironConfig interface {
[11:38] <niemeyer>         // Open opens the environment and returns it.
[11:38] <niemeyer>         Open() (Environ, error)
[11:38] <niemeyer> }
[11:38] <niemeyer> fwereade_: This is just wrong..
[11:38] <fwereade_> niemeyer, ok, we followed this approach in python, and we ended up in a totally ridiculous situation, in which keys were added and used willy-nilly without even being used in the schema
[11:39] <niemeyer> fwereade_: The interface of an environment configuration cannot tell us anything about the configuration, but *opens* the environment
[11:39] <niemeyer> wtf?
[11:39] <niemeyer> fwereade_: Well, we don't want that to happen for sure
[11:40] <niemeyer> fwereade_: But that's a separate issue
[11:40] <niemeyer> fwereade_: and one that you just helped solving, in fact ;)
[11:40] <fwereade_> niemeyer, well, it is a big advantage of turning things into actual types as early as we can :)
[11:41] <niemeyer> fwereade_: I'm not sure.. that's exactly why I started with this:
[11:41] <fwereade_> niemeyer, how is the configuration of an environment anyone's business but the environ itself? there are, it is true, some common properties, but they can be added to the EnvironConfig interface as we feel the need for them
 fwereade_: Here is an idea..
 fwereade_: Configuration always comes in the form of keys, right?
 fwereade_: In state, in environments.yaml, and from the cmdline
 fwereade_: We actually have infrastructure to deal with that information as keys even, in the form of the schema package
 fwereade_: So, it's at least interesting that we chose to transform that information onto a type so early on
[11:42] <niemeyer> fwereade_: Aren't you trying to inject a dependency on environs onto the state just so you can get an EnvironConfig from it?
[11:42] <niemeyer> fwereade_: Clearly it seems to be someone else's business too
[11:43] <niemeyer> fwereade_: cmdline, state, config
[11:43] <fwereade_> niemeyer, well, the state has to store EnvironConfigs somehow, right?
[11:44] <niemeyer> fwereade_: The configuration of an environment has well known fields, and then other flexible fields
[11:44] <fwereade_> niemeyer, sure, I would like at some stage to split the common fields out into their own type, but that's orthogonal
[11:44] <niemeyer> fwereade_: What I'm suggesting is that we, actually, realize the EnvironConfig into exactly what it is
[11:44] <niemeyer> fwereade_: We can have methods on it
[11:46] <niemeyer> fwereade_: And can also have a Specific method, for example that returns all the unknown fields
[11:46] <niemeyer> fwereade_: (*without* the well known ones.. we handle those internally)
[11:46] <fwereade_> niemeyer, and how are we meant to have any sanity-checking on those unknown fields?
[11:47] <niemeyer> fwereade_: That's the environ's business to do
[11:48] <fwereade_> niemeyer, ok, so State.Set/UpdateEnvironConfig should just poo whatever it's given into /environment and damn the consequences?
[11:48]  * niemeyer waits until fwereade_ relaxes again
[11:49]  * fwereade_ is sorry, but this feels like a pretty fundamental change in direction of which I had no warning
[11:49] <TheMue> fwereade_: Who, in the sense of which part of the code, knows what unknown fields are valid?
[11:49] <fwereade_> TheMue, something in environs
[11:50] <niemeyer> fwereade_: I think you're being slightly unfair
[11:50] <niemeyer> fwereade_: You're the one changing the direction of things
[11:50] <niemeyer> fwereade_: This is in state, today:
[11:50] <niemeyer> / EnvironConfig returns the current configuration of the environment.
[11:50] <niemeyer> func (s *State) EnvironConfig() (*ConfigNode, error) {
[11:50] <niemeyer>         return readConfigNode(s.zk, zkEnvironmentPath)
[11:50] <niemeyer> }
[11:50] <niemeyer> fwereade_: We're "pooing" stuff with "damned consequences" in the current code base
[11:51] <fwereade_> niemeyer, yes, and I feel it's a serious problem
[11:51] <TheMue> fwereade_: If it's in environs it doesn't seem unknown to me. environs only should handle well knows fields. If we have a need for more we should define a validator function type so that the provider/user of those fields could also provide a validator.
[11:51] <fwereade_> TheMue, so every time we create a State we pass in an EnvironConfigValidator?
[11:51] <niemeyer> fwereade_: Yes, so let's run through this with less emotion, ok? I'm not changing the direction of anything, and I'm not taking you by surprise on anything
[11:51] <fwereade_> niemeyer, you were very very clear in orlando that environs must not depend upon state
[11:52] <TheMue> fwereade_: Only when changing the content of the EnvironConfig.
[11:52] <niemeyer> fwereade_: and it does not depend on state.. it depends on data
[11:52] <niemeyer> fwereade_: We can put EnvironsConfig onto  the foobar package if you want
[11:52] <fwereade_> niemeyer, seeing environs using state, I thought "oh, that's just a mistake that has lain dormant because we hadn;t yet implemented enough to be aware of the problems"
[11:53] <niemeyer> fwereade_: I didn't say in Orlando "let's make state depend on environs"
[11:53] <niemeyer> fwereade_: Changing 6 by 12/2 won't help
[11:54] <fwereade_> niemeyer, ok, so your position is that state and environ should not know about one another at all?
[11:54] <niemeyer> fwereade_: Yes
[11:54] <fwereade_> niemeyer, but state should hold environment configuration?
[11:55] <niemeyer> fwereade_: Re-read that question again, and think through it in the broader sense of things for a moment
[11:55] <niemeyer> fwereade_: What *is* the state?
[11:55] <fwereade_> niemeyer, a description of the desired state of the environment?
[11:56] <TheMue> fwereade_: Is it something that represents a state or is it something we only store convenient in ZK?
[11:56] <niemeyer> fwereade_: Exactly.. it's the information about the whole environment
[11:56] <fwereade_> TheMue, AFAICT it absolutely represents state... not sure what you're getting at
[11:57] <niemeyer> fwereade_: We can put the type elsewhere
[11:57]  * TheMue asks to reflect this topic from a distance.
[11:57] <niemeyer> fwereade_: But the state will necessarily have to *hold the state configuration*!
[11:57] <niemeyer> Erm
[11:57] <niemeyer> fwereade_: But the state will necessarily have to *hold the environment configuration*!
[11:57] <niemeyer> fwereade_: There's simply no option for it to not do it
[11:57] <niemeyer> fwereade_: It does today, already
[11:58] <fwereade_> niemeyer, yes, this is at the heart of my conviction that the state package is a natural consumer of the environs package
[11:58] <niemeyer> fwereade_: That's the fundamental disagreement
[11:58] <niemeyer> fwereade_: The environs package *talks to the environment*
[11:58] <niemeyer> fwereade_: There's zero reason for the state package to talk to the environment
[11:58] <fwereade_> niemeyer, which abstracts away the differing features of various environs such that they can be used by other code without them having to worry about the differences between them
[11:58] <TheMue> fwereade_: My understanding has been that other packages (like environ) just *use* state.
[11:58] <niemeyer> fwereade_: The right thing for us to do is to break the dependency, both ways
[11:59] <fwereade_> niemeyer, ok, fine as far as it goes, wrt the types moved in the CL
[12:00] <fwereade_> niemeyer, but it seems to me that it is valuable for the state to be able to validate its environ config somehow
[12:00] <TheMue> IMHO environs has to read the configuration from state and instantiate the according "factory" (dislike the word) which then uses the config data to do the real setup.
[12:00] <niemeyer> fwereade_: It's valuable to validate the environ config somehow, agreed
[12:01] <niemeyer> fwereade_: The state doesn't have to do that, though
[12:01] <fwereade_> niemeyer, and I don't see how it can do that without using code from the environs package
[12:01] <niemeyer> fwereade_: The state package doesn't have to do that
[12:02] <TheMue> niemeyer: Validation has to be provided by the various environs, EnvironConfig only provide a mechanism.
[12:02] <niemeyer> TheMue: You can assume I understand that
[12:02] <fwereade_> niemeyer, I would prefer that it be *impossible* to set a broken environment config via the state package
[12:03] <TheMue> niemeyer: Fine
[12:03] <fwereade_> niemeyer, I guess we could also pass a ConfigValidator into state.Open, or something..?
[12:04] <fwereade_> niemeyer, hmm, ok, actually, the fundamental thing I don't understand is whystate  should not depend on environs
[12:04] <TheMue> fwereade_: IMHO only when writing the config.
[12:04] <fwereade_> niemeyer, would you expand on that a little?
[12:04] <niemeyer> fwereade_: It feels like a slightly abstract goal to me. There are very few places the system gets unreliable configuration from the outside world.
[12:05] <fwereade_> TheMue, so it's not worth checking validity on the way out? only on the way in?
[12:05] <niemeyer> fwereade_: On the way out?
[12:05] <TheMue> fwereade_: If it only can be written well validated, reading could be assumed as ok, yes.
[12:06] <niemeyer> TheMue: +1
[12:06] <niemeyer> fwereade_: We're not checking anything else for brokeness every time we load from state.. (?)
[12:08] <fwereade_> niemeyer, aren't we? in general I think we return either errors or valid instances, rather than timebombs without errors
[12:08] <TheMue> Exactly, only when during a following operation something weird is discovered an error is returned. This indeed can happen in operations depending on the config too (e.g. by changing it concurrently while it's already loaded by another part).
[12:09] <niemeyer> fwereade_: No.. if you get "poo (*&@(*#&(!" as a service name.. do we validate that?
[12:09] <niemeyer> fwereade_: This feels like a total departure
[12:09] <fwereade_> niemeyer, yeah, probably
[12:09] <fwereade_> niemeyer, could we return to "why should state not use environs" please? I think there's something I'm missing there
[12:10] <TheMue> Errors always may and can happen, so it's more useful to keep our software handling those errors well.
[12:11] <TheMue> fwereade_: It's a dependency thingy. environs uses state, state uses environs? Can't say exactly why, but I dislike this behavior.
[12:11] <fwereade_> TheMue, that's unpossible :)
[12:11] <niemeyer> fwereade_: Because it's much easier to keep things on track that way. The environs package and the specific implementations of environs have the goal of talking to an IaaS provider.
[12:12] <niemeyer> fwereade_: The state package has no business there.
[12:12] <niemeyer> fwereade_: If we start breaking that line, something is going wrong
[12:12] <niemeyer> fwereade_: That said,
[12:12] <niemeyer> fwereade_: I wouldn't be opposed to, for example,
[12:12] <fwereade_> niemeyer, I agree with that bit unquestionably :)
[12:13] <niemeyer> fwereade_: Introducing the environs/config package
[12:13] <niemeyer> fwereade_: and importing *that* from state
[12:13] <fwereade_> niemeyer, it's the other direction I don't see a fundamental problem with, because the state describes the environ and it seems odd to stipulate that it cannot know anything about the environ
[12:13] <fwereade_> niemeyer, ah-ha!
[12:13] <fwereade_> niemeyer, I can totally live with that
[12:13] <niemeyer> fwereade_: Woohay middle ground ;0
[12:13] <niemeyer> ;)
[12:14] <fwereade_> :D
[12:14] <TheMue> :D
[12:15] <fwereade_> niemeyer, so the Open stuff stays in environs, and all the other config stuff moves?
[12:16] <niemeyer> fwereade_: Yeah, we'll have to figure how to handle Open
[12:16] <niemeyer> fwereade_: I never liked the idea of EnvironConfig handling Open, fwiw
[12:17] <niemeyer> fwereade_: I think EnvironProvider.Open sounds sane..
[12:17] <fwereade_> niemeyer, that sounds pretty plausible to me
[12:17] <fwereade_> niemeyer, I'll kick it around and see how it turns out
[12:17] <niemeyer> fwereade_: Btw, I have a bikesheddy desire of renaming env to envs
[12:18] <niemeyer> Erm
[12:18] <niemeyer> fwereade_: Btw, I have a bikesheddy desire of renaming environs to envs
[12:18] <niemeyer> and Environ to Env
[12:18] <niemeyer> :-)
[12:18] <niemeyer> Maybe some day
[12:18] <fwereade_> niemeyer, +1 but it feels like a distraction right now ;)
[12:18] <niemeyer> fwereade_: It is
[12:19] <fwereade_> niemeyer, other issue -- should we keep Info and AssignemntPolicy in state, and consider environs' usage of same to be an acceptable purity break?
[12:20] <fwereade_> niemeyer, if not, where do they go?
[12:20] <niemeyer> fwereade_: I think both of these belong in state
[12:20] <niemeyer> fwereade_: Inherently
[12:20] <niemeyer> fwereade_: Info we've talked about
[12:20] <niemeyer> fwereade_: AssignmentPolicy is logic fully implemented in state
[12:20] <fwereade_> niemeyer, yeah, I'm ok with it, just wanted to confirm
[12:21]  * fwereade_ breaks out the chainsaw and goes to work on environs :)
[12:21] <niemeyer> fwereade_: ROTFL
[12:24] <TheMue> fwereade_: Be careful, don't forget the earmuffs and safety glasses.
[13:07] <TheMue> So folks, will continue tomorrow. Have to do some final preparations before the birthday guests are coming.
[13:15] <niemeyer> TheMue: Oh, is it your birthday today?
[14:29] <niemeyer> fwereade_: Oh, btw, I was going to ask you earlier about mstate vs. the test reorganization
[14:29] <niemeyer> fwereade_: Have you had a chance to look at that?
[14:51] <Aram> niemeyer: pong, oops, different computer.
[14:51] <Aram> niemeyer: thanks for the reviews.
[14:51] <Aram> reviewing the reviews.
[14:52] <Aram> great, thanks.
[14:58] <Aram> niemeyer: I can answer the last question, I am duplicating william's changes.
[14:59] <fwereade_> niemeyer, yeah, I started talking to Aram and he was already on it :)
[15:03] <fwereade_> (so it was a short conversation :))
[15:16] <niemeyer> Aram, fwereade_: Thanks!
[15:59]  * fwereade_ straightens up, bloody to the elbows
[15:59] <fwereade_> niemeyer, https://codereview.appspot.com/6355077 :)
[15:59] <niemeyer> fwereade_: Awesome!
[15:59] <niemeyer> fwereade_: I'll have a look right after lunch
[15:59] <fwereade_> niemeyer, cool, enjoy :)
[16:00] <niemeyer> fwereade_: Thanks!
[17:54] <niemeyer> fwereade_: The CL is not quite what I had in mind
[17:55] <niemeyer> fwereade_: Just thinking through about pros/cons now
[18:05] <niemeyer> fwereade_: https://gist.github.com/3061697
[18:05] <niemeyer> fwereade_: Do we need anything else?
[18:38] <niemeyer> Aram: ping
[18:39] <Aram> pong niemeyer.
[18:40] <niemeyer> Aram: Yo
[18:40] <Aram> hey.
[18:40] <niemeyer> Aram: How're you doing there.. are you working or relaxing?
[18:40] <niemeyer> Aram: I was going to invite you for a call, but I know it's late
[18:40] <niemeyer> Aram: So it can wait if that's the case
[18:41] <Aram> yeah, I'm working, I've had some errands to do today, but I'm compensating this evening/night.
[18:42] <niemeyer> Aram: Awesome, can we have a quick sync up call then?
[18:42] <Aram> yes, yes, skype?
[18:44] <niemeyer> Aram: G+?
[18:44] <Aram> ok
[18:44] <niemeyer> Aram: Inviting
[18:47] <niemeyer> Aram: https://codereview.appspot.com/6356060/diff2/2001:6002/mstate/service.go
[18:49] <niemeyer> Aram: unit.Life()
[18:50] <niemeyer> Aram: Remove only Life() == Dead
[18:50] <niemeyer> Aram: SetLife..
[18:51] <Aram> https://codereview.appspot.com/6356060/diff2/2001:6002/mstate/state.go?column_width=80