/srv/irclogs.ubuntu.com/2020/03/13/#smooth-operator.txt

Chipacagood morning peeps!09:14
niemeyerMoin moin09:14
niemeyerChipaca: Didn't get to do a full round of reviews yesterday.. thankfully friends/family called09:40
niemeyerGot through the harness one, though, and just replied to your first requested point above09:40
Chipacaniemeyer: glad you got some social interaction in :-)09:41
Chipacai went out and had a belated birthday dinner with my uncle and my brother+sister-in-law09:42
Chipacawe tried not to cough too much at people09:42
Chipacanow i'm going to finish the HR training thing before they get upset09:43
niemeyerReplied to #178 as well10:08
Dmitrii-ShThanks for the replies on #157. I made a comment about the "default binding" term here https://github.com/canonical/operator/pull/157#discussion_r392150027 - I hope the example makes sense10:40
niemeyerReplied10:46
Chipacai need to step out for a bit10:48
* Chipaca realises he hasn't actually moved10:51
FacuMuy buenos días a todos!11:24
ChipacaFacu: o/!11:26
niemeyer\o11:27
niemeyerI'm going to skip the standup today as I'm researching something for a call with Mark in a bit.. I've been reviewing and will be reviewing is my main action points11:42
Facuniemeyer, (no rush, just don't want to drop your comment from yesterday) -- "That DBAvailable event really wants me to make StoredState work there" <-- this means to provide to events the same mechanism of "store whatever you want, then access it later" for the charms, right?11:47
niemeyerFacu: I meant supporting a _stored = StoredState() attribute in events so people don't need to implement the methods11:48
Facuniemeyer, having "one mechanism to rule them all" sounds nice, not having to learn two things... however, Events may be simpler than that, we could have the responsability of spawn the same event using the original information automatically, no developer code needed11:48
Facuwe could just "freeze" the events and melt them later... we want for Events to not carry around any extra information, right?11:52
Facuwhat about defining the events like this? https://pastebin.canonical.com/p/yzbpvNMKHW/11:53
niemeyerFacu: The thinking behind StoredState is that it enables people to very clearly define things they do want persisted and things they don't want persisted11:53
Facuwe can take care of having those fields inside, saving them and loading them11:53
niemeyerFacu: There's no ambiguity when one is using code like self._stored.private_addresss about where that value is coming from, where it goes to11:54
niemeyerFacu: This already works for anything that is an Object in the framework world11:54
niemeyerFacu: So this need is not unknown to us, or something we need a different design for I think11:54
Facuniemeyer, I get that; my point is if we want to encourage people to have "super simple event objects that may carry one or two well-defined pieces of information", or "a generic object with complex machinery that may save some state and flies around"11:55
niemeyerFacu: If we do change it, we need to change everything else with it so we don't have diverging patterns inside the same logic11:55
niemeyerFacu: Yeah, that's what I'm talking about too11:55
niemeyerFacu: I don't see self._stored.private_address as worse than self._private_address + a list of fields elsewhere11:56
niemeyerFacu: The list of fields means you'll need to read the list of fields again every time you want to know which of the 10 attributes are persisted or not11:56
niemeyerSeems very error prone and unfriendly11:56
Facuall those fields are persisted11:57
niemeyerFacu: All the fields in the list of fields are persisted11:57
niemeyerFacu: All the fields not in the list of fields are not persisted.. right?11:57
Facuthere are not "fields not in the list", we don't allow them, we enforce the Events to be dead simple11:58
Facuthat pastebin I shown holds *all the code* for the Event the user needs to write (it was not just the beginning)11:58
niemeyerFacu: So what happens when one needs any kind of logic in the event?  Then the dead simple becomes painful?12:01
niemeyerFacu: Again.. we have a solution for this problem, because it's a common problem. If our solution needs further improvements, let's do so for everything.12:01
Facuwe want developers to add logic to the event? if yes, let's go with developers handling what they store by hand, yes12:01
niemeyerFacu: If we want people to be able to use normal Python code in their types?  Yes12:02
niemeyerFacu: I hope you can see the value in us defining a strong pattern that solves that kind of issue nicely and consistently12:03
niemeyerFacu: Does StoredState work in events today?12:04
Chipacaniemeyer: standup?12:16
niemeyer11:42:15 <niemeyer> I'm going to skip the standup today as I'm researching something for a call with Mark in a bit.. I've been reviewing and will be reviewing is my main action points12:17
Chipacaniemeyer: missed that. thanks.12:29
Chipacaniemeyer: good luck with the call12:29
niemeyernp, and thanks12:32
jamChipaca: no, its just me trying it out. ":return: None" is probably better.12:34
Facuniemeyer, yes, I totally see the value, my other proposal was a way to super restrict users in what they could do with the events, if we wanted that12:47
Facuniemeyer, I would need to explore if StoredState works in events today; without exploring/seeing code I don't envision how we could restore/unfreeze an Event that was deferred and make external code to access what the event has stored12:49
niemeyerFacu: Restoring data is exactly what StoredState does.. both deferred Events and StoredState use the normal persistence system of the framework12:51
niemeyerThings are not so far apart as they may seem12:51
niemeyerIt probably already works if we make EventBase a child of Object12:51
Faculet me play with the code a little12:52
Facuthis is weird, I just noticed that the timestamps from "juju debug-log" are local (GMT-3), not UTC (which is how the units are configured)14:15
Facuwhich makes me wonder... when I see14:15
Facuunit-my-super-charm-5: 11:13:56 INFO juju.worker.uniter.relation joined relation "my-super-charm:dumper postgresql:db"14:15
Facu...that means that the event happened at minute 13 second 56, or that juju is showing me the message at that time?14:16
Dmitrii-Shhttps://github.com/canonical/operator/pull/157#discussion_r39228993015:15
niemeyerFacu: I don't know the response to that.. It would be nice if what you see _locally_ in debug-log is in the local timestamp, though15:16
niemeyerFacu: I believe the data is stored in UTC, because that's what the db driver will do by default15:16
niemeyerFacu: But.. don't trust me :)15:16
Facuso it probably shows me the original timestamp, shifted for my local timezone15:17
niemeyerDmitrii-Sh: As I said there, we seem to be in very different wavelengths15:18
niemeyerDmitrii-Sh: I am (and Chipaca is) trying to explain things in a way that makes sense to users15:18
niemeyerDmitrii-Sh: Saying that we're returning an "app endpoint binding" doesn't make any sense in this context15:19
niemeyerDmitrii-Sh: The API allows people to bind specific spaces to endpoint names, and to specific relations established15:19
niemeyerDmitrii-Sh: That's the general framework people will have in mind when they're coding or using the system15:19
niemeyerDmitrii-Sh: The terminology we pick needs to make sense inside that framework15:20
niemeyerFacu: I *hope* so15:20
Facuniemeyer, good enough15:20
Dmitrii-Shniemeyer: I think you are right about naming. My suggestion lacks an adjective for "non-relation-specific" bindings.15:24
Dmitrii-ShYou could have two apps related via their relation endpoints bound to different spaces as of today AFAIK. It doesn't make a lot of practical sense in my view but relation instances themselves cannot be bound to spaces.15:24
Dmitrii-Shi.e. one can't say15:25
Dmitrii-Shbind "1=myspace"15:25
Dmitrii-Shfor relation_id=115:25
niemeyerI don't think I understand what you're trying to say... we accept a relation instance in that method precisely because people can bind spaces to specific relation IDs.. network-get takes an ID parameter doesn't it?15:29
Dmitrii-Shniemeyer: network-get accepts a -r <id> parameter, however, juju doesn't allow things like `juju bind <relation-id>=<space>` or `juju relate <appA> <appB>` via a space15:41
niemeyerDmitrii-Sh: Sorry, can we focus on that first part for a moment15:41
niemeyerDmitrii-Sh: What does that mean that network-get accepts a relation ID?15:41
Dmitrii-ShOne can use `network-get <endpoint-name>` or `network-get -r <rid> <endpoint-name>` https://github.com/juju/juju/blob/juju-2.6.7/worker/uniter/runner/jujuc/network-get.go#L8315:43
Dmitrii-Sh-r <rid> could only provide a different output in the case of CMR15:43
niemeyerDmitrii-Sh: If you may get a different binding when you provide an ID, that means a relation instance may in fact be bound to a particular space, right?15:44
Dmitrii-ShNot at the moment, a relation id only affects the selection of ingress-address and egress-subnets when CMR is used. It's difficult to explain because the logic is convoluted at the Juju side:15:47
Dmitrii-Shhttps://github.com/juju/juju/blob/juju-2.7.4/apiserver/facades/agent/uniter/networkinfo.go#L142-L15515:47
Dmitrii-Shhttps://github.com/juju/juju/blob/juju-2.7.4/apiserver/facades/agent/uniter/networkinfo.go#L310-L33415:47
niemeyerDmitrii-Sh: Man.. can you please stop sending me links? :)15:47
Dmitrii-ShOK, simply put: as a user, I cannot specify a space per relation ID - only per endpoint name.15:48
niemeyerDmitrii-Sh: We're documenting the juju CLI15:48
niemeyerDmitrii-Sh: We're documenting the operator framework API15:49
niemeyerDmitrii-Sh: network-get takes a parameter which is a relation ID15:49
niemeyerDmitrii-Sh: Your code accepts a parameter which is a relation instance.. the method name is get_binding15:49
niemeyerDmitrii-Sh: This is a very simple story.. the confusion comes if we try to reject what is clear15:50
niemeyerDmitrii-Sh: We're NOT documenting the juju CLI15:50
niemeyerThe alternative here is to change the API so that we don't do any of that15:52
niemeyerTaking details out of the binding information15:52
niemeyerI don't know how to do that cleanly, though, because that's a "network binding", and these are network binding details15:53
niemeyerIf we take egress,  ingress, etc out of the network binding details, where do we put them?15:53
Dmitrii-Shnot `Relation`s because they might not exist at a given point in time15:55
Dmitrii-ShAs an idea, since apps have endpoints: self.model.app.<something>15:59
niemeyerHow about this: specific relation instances may have different network bindings16:00
Dmitrii-Shso, relation.binding.network.ingress_address would only work if you had a reference to a relation16:01
Dmitrii-Shbut get_binding(relation_name) would give you a relation-less binding16:01
niemeyerDmitrii-Sh: We might also make get_binding accept a relation instance16:01
Dmitrii-Shwell, then we are back to the naming conversation16:02
niemeyer!!!16:03
Dmitrii-Shok, sorry, I didn't get your point:16:07
Dmitrii-Sh1) relation.binding - OK, we could do that16:07
Dmitrii-Sh2) get_binding(relation_instance) - OK, it's in the framework already16:07
Dmitrii-Shwhat's the catch?16:07
niemeyerThe catch is this is a long proposal to change something that apparently works, matches what juju does, and is relatively clean, without a rationale16:09
niemeyerWe got into this conversation because I was proposed three lines of documentation to explain what was going on16:10
niemeyerYou disagreed.. and I asked: okay, we have these three scenarios in this method.. how do we document them?16:11
niemeyerWhich then got you to argue with dozens of links :) about how we don't relation-specific bindings16:12
niemeyer*don't have16:13
niemeyerExcept, well, apparently we do otherwise we cannot explain the behavior16:13
niemeyerSo.. let me know how you want to document it cleanly :)16:13
Dmitrii-Shok, I'll think about an alternative for "default binding for that relation" phrasing because it overlaps with "a default binding for all endpoints of an application". I'll suggest it if I come up to something.16:19
niemeyerDmitrii-Sh: "default for the relation" and "default for the application" only overlap in the "default" part.. default is a very common term that has an important meaning, and is hard to replace16:21
Dmitrii-ShI agree, I'd be confused though because "default for the relation" is not documented in the Juju docs. I am not suggesting "default binding" is well documented in Juju either but at least it's mentioned :^)16:23
Dmitrii-ShEither way, replacing a docstring is easier than replacing an API.16:23
niemeyer@Dmitrii-Sh Which is exactly why I outlined the three points in my comment in the PR16:24
niemeyerFull circle now.. we have bindings for a relation name, bindings for a relation instance that may return the bindings for that instance, and bindings for a relation instance that actually return the bindings assigned to the relation name16:24
niemeyerThe third case is a fallback16:24
niemeyerAn easy way to explain a fallback is with the "default" word16:25
FacuOk, I can not use my system's autopep8 because it seem it's too old16:47
FacuI'll use a venv, with system-site-packages so I get PyYAML from the system, which is what we wanted to do16:48
Facuhowever, now all the test fails because (for example) files inside the env doesn't have a copyright header :p16:49
Facu(I also had to move my test charm out of this directory for the same reason)16:49
FacuChipaca, any objection that we specify "ops" and "test" in the Makefile commands? otherwise it's too intrusive, not letting anybody have other stuff in the same dir while developing16:50
Dmitrii-Shniemeyer: ok, I think we can settle on "default" for now16:50
Dmitrii-Shthanks for guiding me through the thought process behind it16:51
ChipacaFacu: and setup.py i guess :-)16:51
ChipacaFacu: and … anything else?16:51
FacuChipaca, setup.py already specify     packages=["ops"],16:52
ChipacaFacu: i mean the other way around16:52
ChipacaFacu: setup.py should be held to the same standard as the rest of the code16:53
Facuah16:53
Facuwould you mind to explain me the rationale of using *both* autopep8 and flake8?16:57
Facuif we're trying to have our code compliant to pep8, have a flake8 guardian should be enough16:58
ChipacaFacu: i'm not familiar enough with the details of those two to know what they cover16:58
Chipacaor how much overlap they have16:58
niemeyerI can explain..16:59
niemeyerFacu: We want to stick to flake8 as it's probably the most common tool use for this and it does a good job16:59
niemeyerFacu: We use autopep8 to automatically do that for us16:59
Facuyes, everybody uses it16:59
niemeyerFacu: The goal of using both is to ensure that we remain compatible with flake8, but we want to get the hints that autopep8 give us to tell how to fix it17:00
niemeyer*gives us17:00
niemeyerThat's why autopep8 comes first as well17:00
niemeyerAnd that's why travis runs it with --diff17:00
niemeyerInstead of telling us "You guys suck", it says "You guys suck in those specific ways, and this is how you should not suck"17:01
Facuack17:02
Facuwould you mind if I run these two as part of the unit test infrastructure (together with the grep and find for copyright and backslashes)?17:02
Facuthat would allow us to have a more simple indication on where everything must run, and get rid of the Makefile17:03
* Facu would leave just a "test" script 17:03
niemeyerWe don't need to run both all the time.. I'd run just autopep8 which is the one that gives us more details17:04
niemeyerKeep flake8 in travis as a double check17:04
FacuI can do that17:04
niemeyerRunning it in test seems fine, as long as it doesn't take a lot of time to run every time, and that there's a flag to not run it (sometimes you want to test code even if it's messy for the moment)17:04
Facuniemeyer, that's one beneffit of getting it as a unit test, you can have a total messy code, and you will only get one failing test (currently it just blocks the execution of the real tests)17:06
niemeyerI see what you mean, yeah, sounds good17:06
Facualso I'll try also flake8 locally, and see if it's slow or not17:06
FacuA mate, and then the final stretch19:36
niemeyerI'm envy19:36
* Facu eods and eows!21:12
Facusee you all on Monday!21:12
niemeyerHave a good weekend!21:12
Facuniemeyer, same for you!21:13

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