Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Serialize downloads #1031

Merged
merged 6 commits into from
Dec 13, 2018
Merged

Serialize downloads #1031

merged 6 commits into from
Dec 13, 2018

Conversation

OYTIS
Copy link
Contributor

@OYTIS OYTIS commented Dec 11, 2018

No description provided.

Anton Gerasimov added 2 commits December 11, 2018 11:26
Parallel writes to SQLite database over-complicate the code
for little benefit

Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
@pattivacek
Copy link
Collaborator

Before we merge this, we should double-check that no one is relying on something that we will break. I'll look into that. Conceptually, though, I have been convinced that this is the right way forward.

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 11, 2018

@patrickvacek What do you mean? Right now we only have sachertorte project as an external user, and I'm pretty sure it's fine.

@pattivacek
Copy link
Collaborator

@OYTIS I want to make sure that no one else was expecting this mis-feature. :)

Also, could you try adding the feature to implicitly pause when calling shutdown via the API?

@codecov-io
Copy link

codecov-io commented Dec 11, 2018

Codecov Report

Merging #1031 into master will increase coverage by 0.02%.
The diff coverage is 81.81%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1031      +/-   ##
==========================================
+ Coverage   82.29%   82.31%   +0.02%     
==========================================
  Files         189      189              
  Lines       13655    13663       +8     
==========================================
+ Hits        11237    11247      +10     
+ Misses       2418     2416       -2
Impacted Files Coverage Δ
src/libaktualizr/primary/sotauptaneclient.cc 82.33% <100%> (-0.06%) ⬇️
...libaktualizr/package_manager/debianmanager_test.cc 100% <100%> (ø) ⬆️
src/libaktualizr/storage/storage_common_test.cc 98.18% <100%> (+0.04%) ⬆️
src/libaktualizr/storage/sqlstorage.cc 74.96% <63.15%> (-1.22%) ⬇️
src/libaktualizr/uptane/fetcher.cc 97.16% <87.5%> (-0.81%) ⬇️
src/libaktualizr/primary/reportqueue_test.cc 97.29% <0%> (+1.35%) ⬆️
src/libaktualizr/package_manager/ostreemanager.cc 54.7% <0%> (+3.84%) ⬆️

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 16b3ecb...c0e57f6. Read the comment docs.

@pattivacek
Copy link
Collaborator

Do you think it is reasonable to actually measure the download times with and without this change? I believe this should be an improvement, and I also know it will make things easier to maintain, but it's worth knowing what effects this has in practice.

@eu-siemann
Copy link
Contributor

@patrickvacek Yes, makes sense to measure. We know the current speed already, it's about 64 kbit/s. When this PR is merged I'll create another one with updated fetcher test, which measures the speed.

That should increase the download speed and reduce the wear load.

Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
@lbonn
Copy link
Contributor

lbonn commented Dec 11, 2018

Some tests are failing in the debian package manager case (which is pretty obsolete, but still...)

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 11, 2018

@lbonn Yes, it uses WHandle directly, fixed that.

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 11, 2018

@eu-smirnov Thank you, I was wondering how this should be tested.

Copy link
Collaborator

@pattivacek pattivacek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, and I'm curious to see how it works in action!

}
// It is possible for the PutManifestComplete to come before we get the
// InstallTargetComplete depending on the threading, so check for both.
if (allcomplete_FullMultipleSecondaries && complete_FullMultipleSecondaries == 2 &&
manifest_FullMultipleSecondaries) {
LOG_ERROR << "SETVALUE";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this leftover from testing or intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrickvacek That's debug output, thanks, I'll remove it.

}

~SQLTargetWHandle() override {
if (!closed_) {
LOG_WARNING << "Handle for file " << target_.filename() << " has not been committed or aborted, forcing abort";
db_.commitTransaction();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't notice it before, but why do we call commit here? We want to abort the transaction, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not quite sure actually. My idea was that if we don't abort explicitly then we probably want to save what we've already downloaded.
By the way, maybe we don't need explicit pause from Aktualizr::Shutdown in the end, @patrickvacek's commit confused me somewhat. Just need to add the test that the file really gets committed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@OYTIS good call, actually! I overlooked the commit in the destructor, which is actually an even better solution than the implicit call to pause.

@eu-siemann
Copy link
Contributor

I locally rebased my changes to fetcher/fetcher test to measure the download speed. It certainly got much better, up to 4 Mbit/s from previous 64 kbit/s.
For some reason, speed drops significantly after pause/resume cycle. I'll look into that.

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 12, 2018

@eu-smirnov Could you please share the rebased code on some branch? I might try to debug that as well.

Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
@eu-siemann
Copy link
Contributor

@OYTIS Sure, pushed it to fix/fetcher-test.

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 12, 2018

@eu-smirnov Thanks!

@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 13, 2018

OK, as we've found, transactions around sqlite_blob_* API calls are not needed at all. As @eu-smirnov suggested, we'll rewrite it to keep the blob open over wfeed operations, but the database schema needs to be reworked for that.

This PR already improves the speed significantly, but we can do better by keeping the blob open. Let's merge this one (after @eu-smirnov tries it with his #1032), and make the rest of improvements after that.

Blob handler is now kept open between the calls to wfeed

Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
@OYTIS
Copy link
Contributor Author

OYTIS commented Dec 13, 2018

OK, so it was relatively simple, no schema redesign needed. Let's rebase it on @eu-smirnov's PR and measure the speed now.

@pattivacek
Copy link
Collaborator

This looks fine to me, but I'd prefer someone with better SQL knowledge to sign off if possible.

I want to make sure that no one else was expecting this mis-feature.

It doesn't sound like anyone will be upset if we remove it, especially since the numbers clearly demonstrate that this is a major improvement. (Or more accurately, this retracts what we now know to have been a downgrade, and it appears to moderately improve upon what we had before that.)

int err = statement.step();
if (err != SQLITE_DONE) {
LOG_ERROR << "Could not save size in db: " << db_.errmsg();
throw StorageTargetWHandle::WriteError("could not update sise of " + target_.filename() + " in sql storage");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "size"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

if (blob_ != nullptr) {
sqlite3_blob_close(blob_);
blob_ = nullptr;
auto statement = db_.prepareStatement<int64_t, int64_t>("update target_images SET real_size = ? where rowid = ?;",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really small, but we upper case sql operations everywhere else, would be nice to keep a consistent style for easy grepping etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will fix.

@lbonn
Copy link
Contributor

lbonn commented Dec 13, 2018

Looks good. I don't know if I really have more knowledge of sql but it seems to be consistent with the approached we agreed with.

@eu-siemann
Copy link
Contributor

Awesome, now it takes 7 seconds to download a 100 MB file, which is around 120 Mbit/s or ~2000 times faster. Let's merge it, guys :)

@pattivacek
Copy link
Collaborator

For some reason, speed drops significantly after pause/resume cycle. I'll look into that.

@eu-smirnov Is this still happening? My guess is no, but just wanted to be sure...

@eu-siemann
Copy link
Contributor

@patrickvacek nope, that one is also seems to be fixed

Signed-off-by: Anton Gerasimov <anton.gerasimov@here.com>
@OYTIS OYTIS merged commit b5d105c into master Dec 13, 2018
@lbonn lbonn deleted the bugfix/serializedownloads branch December 13, 2018 16:08
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants