/srv/irclogs.ubuntu.com/2012/06/18/#juju-dev.txt

rogdavecheney, fwereade: hiya06:54
fwereaderog, heyhey06:54
TheMueMorning.07:15
davecheneymorning all07:29
TheMuedavecheney: Hi07:30
=== TheRealMue is now known as TheMue
twobottuxaujuju: How to SSH into local juju instance? <http://askubuntu.com/questions/152428/how-to-ssh-into-local-juju-instance>08:25
TheMueHmm, t-storm above our home.08:31
=== mcclurmc_ is now known as mcclurmc
Arammorning.10:07
TheMueAram: Hi10:46
voidspaceis this page still the "official" guide to writing charms?11:46
voidspacehttps://juju.ubuntu.com/docs/write-charm.html11:46
voidspaceif so, then maybe it should start by referencing a directory that actually *exists* in juju trunk11:49
voidspacehaving to check out juju trunk when you're using an installed juju is not the friendliest way of starting a tutorial as well11:50
voidspace"Assuming the current directory is the juju trunk"...11:50
voidspaceanyway, just some friendly feedback :-)11:51
rogniemeyer: yo!12:27
fwereadevoidspace, thanks for pointing that out :)12:29
fwereadeniemeyer, heyhey12:29
Aramhi niemeyer.12:30
voidspacefwereade: morning12:30
fwereadevoidspace, how's it going?12:30
voidspacefwereade: mainly good :-)12:31
fwereadevoidspace, mainly glad to hear it then :)12:31
voidspacefwereade: daughter has unexplained minor illness causing random temperature fluctuations12:31
fwereadevoidspace, aww :(12:31
niemeyerGooood morning all!12:31
voidspacefwereade: but she's happy and lively, so not *much* of a problem :-)12:31
voidspaceniemeyer: morning12:31
voidspacefwereade: and yourself?12:31
voidspaceour team is sprinting on getting us all up to scratch with juju this week...12:31
fwereadevoidspace, yeah, very good thanks12:31
fwereadevoidspace, ah, excellent12:32
voidspacefwereade: so expect more "observations" on your documentation :-)12:32
fwereadevoidspace, they're greatly appreciated12:32
voidspacehehe12:32
fwereadevoidspace, bug reports even more so ;)12:32
Aramniemeyer: I have some errands to attend to, I'm talking half a day off and will recuperate it later this evening/night.12:33
voidspacegetting juju up and running with lxc inside a vm was astonishingly easy though - so kudos on that (using precise)12:33
niemeyerAram: Sounds good, thanks for the note12:33
voidspacefwereade: want an issue for the charm writers guide?12:33
fwereadevoidspace, it's very cool, isn't it -- sadly I can't take much credit for that bit :)12:33
voidspacefwereade: I wasn't 100% certain I was on the current-latest-correctest documentation page anyway12:33
fwereadevoidspace, that would be fantastic12:33
voidspaceheh12:33
fwereadevoidspace, if it's what you find when you look for the docs then I think that's something we should address12:34
voidspacefwereade: yep12:34
fwereadeniemeyer, when you have a mo please let me know if I still appear to be on crack re relation types12:35
fwereadeniemeyer, I do think that RelatedService is applicable more widely than just in the unit agent12:36
niemeyerfwereade: Hmm12:37
niemeyerfwereade: Maybe.. that comment was made on a bad foundation. I still had in mind the old interface of AddRelation12:38
fwereadeniemeyer, yeah, I was a bit surprised when I looked back at the python code and discovered that nobody ever paid any attention to the result of AddRelation12:38
fwereadeniemeyer, add_relation_state, rather12:39
niemeyerfwereade: I still think eventually we'll need something that represents relations themselves, so we can more easily iterate. But that's a gut feeling rather than any kind of certainty, so I'm happy to see if we can tailor the model to something sensible for the use cases at hand12:40
fwereadeniemeyer, I can well believe that, but I don;t think we're there atm -- have you looked at the Relation type in python recently?12:40
fwereadeniemeyer, it has an internal_id property, and that's it :)12:41
niemeyerfwereade: Good point :)12:42
fwereadeniemeyer, there's something else on my mind actually12:44
fwereadeniemeyer, consistency of the history that unit agents see12:44
fwereadeniemeyer, it really rather bugs me that we have a mix of zk-current and hook-queue-current state available when we're running hook12:45
fwereadeniemeyer, and I think it exposes us to bug that we only don't hit through sheer luck, and coincidental properties of the rest of the implementation12:46
niemeyerfwereade: How so?12:46
fwereadeniemeyer, for example, what should we do when we ask ZK for the current relations in a -joined hook and it turns out that the relation we're supposed to be joining was just deleted?12:47
hazmatfwereade, previously to relation-ids it all worked as expected12:48
hazmatfwereade, the hook could use apis see a state current at time of execution, and delete hook exec would be pending12:49
niemeyerfwereade: It's an excellent question, and we have several such issues all around the code base12:49
fwereadehazmat, ok; but we can also do things like try to look up settings for a relation that doesn't exist any more, and that's only safe because we don't GC anything under /relations12:49
hazmatfwereade, that wasn't a happy accident that was by design12:50
hazmatfwereade, we don't gc things that could be in current use12:50
fwereadehazmat, understood; but it feels to me like it'll be kinda tricky to ever GC relations given the current usage12:50
niemeyerfwereade: There are two options.. either we cope with the fact that the relation is being removed and offer a sensible answer12:50
hazmatfwereade, its quite simple actually.. no presence nodes, not in topology, its dead12:51
niemeyerfwereade: or we tag the relation (or whatever object) as dead and allow the code to handle it in a timely way12:51
fwereadehazmat, until some misfunctioning unit agent comes back up..?12:51
hazmatfwereade, and it would come back up and see the rel doesn't exist12:52
hazmatie. it would check the topo12:52
fwereadeniemeyer, or alternatively, we snapshot settings just as we do membership, and have unit agents execute hooks against the histroy we snapshotted12:52
fwereadehazmat, ok, GC isn't as tricky as I worried :)12:52
hazmatfwereade, if its disconnected for a while and hasn't notified yet12:52
niemeyerfwereade: Not sure I understand what that would mean12:53
hazmatthen it will come back up and queue a broken hook in a separate context, and with queue reduction that wins12:53
fwereadeniemeyer, hazmat: I may be missing something, but it seems to me that the unit agent gets notified of every relevant change to state, and can therefore keep a consistent local history through which it can run at its own pace (which isn't necessarily as slow as it might be, thanks to hook reduction)12:55
niemeyerfwereade: It can't.. assume the unit is down when a change happens12:55
fwereadeniemeyer, it can; it has to know how to diff current state against its known latest state anyway12:56
niemeyerfwereade: Well, yes, and that goes against "every relevant change to state on consistent local history", right?12:56
fwereadeniemeyer, I don;t see the tension there -- we always knew we might miss some changes, and we have queue reduction anyway... what's the difference?12:57
hazmatfwereade, terminology, its not seeing every change, it seeing deltas12:58
hazmatits12:58
niemeyerfwereade: I'm just pointing out that "it's fine to miss some changes" and "every relevant change to state on consistent local history" are not friends.12:58
fwereadehazmat, yeah, exactly12:58
fwereadeniemeyer, I'm saying that within the constraints we're used to, we can run every hook against the state we knew to exist at the time we detected the need for a hook to run (collapsed as necessary), rather than running against a mixed state12:59
fwereadeniemeyer, and I was wondering if there was an obvious downside to that strategy13:00
niemeyerfwereade: We can't snapshot the whole state at once13:01
niemeyerfwereade: Which means that by the time you discovered you had to run "joined", the state has already moved forward13:02
niemeyerfwereade: So there doesn't seem to be much of a point to me to be getting a state that is arbitrary in a time before it is needed13:02
niemeyerfwereade: But maybe I'm misunderstanding what you mean13:02
fwereadeniemeyer, we're already snapshotting membership, and using that; we're snapshotting settings versions, and using those to figure out when to collapse; we could do the same with the actual settings, n'est-ce pas?13:03
hazmatits not really snapshotting13:03
hazmatits tracking13:03
fwereadeniemeyer, when you do a relation-list, you're explicitly not getting the current related units; you're getting the units at the time the change was detected13:03
hazmatits still broken though13:04
hazmater. not a snapshot13:05
fwereadehazmat, go on13:05
hazmatbut conversely if you do a relation-get you do see a current value13:05
hazmatthat's cached for the hook exec13:05
niemeyerfwereade: There's no way to get the data for multiple nodes at the same time.. it's a cache, rather than a consistent snapshot13:05
niemeyerfwereade: relation-list might work better in the case of relation-joined, specifically, but it won't work well in the case of relation-changed, for example13:05
fwereadehazmat, thatis rather my problem, that I'd be a lot more comfortable if we were grabbing the settings at the time they changed and using them13:06
fwereadehazmat, I don;t think we'd ever be too far out of date, because of queue reduction13:06
hazmatfwereade, agreed, these semantics are hard, without evolving a local state copy you can't be consistent throughout13:06
niemeyerfwereade: Because you detecting the change and listing the relations are two operations13:06
niemeyerfwereade: Done at different times13:06
niemeyerfwereade: Yes, not too far out of date, but that's not the point.. if it is out of date, what are we trying to solve then?13:06
hazmatfwereade, and even then its not clear that its truly consistent even then13:07
fwereadeniemeyer, (we're always out of date a little)13:07
niemeyerfwereade: Exactly13:07
fwereadehazmat, this is to me the most interesting bit... how do you see us being inconsistent with local state?13:07
niemeyerfwereade: So doing a snapshot, say, 2 minutes ago so we can run a hook doesn't sound like solving a problem13:07
niemeyerfwereade: Reduction is evidence that we actually don't care about the intermediate state13:08
hazmatfwereade, well the question then is what is meant by consistent? that all values ever show to a hook are true as of the time of its related change event mvcc style?13:08
niemeyerfwereade: We just try to bring the unit aware of the latest state13:08
fwereadeniemeyer, then why do we bother doing what we do with relation-list in the first place?13:08
* hazmat needs some coffee to correct typos13:09
fwereadeniemeyer, I think I'd be comfortable with either "you always get current state" or "you always get consistent state"13:09
fwereadeniemeyer, but it feels liek we're mixing the two and it makes my head hurt a little13:09
rogfwereade: +113:10
niemeyerfwereade: Current is impossible, as we both know..13:11
fwereadeniemeyer, and "current" has the problem that we could then be running relation-joined against some remote unit which relation-list tells us doesn't exist13:11
rogi wonder if we wouldn't be better having simple "something has changed"-style notifications13:11
fwereadeniemeyer, "latest known" then13:11
fwereadeniemeyer, but regardless, I agree that whatever you call it, it has problems13:11
niemeyerfwereade: Let's talk about relation-changed.. what do you suggest we do regarding relation-lsit?13:12
hazmatfwereade, so re not clear, there's also cross context manipulation now, you have to have a linear view across relations13:12
hazmatie. relation-set from rel-a-hook to rel-b-hook13:13
fwereadeniemeyer, AIUI what we currently do is keep track of which units have joined/departed according to local state, and always give that when asked to relation-list13:13
hazmater.. rel-b13:13
fwereadehazmat, can you expand a little? I don't *think* that hurts us... but I'm probably missing something13:13
fwereadehazmat, a unit agent only sets its own settings, right? and that's in response to hooks running relation-set... and so that's automatically synchronised, isn't it?13:15
niemeyerfwereade: We could snapshot the state of the relation the specific hook is part of before we start the hook, if that's not done today13:15
niemeyerfwereade: Is that what you mean?13:15
fwereadehazmat, a unit's own settings will always reflect whatever it's decided to set given the hook that have so far been handled13:15
niemeyerfwereade: or rather, what you are suggesting?13:15
fwereadeniemeyer, yes, I'm just suggesting that when we detect a settings change we store the settings as part of the history rather than just the fact of a change13:16
fwereadeniemeyer, and that that is strictly more consistent than what we have now, and makes my head hurt less :)13:16
fwereadeniemeyer, (and hopefully will make life less confusing for people when they're debugging tricky relations)13:17
niemeyerfwereade: How does that improve things?13:18
niemeyerfwereade: As we just discussed, when we detect that settings have changed, and go to get that, it's already out-of-date13:19
fwereadeniemeyer, if we can divorce hook execution environments from zookeeper state (apart from the unit writing its own relation settings) we can eliminate having to think about an entire class of whoops-zk-changed-in-a-confusing-way situations13:19
niemeyerfwereade: Why is that out-of-date state any better than the out-of-date state we get when we actually run the hook?13:19
hazmatfwereade, right now the state tracking is mostly in independent relation contexts, it works cross relation through benefit of the db giving us a linear time view (albeit with per rel queue reduction), the point i was trying to raise is that we have cross relation activity now from hooks. i don't think its insurmountable if the linear view across relations is maintained, but it is something to keep in mind. ie any rel-a hook could change settings on a rel-b13:19
hazmat thing.13:19
rogniemeyer: FYI continuing weird behaviour with bzr (i've been stuck on it all morning). http://paste.ubuntu.com/1047256/  time to lose the branch, i think. if bzr is this broken, lbox has no hope.13:19
fwereadehazmat, ...whoa, ok, I missed that13:20
fwereadehazmat, how is that OK?13:20
hazmatfwereade, its not without some careful thought ;-) but generally it can work because we have a linear view of events changes across relations that the cache is kept up to date for, but it does require thought to the cache maintenance wrt to queue reduction13:21
fwereadehazmat, we're talking about a foo-relation hook on unit X relation A changeing settings on... unit X relation B?13:21
niemeyerfwereade: How is it not ok?13:21
hazmatfwereade, yes13:21
fwereadeniemeyer, hazmat: it's not *necessarily* not ok, but it's a surprising extra channel13:22
niemeyerrog: Sorry, I can't really help since I can't reproduce the issue locally13:22
niemeyerfwereade: I find it pretty straightforward13:22
rogniemeyer: yeah, i have no idea. just thought you might be interested to see the bizarreness.13:22
hazmatrog, naked bzr works pretty well.. i kept running into issues with cobzr and gave it up13:24
fwereadeniemeyer, ok, as long as it's all on the same unit, that's fine13:24
niemeyerhazmat: FWIW, I use it for every single bzr branch13:24
niemeyerfwereade: It is, the property "relation-set only changes myself" is sustained13:25
roghazmat: i've never had a problem before. i think i mucked things up when i accidentally did a bzr commit as root.13:25
hazmatrog, interesting.. easy to fix with a chown.13:25
fwereadeniemeyer, cool, I misunderstood on first reading, thought we were talking about something altogether more disturbing13:25
roghazmat: that was the first thing i did13:25
niemeyerfwereade: So, still trying to understand what you mean13:25
niemeyerfwereade: Just so you get the background..13:26
niemeyerfwereade: The idea of caching comes from giving people consistent answers across calls that read data from a remote unit, to make things a little more saner13:26
niemeyerfwereade: E.g. (relation-get username + relation-get password) will get data for the same person13:26
rogwould someone be able to explain to me why what thing changes which relation settings is important here?13:27
hazmatniemeyer, also applies to the local unit reads via the writeback cache13:27
niemeyerhazmat: Rihgt13:27
niemeyerfwereade: So, you can see our model as "latest known state, snapshotted on first query"13:28
fwereadeniemeyer, per queried unit, yeah13:28
fwereadeniemeyer, and apart from the actual list of units, which is from longer ago13:29
fwereadeniemeyer, none of these things *seriously* bother me13:29
rogi.e. why is cross-relation activity a difficulty?13:29
niemeyerrog: It's not.. was a red herring13:29
rogniemeyer: ok, thanks.13:30
fwereadeniemeyer, but I'm equally not sure wat benefit we derive from having two different "now" states in play at a time13:30
niemeyerfwereade: We have N "now" states.. we have data from a distributed system, where each detail is arbitrarily old and invalid13:31
hazmatniemeyer, it can be13:31
hazmatniemeyer, with an attempt to have a consistent cache.. at least in the dictates of the py impl13:31
fwereadeniemeyer, ok, but we have ordering guarantees from ZK, right?13:31
niemeyerfwereade: zk has ordering guarantees.. I don't know what you mean, though13:32
hazmatniemeyer, each rel has a separate queue subject to reduction rules, if a hook corresponding to event 3 in rel B executes at a time before a hook corresponding to event 2 in rel A, and they cross communicate it is an issue.13:32
rogfwereade: i'm with you, but i think for a slightly different reason. we *do* have potential consistency problems, but i think they should be solved as close to source as possible. so watchers should detect inconsistency if possible and act appropriately. by the time we get to the actual agent, all the information should be available in processed form.13:33
niemeyerhazmat: I don't know what you mean by "cross communicate".. hooks don't communicate13:33
fwereadeniemeyer, I'm just not 100% convinced that it's never going to break anything if we get settings newer than the relation list13:33
hazmatniemeyer, cross communicate -> i mean hook in rel B modifies rel A setting13:33
niemeyerhazmat: I don't see any issue there13:33
* fwereade cig/assimilate break, 3 mins13:34
niemeyerhazmat: Yeah, don't see any issue there13:34
niemeyerfwereade: Cool, let's talk when you're back13:35
niemeyerfwereade: FWIW, I find your concern great.. it's nice to have that kind of problem in mind13:35
niemeyerfwereade: Let's figure the way we *want* relation-list and hooks to interact13:36
hazmatniemeyer, its only problematic for attempting to maintain a consistent view for each hook, because hook B modified settings in a separate rel using a different consistent view then the present time of the other rel. the linear view of time is subject to some jumps because of how we reduce the queue, it is consistent but only to a rel context, cross rel communication, requires a linear view that is scoped at a higher level to achieve consistency13:36
rogniemeyer: trying to get my head clear around this. this is only a problem because we're not getting all the info from a watcher, right? so the action that an agent is taking depends not only on the data received from the watch, but also some data that it reads from zk later?13:37
niemeyerhazmat: Sorry, I still don't see the problem.13:37
hazmatagain it depends on what you looking for consistency, fwereade was looking for something akin to mvcc (ie. snapshot isolation)13:37
fwereadeniemeyer, heh, I think what I just thought is what hazmat just said13:37
niemeyerhazmat: "B modified settings in a separate relation"..13:37
niemeyerhazmat: That's sequential13:37
niemeyerhazmat: Hooks aren't executing in parallel13:38
rogi don't think we can guarantee consistency across relations.13:38
hazmatniemeyer, but they are subject to time skips due to reduction13:38
niemeyerhazmat: Not time skips, no13:38
niemeyerhazmat: They are subject to ignoring events and acting on the latest known state, yes13:38
hazmatniemeyer, right their linear advancing, but yes the clock does skip event ticks13:38
niemeyerhazmat: I don't think that changes anything with regards to relations in different contexts, though13:39
hazmatit works now because we feed all of them (hook exec queues)  into a linear scheduler13:39
hazmatyeah.. it might be a red herring13:39
niemeyerhazmat: A hook executing for relation A, B, C, or D, and doing changes for relation A, B, C or D, has the system as consistent as if the hook was doing changes on a single relation13:40
rogniemeyer: i don't think it does13:41
fwereadeniemeyer, when relation B changes relation A's settings, it could plausibly affect how relation A acts... right?13:41
rogniemeyer: because the settings for each relation are in a different zk node13:41
niemeyerfwereade: Yes, hopefully :)13:42
rogniemeyer: and we can reorder zk watch firing across different nodes13:42
fwereadeniemeyer, and if relation A doesn't have access to the same view of history that B used to make that change to A, I think we could end up in confusing states13:42
fwereadeniemeyer, maybe it all shakes out, but I haven't convinced myself of that yet13:42
hazmati'd need to white board to work it out, i haven't worked through it with the new cross rel communication work in, its something that needs thought though.13:42
niemeyerrog: DOesn't matter in that case we're discussing. We don't order those events.13:43
hazmats/thought/verification13:43
niemeyerfwereade: I don't see how that's an issue13:43
niemeyerQuick break, biab13:43
hazmatrog, how's the upgrade work coming?13:45
roghazmat: i finished that upgrader thingy. but it's judged premature for the time being, so i've put it on ice. currently working on parallel stuff towards the machine agent.13:46
fwereadeniemeyer, ok, let's say B has set some setting per related unit on A, based on "current" state at the time a hook ran for B; and A then runs a hook, based on a new and incompatible "current" state for A; this feels liable to lead to upset and confusion13:47
hazmatrog, cool.. i got inspired to work on it as well13:47
fwereadeniemeyer, whereas if B and A are both working with the same history, the "current" states don't matter -- both B and A will agree on (say) what units A is currently related to13:47
hazmatrog, although its turning out to be a lot more work than i had hoped.13:48
roghazmat: yeah, i found that. but it wasn't too bad. if you want to copy the protocol, the code is here https://codereview.appspot.com/630706113:49
roghazmat: i had a plan to automatically generate test permutations, but didn't get quite that far.13:50
hazmatrog, i eschewed the separate process for minor upgrades13:51
roghazmat: ah, cool.13:51
roghazmat: where are you finding the main difficulties?13:51
hazmatrog, i want to get to major upgrades though, which is where things get interesting.. else i'll never be able to merge any of the scaling work (json switch)13:51
niemeyerfwereade: That's a good direction for us to explore.. it'll be easier to get a point across with examples indeed13:52
niemeyerfwereade: I don't understand yours, though13:52
niemeyerfwereade: Let me try to translate13:52
hazmatrog, no part in particular is difficult.. i ended up going with some new abstractions (state protocols), its just a lot of pieces.13:52
niemeyerfwereade: We have two units, A and B, is that what you mean?13:52
fwereadeniemeyer, two relations within the same unit13:52
niemeyerfwereade: Okay, so let's call two relations R1 and R213:53
niemeyerfwereade: and two units A and B13:53
niemeyerfwereade: Are R1 and R2 both between A and B?13:54
fwereadeniemeyer, let's say yes13:54
niemeyerfwereade: Okay13:54
fwereadeniemeyer, well, heh, R1 and R2 are each between the respective services of A and B13:55
niemeyerfwereade: So you mean that we have a hook R1-relation-changed executing within A?13:55
fwereadeniemeyer, yes; and R1-relation-changed sets something on A.R2's settings13:55
niemeyerfwereade: Okay, I'm with you13:55
* fwereade thinks a mo, maybe it doesn't matter... just a sec13:57
fwereadeniemeyer, ok, thinking aloud... R1 sets a key in A.R2 per unit related to A, which is currently [B]13:59
niemeyerfwereade: Okay13:59
fwereadeniemeyer, B departs, and B' joins14:00
niemeyerfwereade: C joins, please :)14:01
niemeyerfwereade: Or you mean B joins again?14:01
fwereadeniemeyer, ok, C joins14:01
fwereadeniemeyer, now, I meant another unit of the service that B was a unit of14:01
niemeyerfwereade: Okay, let's call it C since the service relation doesn't really matter in this case.. it's a different unit in the relation14:02
fwereadeniemeyer, yep, ok14:02
fwereadeniemeyer, so, given the delays etc in play, we could well have a situation in which A.R1 still thinks it's related to B, but A.R2 thinks it is now related to C14:03
niemeyerfwereade: Oops, hold on14:03
fwereadeniemeyer, A.R2 thinks A.R1 is now related to C14:03
niemeyerA.R1 doesn't think anything.. this is a settings node14:03
niemeyerfwereade: Neither does A.R214:04
fwereadeniemeyer, yes: A.R1 is a node distinct from A.R2 though14:04
niemeyerfwereade: Yes, and neither of them "think" anything.. they are state14:04
fwereadeniemeyer, s/thinks/has written state predicated on the assumption that/14:05
niemeyerfwereade: Yes, and that's not a problem..14:05
niemeyerfwereade: R1-relation-joined will be called for C14:05
niemeyerfwereade: and A will have a change to do whatever it pleases with it14:06
niemeyerfwereade: If the person maintaining the charm for A is doing crazy stuff that makes no sense, though, we can't avoid it14:06
fwereadeniemeyer, I think I agree that we will eventually reach a steady state in which everything makes sense14:07
niemeyerfwereade: Yep, that was the main thinking14:07
fwereadeniemeyer, but it seems wrong to let C see A.R1's settings in a state wildly divergent from A.R2's settings14:08
fwereadeniemeyer, the eventual consistency may indeed trump all though14:09
niemeyerfwereade: You've lost me now14:11
niemeyerA.R1 and A.R2 were both set solely by A..14:11
niemeyerfwereade: There's no way for them to be "divergent"14:11
fwereadeniemeyer, the "wildly divergent" is hyperbolic, but is meant to indicate that A.R1 could respond to 30 events before A.R2 responds to any14:12
fwereadeniemeyer, unless we're thinking a little about the cross-relation stuff alluded to above14:12
fwereadeniemeyer, I think that would take a pathological scheduling situation and it might be impossible but I can't comfortable state that I'm certain it is impossibvle14:13
niemeyerfwereade: We can improve the scheduling algorithm over time to make events across relations "fair", in case they don't naturally get fair14:14
niemeyerfwereade: We've lost the use of practical examples, though14:14
fwereadeniemeyer, well observed14:14
fwereadeniemeyer, I might have to try to turn this into an email14:14
niemeyerfwereade: R1-relation-changed can *really* have 30 events happening before R2-relation-changed happens14:14
rogfwereade, niemeyer: is it this kind of scenario we're potentially concerned about? http://paste.ubuntu.com/1047364/14:16
niemeyerrog: I'm not aware of any scenario we're concerned about, after the above conversation14:17
fwereaderog, I don't follow that I'm afraid14:17
niemeyerrog: The password case I mentioned works today14:17
rogniemeyer: yes, but it  might not work if the username and password were stored in different relations, right?14:18
niemeyerrog: That's an artificial example that we're not concerned about14:18
rogniemeyer: ok. i was trying to understand fwereade's concerns, sorry.14:18
niemeyerrog: No worries, I'm just explaining what I've been discussing with fwereade14:19
rogniemeyer: i was trying to come up with a concrete example of14:19
rog[15:08:36] <fwereade> niemeyer, but it seems wrong to let C see A.R1's settings in a state wildly divergent from A.R2's settings14:19
rogniemeyer: of course, it *is* an artificial example14:20
niemeyerrog: See my comments that follow that :-)14:20
rogniemeyer: and i'm happy for us to say that settings are only consistent within a relation.14:20
niemeyerrog: Cool, that's a given today, and I agree it doesn't feel useful to go over the trouble14:21
niemeyerfwereade: Okay, can we go back to that branch we were talking about when the conversation diverged?14:22
rogniemeyer: i do think that it might make sense to make the agents use info read by the watchers though, rather than going into the zk state again. it would mean the watchers can detect inconsistencies early on and produce a consistent-looking stream of events which will lead to determinstic actions.14:23
niemeyerrog: The agents use info read by the watchers today.14:23
rogniemeyer: if they do, that's no problem. i seem to remember that wasn't the case though.14:24
niemeyerrog: They do. Of course, there are a lot of details about this, but those details should be taken into account when saying "we should do foo".14:25
niemeyerrog: The whole conversation above was exploring those details14:25
rogniemeyer: looking at this before, it seemed to me that more stuff needed to be cached in the state types for this to be true. but perhaps things have changed, or the agents don't need as much info as i thought.14:27
niemeyerrog: Sorry, but I really don't know what you're suggesting.14:27
rogniemeyer: one example: when the machine agent is watching units for a machine, it sees the topology change and sends a *Unit down a channel. by the time the agent comes to ask the unit for its CharmURL, the unit might be gone.14:33
rogniemeyer: on a completely different subject: how do you feel about the possibility of using build tags for conditional tests instead of flags? (i'm thinking of -amazon here, to start with)14:35
niemeyerrog: I've seen the thread.. sounds fine, but we shouldn't be worrying about this right now14:35
rogniemeyer: i'm just about to add another flag, and it seems a bit wrong. and it's awkward to test everything with the flags.14:36
rogniemeyer: it would be quite and easy to change14:36
rogs/quite/quick/14:36
niemeyerrog: What flag are you adding?14:36
rogniemeyer: -root14:36
niemeyerrog: Hmm.. why do we need it?14:36
rogniemeyer: because the only way of testing the container package with any usefulness is to run the tests as root14:37
rogAFAICS14:37
niemeyerrog: I can't see why that would be the case right now14:37
niemeyerrog: We're not adding support for LXC today14:37
rogniemeyer: not possible to add upstart scripts without being root14:38
rogniemeyer: i could just leave out testing entirely14:38
niemeyerrog: You can add upstart scripts to a path that you define14:38
rogniemeyer: putting yet another shim second-guessing what commands the upstart package will be invoking seems wrong14:38
rogniemeyer: really? running upstart myself, then?14:39
rogniemeyer: i hadn't tried that.14:39
niemeyerrog: Yes, that actually works14:39
niemeyerrog: Although I'd probably just verify that the script was put in place14:39
niemeyerrog: Well, depending on what else is being tested in that path14:40
rogniemeyer: i quite like having a test that really verify that it actually works with upstart for real.14:40
niemeyerrog: Either way, definitely not require root for tests14:40
rogniemeyer: indeed.14:40
rogniemeyer: hence the flag.14:40
niemeyerrog: Those will be run close to never14:40
rogniemeyer: same as the amazon tests :-)14:40
niemeyerrog: Not really.. I run those fairly frequently14:41
niemeyerrog: I don't run *any* test suite as root, though14:41
rogniemeyer: really? when was the last time you did? last few times they've failed for me.14:41
niemeyerrog: We may need that for LXC, unfortunately14:41
niemeyerrog: For EC2/S3, every single time I change the tests14:41
rogniemeyer: that's why i thought it was reasonable to do it now.14:41
niemeyerrog: We're not implementing LXC now14:42
niemeyerrog: Are you working on LXC?14:42
rogniemeyer: nope14:42
niemeyerrog: So I'm lost14:42
niemeyerrog: Only need for LXC => That's why I'm doing it now => Doing LXC? => No => Vhat geev?14:43
rogniemeyer: i thought that since the container package was going to need to have root tests eventually, and that the current tests are more effective running as root, that it would be reasonable to have root tests there now.14:43
niemeyerrog: Testing as root is bad practice, and you know that14:44
rogniemeyer: i agree. but how do you suggest i provide a meaningful test of this code: https://codereview.appspot.com/6312044/diff/1/container/container.go14:45
rog?14:45
rogniemeyer: second-guessing what the upstart package is going to do seems wrong to me14:45
niemeyerrog: Please have a look at how fwereade tested the upstart package14:45
rog[15:45:50] <rog> niemeyer: second-guessing what the upstart package is going to do seems wrong to me14:46
rogi can't test this without knowing exactly what commands upstart is going to call, where it's storing the files, what they look like, etc14:46
niemeyerrog: Sorry, but I don't know what that means.. I'm suggesting having a look at the technique used by the upstart package to test things14:46
niemeyerrog: The actions from these package look trivial14:46
rogniemeyer: they are14:47
niemeyerrog: I hope we can find a trivial way to test them14:47
rogniemeyer: i haven't succeeded yet!14:47
niemeyerrog: that doesn't involve running them as root14:47
rogniemeyer: suggestions very welcome.14:48
rogniemeyer: i've looked at the upstart tests BTW14:48
rogniemeyer: anyway, gotta go to the dentist. back in a bit.14:49
niemeyerrog: Isn't this merely writing a file on disk right now?14:49
niemeyerrog: I hope we don't need root to test that! :-/14:49
niemeyerfwereade: ping14:50
fwereadeniemeyer, pong14:50
rogniemeyer: yes. but to verify that file, i've got to know what file is written and what it looks like. given that the upstart package itself doesn't have a single test that actually verifies that it really works with upstart, we should do that *somewhere* i think.14:50
niemeyer<niemeyer> fwereade: Okay, can we go back to that branch we were talking about when the conversation diverged?14:50
niemeyerrog: Okay.. if you can't figure how to test that file, please move on to something else and I'll figure it.14:51
niemeyerrog: It's a trivial text file14:51
fwereadeniemeyer, probably, if you tell me where you consider it to have diverged...14:51
niemeyerrog: That somewhere is the upstart package, by the way..14:51
niemeyerfwereade: I just mean following up the conversation14:52
niemeyerfwereade: We were talking about the CL and then moved on to something else.. I'd just like to see what we do with it14:53
fwereadeniemeyer, ah, cool, the RelatedService one14:53
niemeyerfwereade: Yeah14:53
fwereadeniemeyer, well... not sure where to go really: have I allayed your fears somewhat?14:54
niemeyerfwereade: Yeah, I'm happy with the overall concept14:54
niemeyerfwereade: I'm not entirely happy with the type and method itself, though14:54
fwereadeniemeyer, ah, ok, go on14:54
niemeyerfwereade: The data in the RelatedService method feels very weird to me14:54
niemeyerfwereade: It alludes a bit to that conversation we had the other day14:55
niemeyerfwereade: About how we store data14:55
niemeyerfwereade: I'm looking at https://codereview.appspot.com/6307099/diff/1/state/service.go14:56
fwereadeniemeyer, I'm more than happy to stick "relation" on the front of everything14:56
niemeyerfwereade: Line 23914:56
niemeyerfwereade: Not about naming.. about the actual data14:56
fwereadeniemeyer, ah, ok, the RelatedRole?14:56
fwereadeniemeyer, or the totality of bits of data that make up RelatedService?14:57
niemeyerfwereade: If s is service A, with a requirer relation R1 named "cache".. this is storing {A, R1, provider(!)}14:58
niemeyerfwereade: If s is service A, with a requirer relation R1 named "cache".. this is storing {A, R1, "cache", provider(!)}14:58
niemeyer(added the name)14:58
fwereadeniemeyer, whoa, I would appear to be totally on crack there14:59
niemeyerfwereade: This RelatedService is *not* the remote service.. this is the *local* idea of a relation for service s.. look at the service key in the data.14:59
fwereadeniemeyer, I switched that back and forth several times, must have desynchronised myself14:59
niemeyerfwereade: The previous doc for the type, and the data stored in the relation, was apparently right14:59
fwereadeniemeyer, my intent there was to store the *other* service, and its role15:00
niemeyerfwereade: Yeah, I'm not sure it's right, though15:00
fwereadeniemeyer, well, the relationKey and scope are the same on either side15:01
niemeyerfwereade: The relation key and scope are.. the relation role and relation name are not15:01
niemeyerfwereade: We're losing those15:01
fwereadeniemeyer, the relation name should IMO come from the local side, and the role and service key from the remote side15:02
niemeyerfwereade: Exactly.. that sounds a bit messy to be honest15:02
fwereadeniemeyer, but I'm pretty sure that that is the actual data we need15:03
fwereadeniemeyer, it's everything about the remote service, plus the local name for that service15:03
fwereadeniemeyer, ok not for the service15:03
niemeyerfwereade: ;-)15:04
fwereadeniemeyer, for the relation through which we are connected to that service15:04
fwereadeniemeyer, hell, just "for the relation"15:04
niemeyerfwereade: You're getting into the confusion that I'd like to avoid :-)15:04
niemeyerfwereade: At the moment s.Relations() returns the participation for s in all its relations15:05
niemeyerfwereade: {s.key, relation key, relation name, relation role}15:06
niemeyerfwereade: All of that data is for *s*15:06
fwereadeniemeyer, yes, that is true; and it looks nice and simple there, and then we have to collect all the remote data later15:07
fwereadeniemeyer, which is not so nice and simple, and happens more than once15:07
niemeyerfwereade: Yep, we can add another call which is also nice and simple that returns the other services participating in the same relation15:08
niemeyerfwereade: and in fact we should cache that data so we don't have to query it again15:08
fwereadeniemeyer, what would you call that other method?15:08
niemeyerfwereade: Relation.Services?15:09
niemeyerfwereade: Alternatively,15:10
fwereadeniemeyer, ah, so you're suggesting a top-level Relation type?15:10
fwereadeniemeyer, it really feels like just one more step to go through15:10
niemeyerfwereade: I'm trying to imagine how to solve it rather15:11
niemeyerfwereade: Another suggestion:15:11
niemeyerfunc (s *Service) Relations() ([][]*ServiceRelation, err error)15:11
niemeyerfwereade: One relation per entry15:12
fwereadeniemeyer, ok, and then we still have to go through the leaves discarding or not-discarding the various Servicerelations that refer to the original service15:12
niemeyerfwereade: First ServiceRelation in the relation is guaranteed to be s15:12
fwereadeniemeyer, picking what to do based on the length of the []ServiceRelation is kinda nasty though15:13
fwereadeniemeyer, IMO the advantage of RelatedService is it's something that all the clients I'm aware of can treat the same regardless of role or scope15:14
niemeyerfwereade: Doesn't have to be based on the length.. l[0].RelationRole()15:14
niemeyerfwereade: The disadvantage is that it's mixing up roles and services in a way not seen anywhere else15:14
niemeyerfwereade: We AddRelation() a list of endpoints.. we add-relation a list of relations with service:rel on the same side.. etc15:15
niemeyerfwereade: We store them in the topology in the same way..15:16
fwereadeniemeyer, it doesn't seem to me to be enormously controversial to suggest that user-facing representations of data do not necessarily map perfectly to internal representations of same15:17
niemeyerfwereade: The internal representation is *also* the same..15:17
niemeyerfwereade: topology stores data exactly like that15:17
niemeyerfwereade: This is an edge case not seen anywhere else15:17
fwereadeniemeyer, ...and in different contexts internally, the same data sometimes wants to be stored in different ways15:17
niemeyerfwereade: and one of the reasons why it is an edge case is that it's being customized for a representation that so far we don't enforece15:18
niemeyerfwereade: enforce15:18
niemeyerfwereade: Relations can have three services today, if we choose to15:18
niemeyerfwereade: and as we debated today, this isn't so far fetched (e.g. peer relations)15:18
niemeyerfwereade: I'm not suggesting we start implementing that now, but it sounds silly to start designing things in a way that is unlike everything else and make that impossible15:19
niemeyerfwereade: (when we can trivially not)15:20
fwereadeniemeyer, it strikes me as a lot of speculative generality... AFAICT multi-peer relations should remain easy whatever I do here, and pro/req remain brain-bendingly hard15:21
fwereadeniemeyer, I feel that you're less happy with the general concept than perhaps you thought... either the RelatedService concept is sane, in which case by its nature it ends up combining useful bits of data from potentially more than one service... or it's not, and we have amore fundamental disagreement in play :)15:24
niemeyerfwereade: I would agree on the speculative generality if we were not in a situation where everything else works the same way.15:24
niemeyerfwereade: and if we didn't have an option at hand that was trivial to implement.15:25
niemeyerfwereade: What you're suggesting is a departure from what we have now,15:25
niemeyerfwereade: And you just mixed up both sides while *suggesting it* above15:25
niemeyerfwereade: I'd really appreciate if we could find a model that was not like that15:26
niemeyerfwereade: Doesn't have to be my suggestion, though. You know the constraints and concerns we have. Anything else that solves these issues is also fine.15:26
fwereadeniemeyer, I mixed it up in the aftermath of a long conversation, involving many of us, which would seem to imply that the whole subject is not quite as simple as it might at first appear15:26
niemeyerfwereade: In my humble opinion, you've mixed up in the precise place I'm concerned about, because it is confusing.15:27
niemeyerfwereade: Having {service key, relation key, relation name} where relation name is not for {service key, relation key} is *extremely* confusing and unnecessary.15:28
fwereadeniemeyer, ok.... I'll think some more15:29
fwereadeniemeyer, I'm just very reluctant to remake the mistakes we made in the python version and then duplicated in the go version15:30
fwereadeniemeyer, (it's just a doc issue... the docs in both places claim a perspective that is not accurate)15:31
fwereadeniemeyer, maybe fixing the types to match the docs is not the right way though15:31
* fwereade cig, think15:31
niemeyerfwereade: I've been explaining why it's not just a doc issue.. we have a model used across the board15:32
niemeyerfwereade: and this is not it15:32
niemeyerfwereade: I'm not suggesting we follow blindly what we do with Python, though15:32
niemeyerfwereade: You've been making changes to the relation stuff that have been accepted15:32
fwereadeniemeyer, that wasn't what I was trying to imply, sorry15:36
fwereadeniemeyer, how would you feel about something with the same core idea, but hopefully a little more explicit and less confusing: {remoteServiceKey string, relationKey string, localEndpoint RelationEndpoint}?15:37
fwereadeniemeyer, combining "what we're connected to" and "how we're connected to it" without leading to the confusion you rightly disapprove of15:38
fwereadeniemeyer, (I would still say that having all the existing types documented to embody a perspective that they actually don;t *is* a doc issue)15:39
niemeyerfwereade: Where are we doing this today?15:41
fwereadeniemeyer, // ServiceRelation represents an established relation from15:42
fwereade/ the viewpoint of a participant service.15:42
niemeyerfwereade: As far as I understand, that is true with the current implementation15:43
niemeyerfwereade: It's not great, though, I agree15:43
fwereadeniemeyer, ha, yes, I see that... :(15:44
niemeyerfwereade: What about [][]RelationEndpoint?15:45
niemeyerfwereade: We wouldn't even need the RelatedService/ServiceRelation red herring15:45
niemeyerfwereade: This is pushing in the direction you were already doing too, with AddRelation(endpoints...) and RemoveRelation(endpoints...)15:46
fwereadeniemeyer, hmm, there's still a certain amount of tomfoolery necessary to extract the data we care about in both the unit agent and in status15:46
niemeyer(no docs!)15:46
niemeyerfwereade: I don't see how it's any worse than the RelatedService interface, to be honest15:47
niemeyerfwereade: rels := s.Relations(); for i, endpoints := rels { ... }15:47
niemeyerfwereade: rels := s.Relations(); for i, endpoints := range rels { ... }15:47
niemeyerfwereade: That's really it15:47
niemeyerfwereade: With the additional guarantee that endpoints[0] is always for s15:47
niemeyerfwereade: and len(endpoints) > 015:48
fwereadeniemeyer, plus fooling around to determine which endpoint we care about, which the s[0] thing doesn't address15:48
niemeyerfwereade: This sounds really easy to deal with15:48
niemeyerfwereade: That went over my head15:48
fwereadeI guess s[len(s)-1] is not too hard15:48
niemeyerfwereade: INdeed, and I bet that we'll need to special case the peer case anyway15:50
fwereadeniemeyer, the point of this is to avoid special-casing peers15:50
niemeyerfwereade: Yeah, I understand, I'm saying that I suspect we'll need to be careful about it anyway15:51
niemeyerfwereade: Peer relations are established by hand, etc15:51
niemeyerfwereade: Erm, manually by juju15:51
fwereadeniemeyer, yeah, that is also something that bugs me15:51
fwereadeniemeyer, but not all that much :)15:51
niemeyerfwereade: I quite like the above interface, actually.. it seems quite appropriate that we can, for example, iterate over the results of s.Relations() and use the result to call state.RemoveRelation(endpoints...) directly15:52
fwereadeniemeyer, yeah, I don't have a strong negative reaction to that one15:53
fwereadeniemeyer, I'll see where I can take it15:53
niemeyerfwereade: I also love the fact we don't have to document ServiceRelation :-)15:53
fwereadeniemeyer, ha, yeah :)15:53
fwereadeniemeyer, offhand it seems this *does* imply a Relation type... {key string endpoints []RelationEndpoint}15:55
niemeyerfwereade: Indeed.. but is it any better than [][]RelationEndpoint?15:55
niemeyerfwereade: For that specific use case?15:55
niemeyerfwereade: I see this as []Relation15:56
niemeyerfwereade: We just happened to have leaning towards representing Relation as []RelationEndpoint, apparently15:56
fwereadeniemeyer, ...hmm, I guess I can keep the relation key out of it for a while15:56
niemeyerhave been15:56
fwereadeniemeyer, we can grab it from the topology when we need it15:57
niemeyerfwereade: I'm not suggesting that's a bad idea, by the way.. sounds like a perfectly good type15:57
niemeyerfwereade: We might just hold off a bit to see if we need it as such in practice15:58
niemeyerfwereade: If you feel the logic would be more sensible with it, I'd be happy too15:58
niemeyerfwereade: (e.g. maybe we do need the relation key materialized for the algorithms)15:59
fwereadeniemeyer, I'm sure enough we'll want it soon that I'd like to wrap the []RelationEndpoint in  a Relation type, even if I leave the key out until it's needed15:59
niemeyerfwereade: +1 then16:00
fwereadeniemeyer, just to reduce the churn from []RelationEndpoint to *Relation16:00
fwereadeniemeyer, cool, I'll see what I can do with that16:00
niemeyerfwereade: We can have  the key from the get go.. sounds sensible enough even if unused16:00
fwereadeniemeyer, even better :)16:00
niemeyerfwereade: Woohay agreement16:01
niemeyer:)16:01
fwereadeniemeyer, thank you... as usual, I feel wiser :)16:01
niemeyerrobbiew: Do we have the cloud consistency call today?16:01
robbiewniemeyer: let me check with zaid16:01
niemeyerfwereade: My pleasure, love those conversations too16:01
niemeyerrobbiew: Cool, leaving for lunch now.. will be back on time no matter what16:03
robbiewniemeyer: bet on it being cancelled16:03
hazmatrobbiew, ? why16:29
robbiewhazmat: b/c sabdfl isn't here ;)16:30
hazmatcool16:30
* hazmat lunches17:03
* rog is in need of a good name. The provisioning agent has ProvisioningAgent (the command) and Provisioner (the implementing type, renewed when the state connection fails). I'm looking for an equivalent to Provisioner for the machine agent.17:09
rogi'm wondering about machineAgent, but that might be confusing.17:10
niemeyerrog: MachineAgent + Machiner? :-)17:11
rogniemeyer: Machiner seems weird though. i did think of that.17:12
* rog didn't see the smiley17:12
niemeyerrog: It does sound weird, but I was only half-joking ;)17:12
rogniemeyer: ok, Machiner it is for the time being, pending better thoughts17:18
niemeyerrog: Sounds good17:18
niemeyermramm: ping17:20
fwereaderog, hmm, Uniter is actually a surprisingly good name for what the unit agent does, too :)17:32
rogfwereade: unite all the rest of the juju functionality in one command, you mean?17:33
fwereaderog, it also unites various services, if you squint17:33
* rog can't squint that hard :-)17:34
* fwereade has -6.5, -7.0 eyesight and can squint with the best17:34
niemeyerfwereade: RelatedFoo tends to be a bad name to refer to something that is part of a relation17:35
niemeyerfwereade: Everything there is related17:35
fwereadeniemeyer, crap, you're absolutely right, but Counterpart didn't seem quite right there17:35
fwereadeniemeyer, still, if I can teach myself to default to that every time I want to type Related it'd probably be better, wouldn't it17:36
niemeyerfwereade: Right.. and this seems related to a more fundamental issue17:36
niemeyerfwereade: *Relation* shouldn't have these methods17:36
niemeyerfwereade: For the reasons we discussed earlier.. a Relation has no side17:36
fwereadeniemeyer, hence the unordered endpoints17:37
fwereadeniemeyer, my feeling was that the serviceName specified a side quite well17:37
niemeyerfwereade: Hm.. how so?17:38
* fwereade is really glad he's talking about this now and not just seeing the review tomorrow am ;)17:38
fwereadeniemeyer, back up a sec: do you have a problem with (*Relation)Endpoint(serviceName string) (RelationEndpoint, error)?17:39
fwereadeniemeyer, or just with RelatedEndpoint(serviceName)17:39
niemeyerfwereade: Hmm17:40
niemeyerfwereade: The former sounds totally fine17:40
fwereadeniemeyer, I freely admit the name of the latter is awkward17:40
fwereadeniemeyer, I *think* it's a valid thing to ask for though17:40
niemeyerfwereade: I'm starting to think we should go back on CounterpartRole, or at least make it private..17:44
niemeyerfwereade: This seems to have been guiding your thinking in those branches17:44
rogfwereade: OtherEndpoint ?17:44
fwereadeniemeyer, not consciously...17:44
niemeyerfwereade: and I would prefer to not create APIs that sparkle these assumptions on the whole code base17:44
niemeyerfwereade: There's no RelatedEndpoint17:45
fwereadeniemeyer, it just seems that there were a couple of places where we needed to match up counterparts, and I anticipate another, so...17:45
niemeyerfwereade: There are participants in a relation17:45
niemeyerfwereade: The only assumption a given endpoint should make is that it is part of a relation with other endpoints17:45
niemeyerfwereade: The number of other endpoints depends on role17:45
fwereadeniemeyer, or without any other endpoints whatsoever ;)17:46
niemeyerfwereade: There's nothing in our current model that binds the number of endpoints to one, two, three, etc17:46
niemeyerfwereade: Over the last few days, I've been trying to maintain that model, and we have been arguing back and forth around issues that deep inside are related to that17:46
fwereadeniemeyer, yeah, this sounds like it's the heart of it17:47
niemeyerfwereade: RelatedEndpoint makes no sense if there are three endpoints17:47
fwereadeniemeyer, agreed17:47
niemeyerfwereade: and it makes little sense if there is a single one17:47
niemeyerfwereade: (the related endpoint of A is A? huh?)17:47
fwereadeniemeyer, well, it makes more sense than you might think17:47
fwereadeniemeyer, if you read the docs for RelatedEndpoint17:47
niemeyerfwereade: "In the case of a peer relation,"17:48
fwereadeniemeyer, I *think* I was careful to write it in such a way that it did make sense for peer relations17:48
niemeyerfwereade: That's in the docs17:48
niemeyerfwereade: It means "Yo reader! Special case ahead!"17:48
fwereadeniemeyer, on the contrary, it means "yo reader! you probably didn;t read the last sentence carefully enough!" ...which I concede is not *much* better17:49
fwereadeniemeyer, ok, in both significant cases I am aware of, I want to be able to easily get the service which has units that units of a given service might want to relate to17:50
niemeyerfwereade: Hmm.. is that implementation right?17:50
niemeyerfwereade: Oh, ok, nevermind17:50
fwereadeniemeyer, would it make you happier if I made that service*s* which have units which units of a given service might want to relate to?17:50
niemeyerfwereade: It is a special case indeed..17:50
niemeyerfwereade: Look at the implementation17:50
niemeyerfwereade: "If it's not my service, than pick the other"17:51
niemeyerErm17:51
fwereadeniemeyer, yes17:51
niemeyerfwereade: "If it's not my name, than pick the other"17:51
fwereadeniemeyer, indeed17:51
fwereadeniemeyer, the trouble is that we have this task I described above17:51
fwereadeniemeyer, it doesn't seem to me to be a good move to insist on sprinkling special cases per relation type through the code right now, every time we want to do this, on the basis that we might want to have more special cases later17:53
niemeyerfwereade: Agreed, but that seems to have different meanings for us17:54
fwereadeniemeyer, apparently so :)17:54
niemeyerfwereade: RelatedEndpoint in my mind is *huge* special casing17:55
niemeyerfwereade: It  special cases the concept of provider and requirer, of peer, and of the assumption that there are only 1 or two relation endpoints17:55
niemeyerfwereade: All in that small block of code17:55
fwereadeniemeyer, all in that small block of code *tacked onto the Relation type*17:55
fwereadeniemeyer, I think we agree that there are special cases regardless17:56
niemeyerfwereade: No, not at this level17:56
fwereadeniemeyer, I want my relation-related special cases packaged up neatly in the place I expect17:56
niemeyerfwereade: The existence of a Relation is generic17:56
niemeyerfwereade: The fact multiple endpoints participate in a relation is generic17:56
niemeyerfwereade: The fact they may have arbitrary types is generic17:56
niemeyerfwereade: The fact they are arbitrarily numbered is generic17:56
niemeyerfwereade: All of those were properly generic in the previous API17:57
niemeyerfwereade: CounterpartRole changes that17:57
niemeyerfwereade: RelatedEndpoint changes that17:57
fwereadeniemeyer, weeeeeeelll.17:57
fwereadeniemeyer, I invite you to take a look at just what would be involved in adding multi-endpoint relations to the python17:57
niemeyerfwereade: and I'm feeling bad about it because it feels like we're going down that path for no good reason17:57
fwereadeniemeyer, but I *am* trying to figure out a middle ground :)17:58
fwereade<fwereade> niemeyer, would it make you happier if I made that service*s* which have units which units of a given service might want to relate to?17:58
niemeyerfwereade: I didn't parse that sentence.. that's mainly why I didnt answer17:58
niemeyerfwereade: "services which have units which units of given service"?17:59
fwereadeniemeyer, so, (*Relation) OtherEndpoints(serviceName string) ([]RelationEndpoint, error)17:59
fwereadeniemeyer, ok, not Other17:59
niemeyerfwereade: No, that actually sounds fine17:59
niemeyerfwereade: With Other too17:59
fwereadeniemeyer, because I would still want to return the peer endpoint there17:59
niemeyerfwereade: Uh oh18:00
niemeyerfwereade: Then no18:00
fwereadeniemeyer, it's a matter of "[units of which services] might my units want to communicate with?"18:00
niemeyerfwereade: You have a very specific use case in mind, and is tailoring a generic interface to that very specific use case18:00
niemeyerfwereade: Just special case it in your use case.. I bet it's a three or four lines function18:00
niemeyerfwereade: Exactly.. there no "my units" concept outside of "your unit"18:01
fwereadeniemeyer, yes, I am primarily focused on getting an interface that allows me to express what I need in the same way in the 2 cases we currently have18:01
fwereadeniemeyer, so you wouldn't be opposed to a function that basically did that, but you don't like having it on Relation?18:02
niemeyerfwereade: Silly example: it's a well known model to have Primary, Secondary, and Voter18:03
niemeyerfwereade: If I have a Secondary, what's the other Unit?18:03
fwereadeniemeyer, I don't really see how that fits our scenario... can't secondaries become primaries, etc?18:04
niemeyerfwereade: That's not the point..18:05
niemeyerfwereade: What's the CounterpartRole?18:05
rogniemeyer: a couple of small reviews for you, if you like: https://codereview.appspot.com/6302089/ and https://codereview.appspot.com/6312044/18:06
niemeyerrog: Thanks, I'll include them in the set of reviews18:06
rogi've gotta go, see y'all tomorrow18:07
niemeyerrog: Have a good one18:07
fwereadeniemeyer, look, I tried to start this conversation several days ago, and you brushed it off with words to the effect of "I don't know, maybe we'll need more, maybe we're fine with what we have"18:07
fwereadeniemeyer, I'm happy to drop CounterpartRole18:07
niemeyerfwereade: Thanks, I'm starting to feel like this is more important than I thought, because it will affect our thinking elsewhere18:07
fwereadeniemeyer, I understand the high-level concept of "there may be more relation types"18:07
fwereadeniemeyer, I don;t follow how primary/secondary/voter fits in with what we have, because roles can change18:08
niemeyerfwereade: But i was actually trying to explain why I see issues in the OtherEndpoint stuff18:08
niemeyerfwereade: It was an example.. I do think we'll have other relations in the future, and I don't know how they look like right now18:08
niemeyerfwereade: We'll need smart brains, etc18:08
niemeyerfwereade: We'll have maintenance of filesystems and whatnot18:09
fwereadeniemeyer, it seems to me that the roles we have in play are used in really quite a lot of places18:09
niemeyerfwereade: I don't know how those will look like18:09
niemeyerfwereade: But I'm trying to point out that there's no reason why relations are singletons of pairs only18:09
niemeyerfwereade: Primary/Secondary/Voter is a model that I thought was easier to get across18:09
niemeyerBut maybe not..18:09
fwereadeniemeyer, I'm trying to handle one single problem: given a relation R, and a service S in that relation, independent of the number of services18:10
fwereadeniemeyer, *what* services in that relation might units of S need to respond to changes in?18:10
fwereadeniemeyer, I think that this is a generic question18:11
niemeyerfwereade: Processing your (clean) statement.. hmm18:11
fwereadeniemeyer, I understand your reservations re CounterpartRole, but I'm not sure it's as simple as dropping it... what about topology, where we had the counterpart dict beforehand?18:13
niemeyerfwereade: This is facilitating an algorithm that takes into account the specific roles.. that algorithm knows the roles, and deals with them appropriately18:13
fwereadeniemeyer, CanRelateTo takes one argument, and that encodes the 2-service asusmption as well18:14
niemeyerfwereade: Not really18:14
fwereadeniemeyer, at least, surely, we need a CanMakeRelationWith(roles ...RelationRole) ?18:14
niemeyerfwereade: CanRelateTo(A, B).. CanRelateTo(B, C)..18:14
niemeyerfwereade: Not necessarily, no18:15
niemeyerfwereade: Just like you don't need a GreaterThan(numbers ...) to see if a number is larger than a set of numbers18:15
niemeyerfwereade: FWIW, that API was conceptualized in that form with this in mind18:16
fwereadeniemeyer, I think relations between services are perhaps a little more involved than comparisons between reals, but I worry that I'm straying off the point18:16
fwereadeniemeyer, does it make sense to have an incomplete multi-endpoint relation though?18:17
niemeyerfwereade: CanRelateTo(Voter, Primary)... CanRelateTo(Primary, Secondary)...18:17
niemeyerfwereade: These are examples.. I hope they make some sense to you18:17
fwereadeniemeyer, *kinda*, but... does it really make sense to have, say, *just* voters and primaries?18:18
niemeyerfwereade: In a number of cases, yes18:19
fwereadeniemeyer, I'm not clear what impact the votes could have then18:20
fwereadeniemeyer, but can we take it as read that there are more kinds of relation than are dreamed of in my philosophy18:20
niemeyerfwereade: For a typical database, maybe it doesn't do much, but it actually works, and may be a fine step towards establishing the full topology wanted18:20
niemeyerfwereade: The real point is that CanRelateTo(Primary, Primary) would fail.. and CanRelateTo(Peer, Requirer) would also fail18:21
fwereadeniemeyer, ok, that makes sense18:21
fwereadeniemeyer, but regardless... can you think of a generic way to expose an answer to the problem I'm trying to solve?18:23
fwereadeniemeyer, OtherEndpoints would almost work, except for peer relations it's not really an "other" endpoint18:23
fwereadeniemeyer, RelatedEndpoints feels to me like it's the closest I've heard yet18:24
fwereadeniemeyer, but I suspect you will dislike that word for perfectly rational reasons18:24
niemeyerfwereade: I'm still processing your previous (clean) statement.. that was a great way to put it18:24
fwereadeniemeyer, thanks :)18:25
fwereadeniemeyer, I'm also fretting that, really, we've got a *lot* of generic code to put in place to support this18:25
fwereadeniemeyer, for example, I can't in good conscience implement unit agents with only one presence node per relation18:26
fwereadeniemeyer, I can't watch related units without watching a range of possible locations for the presence nodes18:26
fwereadeniemeyer, it all makes me very nervous18:26
fwereadesorry, brb18:27
niemeyerfwereade: Okay, your thinking seems to be reaching my head18:30
fwereadeb18:32
niemeyerfwereade: :)18:32
fwereadeniemeyer, indeed, I'm not actually blind to your perspective, but it has been rather hard to incorporate it at the point where the bits hit the disk, as it were ;)18:33
niemeyerfwereade: Your idea of RelatedEndpoint sounds fine.. I can't think of a better name either18:33
niemeyerfwereade: Can we do one tweak:18:34
fwereadeniemeyer, surely :)18:34
niemeyerfwereade: Considering all the conversation about regarding multiple endpoints and the unknown coming future,18:34
niemeyers/about/above18:34
niemeyerfwereade: I'd appreciate if we could make counterpartRole private, and make RelatedEndpointS (plural) return a slice18:35
fwereadeniemeyer, SGTM18:35
niemeyerfwereade: and attempt to keep in mind the fact we don't have a clearly defined set of relation roles when doing the lower level algorithms18:35
fwereadeniemeyer, if I'd been thinking I would have made that private in the first place18:35
fwereadeniemeyer, I'll do my best :)18:36
niemeyerfwereade: I don't want to go crazy with that, though18:36
niemeyerfwereade: It's just a way to force us to *try* to go in that direction if it's not too much pain18:36
niemeyerfwereade: If it turn out to make no sense, we can always talk again and see if we should reevaluate our position18:36
fwereadeniemeyer, ok, I'll see how we do :)18:37
niemeyerfwereade: Thanks a lot, and sorry for making such a minor step difficult somehow18:37
fwereadeniemeyer, on the upside, multi-peer relations really shouldn't be too hard even as we are now18:37
fwereadeniemeyer, np, a pleasure, we all end up the richer for these discussions ;)18:38
niemeyerfwereade: That's an easy case to keep in mind.. if we can handle that with minor trouble, we're probably in a good direction18:38
fwereadeniemeyer, cool18:38
fwereadeniemeyer, I should probably go and see some physical human beings now, gn :)18:38
niemeyerfwereade: Haha18:39
niemeyerfwereade: Sounds like a good plan, thanks :-)18:39

Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!