/srv/irclogs.ubuntu.com/2020/04/21/#smooth-operator.txt

jammorning all05:15
niemeyerMorning jam07:49
niemeyerMorning all07:49
jammorning niemeyer07:49
mup_PR operator#236 opened: ops/log.py: Default to DEBUG logging <Created by jameinel> <https://github.com/canonical/operator/pull/236>08:09
niemeyerjam: Reviewed, thanks08:14
jamthanks for the review08:34
* jam goes to make lunch08:34
Chipacagooooood morning!08:52
niemeyerHey hey08:52
stubChipaca: https://code.launchpad.net/~stub/interface-pgsql/+git/operator , which needs a better repo home and updating to namespace standards when the standards exist :)09:04
niemeyerstub: I hope to have this settled before the week is over09:04
stubYup, no hurry from my end09:05
niemeyerstub: We also need to have some kind of group for reviewing interfaces while we try to develop some joint agreement of which directions we want to go09:05
niemeyerstub: This sounds like the right time for that09:05
niemeyerstub: That is, now that we're about to have the basic proposal in place for the extension mechanism and the namespacing09:06
niemeyerstub: Would be happy to have you on board this effort09:06
stubok, let me know if I'm needed when you get that far.09:09
niemeyerstub: Your presence would certainly be good, given your prior experience in the postgres charm and interfaces.. we also need to do a review of these interfaces to evolve our idea of which way we want to go as recommended patterns09:11
niemeyerstub: Did you inspire the initial implementation on the sketches that were being discussed here, or completely independently?09:11
stub(and that intereface needs tests, so probably would fail review right now ;) )09:12
niemeyerstub: Well, that's another area worth talking about.. we've been evolving the Harness, so it would be interesting to know how suitable it is for working with interfaces as well09:12
stubniemeyer: Somewhat independently... based on some examples (graphana request for comments I recall)09:13
niemeyerstub: Cool, let's please try to find a slot that works for everyone over the next few days and get that going09:13
niemeyerstub: I will have the mechanism and namespace proposal in hand by then09:14
Chipacastub: thanks!09:15
Chipacagraaah09:53
* Chipaca hulk-smashes09:53
Chipacawhy would _simulate_event itself clear the charm state09:53
Chipacathat should be done by tear-down09:53
Chipacastoopid stoopid09:53
niemeyerMe too, but in a good way.. manual k8s deployment seems to work okay09:54
Chipacaand of course the test charm doesn't load the state before writing it out09:56
Chipacait's all worms all the way down09:56
Chipacain fact why is this doing it by hand09:56
Chipaca… D'OH10:51
jamChipaca, can you point me at what you're talking about? _simulate_event is not something I'd generally recommend.10:51
Chipacatruncate() and truncate(0) are *not* the same thing10:51
Chipacajam: hi :)10:51
Chipacajam: it's in test_main.py10:51
Chipacajam: there's a combination of issues that made it hard to figure out for me10:52
Chipacajam: the test_main charm nukes its state every time10:52
Chipacaie it does not load state, just sets it to default10:52
Chipacanot helped by doing things by hand instead of using StoredState10:52
Chipacathen, _read_and_clear state does truncate() instead of truncate(0)10:53
Chipacaso i fixed one side of that and then was confused by the other side breaking10:53
jamChipaca, in each test? I would expect that, otherwise the tests would be coupled and you couldn't just run 1 test. But _simulate_event doesn't, does it?10:53
jamChipaca, oh.10:54
Chipacajam: in test_main/src/charm.py, in __init__, it just does _state = {}10:54
Chipacaso no matter how many times dispatch dispatches an event you'll only get the one event in the state10:54
jamload and then truncate, but don't actually do anything because you just read a bunch of stuff so truncate() is a noop, right?10:54
Chipacanah, that bit is fine (in a twisted kind of way), it truncates it so the _next_ call gets the data ok10:55
Chipacai wouldn't write it that way but it works (assuming truncate(0) and not truncate() as it was written)10:55
jamChipaca, that's what I mean. Plain truncate() is a no-op10:56
Chipacaah, yes10:56
jamyou just read the filefor pickle.load()10:56
Chipacajam: i'm not sure we're in sync, so let me replay events for you:  i was trying to write a test that made sure that dispatch + a hook that pointed to the same thing only triggered the event once10:57
Chipacajam: i wrote the test, and it passed! but that made no sense, and adding prints to the charm code showed me it was processing the events twice10:57
Chipacajam: then i noticed that __init__ was not loading the state, just setting it every time, so that's why it was failing10:58
Chipacaor rather, failing to fail10:58
Chipacajam: so i fixed that10:59
Chipacajam: and then other tests started failing!10:59
Chipacajam: because truncate() instead of truncate(0)10:59
Chipacajam: <the end>10:59
Chipacai think it needs refactoring to used StoredState at some point, but for now this seems ok to me11:00
Chipacanot ideal :) but ok11:00
jamChipaca, yeah, so we only ever write the state file, we wb which means we always write from the beginning, and we never read it to include more events...11:07
jamChipaca, so, between updating the tests to not overwrite the state file on each call, and using StoredState, which do you think you prefer?11:08
jamChipaca, I feel like StoredState would be more the way we want the charm written, and means it would get auto loaded and saved rather than explicitly done by the charm11:10
Chipacajam: I think we want to rewrite it to use StoredState because people will pick up on this way of doing things if not11:13
jamindeed11:13
Chipacajam: but I think it needs doing in a separate PR as it'll be a big refactor11:13
jamlooking at it right now11:13
Chipacajam: ideally _after_ i land this which already touches test_main :-311:13
jamChipaca, so in setUp we end up calling 'exec_module'. Does that exec the module with __name__ == __main__ ? or is it just effectively 'import the module into a namespace' ?11:17
facubatistaMuy buenos días a todos!11:19
jammorning facubatista11:20
jamany chance you could look at #230 today?11:20
mup_PR #230: Testing harness no events for own data <Created by jameinel> <https://github.com/canonical/operator/pull/230>11:21
facubatistahola jam11:23
facubatistajam, yes!11:23
jamgreat11:23
Chipacajam: it does not exec the module with __name__ == __main__, no11:26
jamChipaca, k. its essentially just 'import' but return the module as an imported thing, rather than into sys11:26
Chipacajam: it execs it with __name__ being the "fully-qualified name of the module"11:26
Chipacajam: the import has two parts, loading the code object, and executing it11:27
Chipacabah, loading also has two parts, finding it first :)11:27
Chipacajam: but, yes11:27
Chipacait's 'exec' in the exec-the-keyword sense, not in the exec-the-syscall sense11:27
Chipacajam: note the module is already 'loaded' before the exec call, in that self.charm_module is already <module 'charm' from '<...>/test_main/src/charm.py'> before you exec it11:30
jamChipaca, presumably it doesn't have any types, etc defined, right?11:31
Chipacajam: correct, just a name, a source, a loader, etc11:33
* Chipaca looks11:33
Chipaca['__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']11:33
Chipacathat's all :)11:33
jamChipaca, not critical to my understanding of what is going on. Mostly it is a way to do 'import foo' but not actually pollute your local namespace.11:33
Chipacayep11:34
Chipacaalso it doesn't touch sys.modules11:34
Chipacanot sure why we're not just doing __import__ though ¯\_(ツ)_/¯11:34
Chipaca(but i haven't looked in detail; there might be some tweak or subtlety i'm not seeing)11:35
Chipacaouch, i must go get lunch otherwise it's all meetings all the time and i'll be eaten alive by feral teenagers11:35
jamChipaca, So I have a different test that just does 'import' but means i clean out sys.path afterward. I think this is 'think about that other charm thing'11:35
jamChipaca, eat hearty11:36
facubatistajam, why RelationDataContent is a lazymapping? and not grab all the info at once?11:38
jamfacubatista, so I didn't write it, but it reads all the data when you access one attribute. it doesn't read keys individually11:38
jamit just doesn't read the data if you only write 1 key11:38
facubatistajam, do you know why?11:39
facubatistait's an optimization?11:39
jamfacubatista, yeah, I presume it is just to avoid calling relation-get just because you have a relation, but you don't access any data11:39
jamand the LazyMapping means that once you *do* read something, you don't pay an overhead for every access, it gets once and caches the content11:40
jamfor the lifetime of a hook, the content you read isn't allowed to change, so it is fine to cache.11:40
jamin Testing, though, we don't want to destroy the whole model and build it back up between steps11:40
jamso we _invalidate the parts we know we're changing.11:40
facubatistajam, _invalidate() does not "discards current cache content", but "prevents further caching"?11:42
jamfacubatista, no, it sets _lazy_data to None, so it will be reloaded on next access11:42
facubatistaso it discards current cache?11:43
jamcorrect11:43
facubatistaso, let me recap11:43
jamLazyMapping has a _data attribute that returns _lazy_data if not None, else load _lazy_data11:43
facubatistaI just do rel_data = relation.data.get(entity) ... at this moment, rel_data is "empty", the real info is not loaded yet, so it's not cached, right?11:44
facubatistait's _lazy_data is still None11:44
jamfacubatista, if that is all you do, yes. If someone has accessed that object before, the data might already be loaded11:45
jamwhich is what why we want to _invalidate so we know the new content will be loaded.11:45
facubatistaok11:46
facubatistathanks, I understand now11:46
jamChipaca, so... I have a rough cut of replacing the STATE_FILE with StoredState. But it turns out we're doing some "naughty" stuff.11:53
jamNamely, it saves the type(event) for all the events, which then get pickled down to the state file, and are assumed to be reloaded correctly11:54
jamand then the test dose: "assertEqual(state.events, [EventType])"11:54
jamwhere EventType is "from framework import EventType", and state.events was unpickled from the charm state file.11:54
jamWhy are they doing AllHands in the middle of Vienna Product roadmap ...11:56
* facubatista misses real all hands11:57
jam:)11:57
jamYeah. Though to be fair, All-Engineering is about 200 people, which is almost the size of the largest all-hands11:58
facubatistajam, yeap, but we don't mix to the rest of the company11:58
facubatistajam, it's not about size, but (content) diversity11:58
facubatistajam, I added a couple of small details inline in the #230 review; those are probably so small that we may be done with this today12:02
mup_PR #230: Testing harness no events for own data <Created by jameinel> <https://github.com/canonical/operator/pull/230>12:02
jamfacubatista,             # rel_data may have loaded now-stale data, so _invalidate() it. Note that just12:03
jam            # accessing rel_data for an entity doesn't load it unless you access an attribute.12:03
jam?12:03
jamThe point is to note that the act of wanting to invalidate won't itself read the data, but I understand wanting both comments.12:04
facubatistajam, but we don't care if it read the data, as we're invalidating it! that is confusing12:06
facubatistait looks like "oh, so let's not call to invalidate, and for sure will not be reading the data"12:06
jamfacubatista, so the concern that G had, was that if we access rel_data, it looks like we read it, just to invalidate it.12:06
jamso I'm trying to find a way to express "make sure if it was read, we invalidate it, but we don't force a read here"12:07
facubatistathe point of that invalidate call is to clear *possible previously* loaded cache12:07
facubatistajam, the "Note that just accessing rel_data for an entity doesn't load it unless you access an attribute." is a good piece of information, maybe confuses to be just around the invalidate() call12:09
jamfacubatista, how about:12:51
jamrel_data may be caching now-stale data, so _invalidate() it.12:51
jamNote, this won't cause the data to be loaded if it wasn't already.12:51
facubatistajam, I like it, may you replace "be caching" with "have cached"?12:53
niemeyerHey folks, can we have the standup a bit earlier today?  I have an errand that I need to run this afternoon and it would be helpful if I could do it a bit earlier12:55
jamsure13:03
jamfacubatista, ^^13:03
jamniemeyer, we can, though I have a meeting just before it. but it is lower priority13:03
facubatistaniemeyer, otp, what about in 10'?13:04
niemeyerjam: No worries then.. it's not critical on my end either13:04
niemeyerfacubatista: Let's do at the usual time13:04
facubatistaack13:04
* Chipaca suddenly realises the time13:27
facubatistaChipaca, you mean, in an einstanian way?13:29
jamTime flies like an arrow. Fruit flies like a banana13:29
jamfacubatista, can you check if 230 now matches your expectation?13:33
facubatistajam, yes13:34
pekkariHi, qq, is juju triggering any config-changed after upgrade charm?13:43
Chipacapekkari: AFAIK yes, why?13:48
Chipacajam: ^13:48
pekkarithanks Chipaca, just to know, the charm I'm working on was having config rewrites in the upgrade path that I believe are redundant, so if config change comes after, I can just drop that code13:49
Chipacapekkari: perhaps relatedly, if the unit is in error state and you force-upgrade the charm, the upgrade-charm isn't triggered but the config-change is (i only know this from notes in our codebase)13:51
pekkariseems to be a case I wasn't into it yet, as I was just ensuring I can, from a working unit, upgrade the charm, and get to a ocnsistent state, but good to know13:52
jampekkari, Chipaca : afaict, on the agent side, it doesn't explicitly say "an upgrade was done, thus I must also do a config changed". However, I think if you do an upgrade, the act of requesting an upgrade might create a new config state, since old version of the charm and new version of the charm may have different fields available.13:52
pekkarithat makes sense, jam, thanks!13:55
jampekkari, a quick test with 'juju debug-hooks' says that we do, indeed, trigger a config-changed with upgrade even if you didn't pass '--config' to upgrade-charm.13:56
pekkariawesome, wiping unneeded code then :)13:58
facubatistajam, I see that you answered two conversations, but other two are unanswered, and no commit pushed... maybe I'm looking at it wrongly?14:08
Chipacajam, niemeyer, if you have a hook and dispatch, and the first one fails, should the second one still run?14:40
facubatistaChipaca, I'd follow the same reasoning of "if you have two registered callbacks for one event, and the first callback fails, should the second still run?"14:46
Chipacafacubatista: yeah, and afaict the answer is no14:47
facubatistaChipaca, I concur14:49
Chipacagithub seems to be having issues15:36
Chipacacan't comment on a pr right now15:36
Chipacai think that's github's way of telling me to take a braek15:36
* Chipaca obeys15:36
facubatistajajaj15:46
facubatistaChipaca, that, or they decided to turn it off forever15:46
jamfacubatista, so I tried to push, but I think Chipaca had auto-committed to my branch, so it rejected my push. sorry about that. I didn't see the "rejected" on the push16:44
jamfacubatista, I just confirmed the PR has been updated with my commits. can you look again ?16:45
jamChipaca, I agree, whatever fails first stops the second from executing.16:45
Chipacaof course now there are _three_ comments with the same content18:12
Chipacaah well18:12
Chipacaat least i'm consistent :-D18:12
Chipacaand travis <-> github is now discombobulated18:14
Chipacait's fun all the way down18:14
Chipacai shoulda just carried on running :-)18:14
* Chipaca is sure he used to know english18:15
facubatista"discombobulated"18:17
Chipacafacubatista: https://en.wiktionary.org/wiki/discombobulated18:23
facubatistanice18:24
* facubatista eods21:14
Chipacafacubatista: 👋 have a good one21:19
facubatistaChipaca, good night!21:22
* facubatista really goes21:23
* Chipaca EODs23:18

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