many: fetch & cache remote snaps and sections; complete from there #3748

Closed
wants to merge 7 commits into
from

Conversation

Projects
None yet
4 participants
Member

chipaca commented Aug 16, 2017

While the sections work wasn't strictly needed, it helped to
understand the pattern I was going for as to how these things are
handled (e.g. why a 'cache' directory and not dropping these things
directly in /snapd/).

The worst part of this is probably the names of the ensure bits. I'll
leave you all to decide that.

many: fetch & cache remote snaps and sections; complete from there
While the sections work wasn't strictly needed, it helped to
understand the pattern I was going for as to how these things are
handled (e.g. why a 'cache' directory and not dropping these things
directly in /snapd/).
Member

chipaca commented Aug 23, 2017

(sneakily rebased as nobody had looked at it yet)

Member

chipaca commented Aug 23, 2017

Sigh. Tests in overlord/snapstate don't dirs.SetRootDir, so end up using the real paths for things. Ouch.

chipaca added some commits Aug 23, 2017

Member

chipaca commented Aug 23, 2017

completion spread test failure is real. Need to dig.

codecov-io commented Aug 24, 2017

Codecov Report

Merging #3748 into master will decrease coverage by 0.08%.
The diff coverage is 60%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3748      +/-   ##
==========================================
- Coverage   75.74%   75.65%   -0.09%     
==========================================
  Files         409      409              
  Lines       35388    35513     +125     
==========================================
+ Hits        26804    26869      +65     
- Misses       6688     6735      +47     
- Partials     1896     1909      +13
Impacted Files Coverage Δ
cmd/snap/cmd_find.go 62.5% <0%> (-2.72%) ⬇️
dirs/dirs.go 98% <100%> (+0.08%) ⬆️
cmd/snap/complete.go 58.84% <22.72%> (-3.6%) ⬇️
overlord/snapstate/snapstate.go 79.38% <47.36%> (-1.3%) ⬇️
store/store.go 79.49% <75%> (-0.22%) ⬇️
overlord/snapstate/snapmgr.go 79.91% <88.88%> (+0.57%) ⬆️
interfaces/sorting.go 97.43% <0%> (-2.57%) ⬇️
overlord/snapstate/check_snap.go 79.18% <0%> (-1.53%) ⬇️
overlord/ifacestate/helpers.go 62.33% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 73bbe43...b6a0ba4. Read the comment docs.

@pedronis pedronis added the Blocked label Aug 29, 2017

Member

chipaca commented Aug 30, 2017

I've got the conflict resolved locally, as well as dropping refresh from 1/hour to 1/day. I'll hold off on pushing these until I've had a review, to not spam travis too much.

Some comments inline.

I think my main worry is that wget a better solution because it writes stuff to disk while we keep the result in memory. As number of snaps grow this will eventually prevent snapd from working on memory-constrained devices.

  • Could the store send stuff sorted in the right order? This saves O(N) sort calls on the scale of the planet.

  • Could we just write it to disk and do an atomic rename?

+
+ var ret []flags.Completion
+
+ // TODO: the file is sorted; we should bisect it
@zyga

zyga Aug 30, 2017

Contributor

How much data are you expecting to see in the particular use case that you wrote this for?

@chipaca

chipaca Aug 30, 2017

Member

I hope it'll grow to be in the millions. I expect it to be in the hundreds of thousands at least.

+ }
+ }
+ }
+
@zyga

zyga Aug 30, 2017

Contributor

I think you ought to also call scanner.Err here.

@@ -170,6 +174,10 @@ func SetRootDir(rootdir string) {
SnapStateFile = filepath.Join(rootdir, snappyDir, "state.json")
+ SnapCacheDir = filepath.Join(rootdir, snappyDir, "cache")
@zyga

zyga Aug 30, 2017

Contributor

Why not /var/cache/snapd instead?

@chipaca

chipaca Aug 30, 2017

Member

not writable on core

@pedronis

pedronis Sep 1, 2017

Contributor

should we change that?

@chipaca

chipaca Sep 1, 2017

Member

I don't see the current approach to be a problem, tbh.

@@ -537,6 +555,32 @@ func (m *SnapManager) ensureRefreshes() error {
return err
}
+// ensureMiscRefresh ensures that we refresh the miscellaneous static
+// data periodically
@zyga

zyga Aug 30, 2017

Contributor

Missing trailing dot.

+}
+
+func refreshNames(aStore StoreService) error {
+ snapCmds, err := aStore.SnapCommands()
@zyga

zyga Aug 30, 2017

Contributor

Should we perhaps stream this instead of buffering it in memory. It may have essentially any size.

+ fmt.Fprintln(buf, name)
+ }
+
+ return osutil.AtomicWriteFile(dirs.SnapNamesFile, buf.Bytes(), 0644, 0)
@zyga

zyga Aug 30, 2017

Contributor

How about having an atomic buffered disk file write API that doesn't need in-memory store of arbitrarily large buffer?

@chipaca

chipaca Aug 30, 2017

Member

I think we do want to move to streaming apis everywhere, but it's a chunk of work

Member

chipaca commented Aug 30, 2017

@zyga, to address your overall concerns, yes we can ask the store to send them sorted (and I'm in the process of doing so), and we can drop the sorting once that is deployed. And yes we should have streaming versions of these things (in particular @mvo5 has needed an atomic rename of a io.writer before, i think). Do you consider these to be blockers?

Member

chipaca commented Aug 30, 2017

@zyga also, note that the file we write is rather different from what we get from the store (it doesn't stop it being streamable, but it isn't just a "hand over response.Body to osutil.AtomicWrite)

@chipaca chipaca removed the Blocked label Aug 31, 2017

looks reasonable, some comments, I wish the SetRootDir where separate :/

@@ -170,6 +174,10 @@ func SetRootDir(rootdir string) {
SnapStateFile = filepath.Join(rootdir, snappyDir, "state.json")
+ SnapCacheDir = filepath.Join(rootdir, snappyDir, "cache")
@zyga

zyga Aug 30, 2017

Contributor

Why not /var/cache/snapd instead?

@chipaca

chipaca Aug 30, 2017

Member

not writable on core

@pedronis

pedronis Sep 1, 2017

Contributor

should we change that?

@chipaca

chipaca Sep 1, 2017

Member

I don't see the current approach to be a problem, tbh.

+ n++
+ }
+ bufsize += n
+ sort.Strings(names)
@pedronis

pedronis Sep 1, 2017

Contributor

is this sorting still needed?

@chipaca

chipaca Sep 1, 2017

Member

until it's sorted at the other end, yes

+ return nil, fmt.Errorf("received an unexpected content type (%q) when trying to retrieve the commands via %q", ct, resp.Request.URL)
+ }
+
+ cmds := make(map[string][]string, len(cmdsData.Payload.Packages))
@pedronis

pedronis Sep 1, 2017

Contributor

do we need a TODO here about the fact that at moment we get only snap names?

@chipaca

chipaca Sep 1, 2017

Member

I'll add it (although we also get aliases right now)

Contributor

pedronis commented Sep 1, 2017

yes, refreshMisc is not a great name

@@ -69,6 +69,7 @@ const defaultRefreshSchedule = "00:00-04:59/5:00-10:59/11:00-16:59/17:00-23:59"
// overridden in the tests
var errtrackerReport = errtracker.Report
+var miscRefreshDelay = 24 * time.Hour
@pedronis

pedronis Sep 1, 2017

Contributor

this probably merits its own comment/explanation, also perhaps s/misc/catalogs/ or something along those lines?

@chipaca chipaca closed this Sep 1, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment