Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Try to download Z3 5 times instead of just once #1835

Merged
merged 10 commits into from
Feb 17, 2022

Conversation

MikaelMayer
Copy link
Member

Problem
In one fo my last PR, the CI was not able to download Z3 in only 1 of the 15 instances.
This happens regularly (like, 1 time over 5) over an entire CI. Assuming that there are 10 runs every day, I don't want this problem to happen more than once a year.

Solution
With 5 tries, this problem will happen only 1 time every 3125, so that should get us covered.

Original exception

The date in version.cs does not agree with today's date: 40216 vs. 40215
12
The version number in version.cs does not agree with the given version: 0.0.0 vs. 3.4.1
13
Creating release files for release "0.0.0-CI" and internal version information: 3.4.1.40215
14
* Finding and downloading Z3 releases
15
  - Getting information about latest release
16
    + Selecting z3-4.8.5-x64-debian-8.11.zip (35.66MB, 35658053)
17
    + Selecting z3-4.8.5-x64-osx-10.14.2.zip (30.06MB, 30064624)
18
    + Selecting z3-4.8.5-x64-ubuntu-14.04.zip (34.44MB, 34441090)
19
    + Selecting z3-4.8.5-x64-ubuntu-16.04.zip (36.22MB, 36216249)
20
    + Selecting z3-4.8.5-x64-win.zip (14.11MB, 14112529)
21
    + Rejecting z3-4.8.5-x86-win.zip
22
  - Downloading 1 z3 archives
23
Traceback (most recent call last):
24
  File "/Users/runner/work/dafny/dafny/dafny/Scripts/package.py", line 302, in <module>
25
    main()
26
    + z3-4.8.5-x64-osx-10.14.2.zip: downloading 30.06MB... 
27
  File "/Users/runner/work/dafny/dafny/dafny/Scripts/package.py", line 296, in main
28
    download(releases)
29
  File "/Users/runner/work/dafny/dafny/dafny/Scripts/package.py", line 223, in download
30
    release.download()
31
  File "/Users/runner/work/dafny/dafny/dafny/Scripts/package.py", line 111, in download
32
    writer.write(reader.read())
33
  File "/Users/runner/hostedtoolcache/Python/3.10.2/x64/lib/python3.10/http/client.py", line 481, in read
34
    s = self._safe_read(self.length)
35
  File "/Users/runner/hostedtoolcache/Python/3.10.2/x64/lib/python3.10/http/client.py", line 632, in _safe_read
36
    raise IncompleteRead(data, amt-len(data))
37
http.client.IncompleteRead: IncompleteRead(8388608 bytes read, 21676016 more expected)
38

@MikaelMayer MikaelMayer self-assigned this Feb 17, 2022
with request.urlopen(self.url) as reader:
with open(self.z3_zip, mode="wb") as writer:
writer.write(reader.read())
maxTries = 5
Copy link
Collaborator

Choose a reason for hiding this comment

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

At this point it might make sense to put this into a global constant. (With L132)

Copy link
Collaborator

Choose a reason for hiding this comment

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

But I do see the argument that we are dealing with events of a different nature here.

Scripts/package.py Show resolved Hide resolved
with open(self.z3_zip, mode="wb") as writer:
writer.write(reader.read())
maxTries = 5
while maxTries > 0:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might be cleaner in a for loop.

Copy link
Member Author

Choose a reason for hiding this comment

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

It still have to check for the last bound to reraise the exception, but I converted it to a for loop with a global constant

@fabiomadge fabiomadge changed the title chore:Try to download 5 times Z3 instead of just once chore: Try to download 5 times Z3 instead of just once Feb 17, 2022
@fabiomadge fabiomadge changed the title chore: Try to download 5 times Z3 instead of just once chore: Try to download Z3 5 times instead of just once Feb 17, 2022
maxTries -= 1
if maxTries == 0:
raise
continue
Copy link
Member

Choose a reason for hiding this comment

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

continue is not needed here

try:
with request.urlopen(self.url) as reader:
with open(self.z3_zip, mode="wb") as writer:
writer.write(reader.read())
Copy link
Member

Choose a reason for hiding this comment

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

urllib.request.urlretrieve instead of write(read())

Copy link
Member Author

Choose a reason for hiding this comment

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

The documentation says your particular method has been deprecated.
Moreover, I don't feel comfortable editing what already worked before - for example, it might work today, but if the cache is outdated tomorrow and it does not work, we might not see the error
If you feel comfortable, feel free to contribute to this PR.

Copy link
Member

Choose a reason for hiding this comment

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

The documentation says your particular method has been deprecated.

Not quite :) But I agree with you that it's fine to keep the current code if it's working (I wrote it, but I'm not sure why I didn't use shutil.copyfileobj or urlretrieve ^^)

@atomb
Copy link
Member

atomb commented Feb 17, 2022

I wonder whether it might make sense to maintain a mapping from OS name to release files directly in this script, rather than asking the GitHub API for it. Something like {"linux": "https://github.com/Z3Prover/z3/releases/download/Z3-4.8.5/z3-4.8.5-x64-debian-8.11.zip", ... }. It would mean a slightly larger chunk of data to keep up-to-date (rather than just a version number) but would reduce the number of round trips to GitHub which should speed it up and hopefully make it less likely to fail. Including that in addition to the retry logic you've already added could be even better.

@fabiomadge
Copy link
Collaborator

I wonder whether it might make sense to maintain a mapping from OS name to release files directly in this script, rather than asking the GitHub API for it. Something like {"linux": "https://github.com/Z3Prover/z3/releases/download/Z3-4.8.5/z3-4.8.5-x64-debian-8.11.zip", ... }. It would mean a slightly larger chunk of data to keep up-to-date (rather than just a version number) but would reduce the number of round trips to GitHub which should speed it up and hopefully make it less likely to fail. Including that in addition to the retry logic you've already added could be even better.

Let's try that in a separate PR if the issue persists.

@robin-aws
Copy link
Member

Sanity check: we can't use the versions of Z3 in nuget can we? What if we eventually move to newer versions?

@fabiomadge
Copy link
Collaborator

Sanity check: we can't use the versions of Z3 in nuget can we? What if we eventually move to newer versions?

We're building the release for multiple platforms. I don't think that's a service nuget provides.

fabiomadge
fabiomadge previously approved these changes Feb 17, 2022
with open(self.z3_zip, mode="wb") as writer:
writer.write(reader.read())
flush("done!")
except (http.client.IncompleteRead) as e:
Copy link
Member

Choose a reason for hiding this comment

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

No need for parentheses here

except (http.client.IncompleteRead) as e:
if currentAttempt == Z3_MAX_DOWNLOAD_ATTEMPTS - 1:
raise

Copy link
Member

@cpitclaudel cpitclaudel Feb 17, 2022

Choose a reason for hiding this comment

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

FWIW, an alternative way to write this kind of loop in Python is something like this (for-else)

err = None
for _ in range(NRETRIES):
    try:
        do_something()
        break
    except SomeException as e:
        err = e
else:
    raise err

fabiomadge
fabiomadge previously approved these changes Feb 17, 2022
RELEASE_NOTES.md Outdated Show resolved Hide resolved
Co-authored-by: Fabio Madge <[email protected]>
@MikaelMayer MikaelMayer merged commit 6252b08 into master Feb 17, 2022
@MikaelMayer MikaelMayer deleted the chore-robustness-in-installation branch February 17, 2022 22:18
@keyboardDrummer
Copy link
Member

Sanity check: we can't use the versions of Z3 in nuget can we? What if we eventually move to newer versions?

We're building the release for multiple platforms. I don't think that's a service nuget provides.

I believe the Z3 NuGet package contains binaries for different platforms, but to use it you have to use a C# API instead of the textual SMTLib2 API that Boogie is using now, so that'd be significant updates to Boogie to support using that new API.

@fabiomadge
Copy link
Collaborator

fabiomadge commented Feb 18, 2022

Yes, looks like all you get is libz3, but for different architectures.

fabiomadge added a commit that referenced this pull request Mar 7, 2022
* returns, ifs, and blocks

* fix the retry logic added a short while back in #1835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants