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

Unified object provider backend #911

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
95f0438
Binary cache: async push_success
autoantwort Feb 15, 2023
42ec787
Binary cache: async push_success
autoantwort Feb 15, 2023
0b1d87f
WIP Current state
autoantwort Feb 16, 2023
2d04507
More or less complete implementation
autoantwort Feb 22, 2023
7e1e57e
Supress warnings
autoantwort Feb 22, 2023
e4ed60e
Fix FileObjectProvider
autoantwort Feb 22, 2023
2e71ca8
enable_if 💘
autoantwort Feb 22, 2023
a4200ec
Merge branch 'main' into unified-object-provider-backend
autoantwort Feb 25, 2023
4bbc46a
Clear package dir before unzipping
autoantwort Feb 25, 2023
9d999d8
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Feb 28, 2023
e0ba623
Merge branch 'main' into unified-object-provider-backend
autoantwort Feb 28, 2023
163d9cd
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 2, 2023
2a54205
Apply suggestions from code review
autoantwort Mar 2, 2023
0912655
Adapt code review
autoantwort Mar 2, 2023
5d7288c
Update src/vcpkg/binarycaching.cpp
autoantwort Mar 2, 2023
10189ac
Adapt code review
autoantwort Mar 2, 2023
2567607
Remove unnecessary actions_to_push_notifier.notify_all()
autoantwort Mar 2, 2023
ecdd000
Prevent deadlock and don't be on the crtl+c path
autoantwort Mar 2, 2023
8e7ae61
Add and use BGMessageSink to print IBinaryProvider::push_success mess…
autoantwort Mar 3, 2023
850d7c9
Restore old upload message
autoantwort Mar 3, 2023
548be38
Don't join yourself
autoantwort Mar 4, 2023
6dbbf06
Print messages about remaining packages to upload
autoantwort Mar 4, 2023
74b86fd
Localization
autoantwort Mar 5, 2023
5171d3e
Improve messages
autoantwort Mar 5, 2023
d69ed8f
No singleton and explicit calls to wait_for_async_complete()
autoantwort Mar 5, 2023
2df42d5
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 8, 2023
5f1786e
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 10, 2023
6f5a7ba
Merge branch 'feature/async-binary-cache-push-success' into unified-o…
autoantwort Mar 13, 2023
93303c3
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 16, 2023
8a26c8b
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 19, 2023
aa7e52f
Merge branch 'main' into feature/async-binary-cache-push-success
autoantwort Mar 22, 2023
d46a4d6
Apply code review
autoantwort Mar 22, 2023
b045c64
Broken: Merge branch 'feature/async-binary-cache-push-success' into u…
autoantwort Mar 22, 2023
104758f
Migrate GHABinaryProvider to ISingleObjectProvider
autoantwort Mar 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions azure-pipelines/pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ jobs:
displayName: 'Rush install, build and test vcpkg-artifacts'
- bash: |
cmake '-DCMAKE_CXX_FLAGS=-fprofile-arcs -ftest-coverage -fPIC -O0 -fsanitize=undefined -fsanitize=address' -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_BENCHMARKING=ON -DVCPKG_BUILD_FUZZING=ON -B build.amd64.debug
make -j 2 -C build.amd64.debug
make -j 2 -C build.amd64.debug vcpkg
displayName: "Build vcpkg with CMake"
failOnStderr: true
- bash: build.amd64.debug/vcpkg-test
displayName: 'Run vcpkg tests'
env:
VCPKG_ROOT: UNIT_TESTS_SHOULD_NOT_USE_VCPKG_ROOT
#- bash: build.amd64.debug/vcpkg-test
# displayName: 'Run vcpkg tests'
# env:
# VCPKG_ROOT: UNIT_TESTS_SHOULD_NOT_USE_VCPKG_ROOT
Comment on lines +47 to +53
Copy link
Member

Choose a reason for hiding this comment

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

Don't think you meant to do that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The tests do not build currently (expected) but I want to run the e2e tests in the ci, so I have to disable the unit tests temporarily.

- task: PowerShell@2
displayName: 'Run vcpkg end-to-end tests'
inputs:
Expand Down Expand Up @@ -92,11 +92,11 @@ jobs:
displayName: "Clone vcpkg repo to serve as root"
- bash: |
cmake '-DCMAKE_CXX_FLAGS=-fsanitize=undefined -fsanitize=address' -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_BENCHMARKING=ON -DVCPKG_BUILD_FUZZING=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 -B build.amd64.debug
make -j 2 -C build.amd64.debug
make -j 2 -C build.amd64.debug vcpkg
displayName: "Build vcpkg with CMake"
failOnStderr: true
- bash: build.amd64.debug/vcpkg-test
displayName: 'Run vcpkg tests'
#- bash: build.amd64.debug/vcpkg-test
# displayName: 'Run vcpkg tests'
- bash: brew install pkg-config
displayName: 'Install pkgconfig'
- task: PowerShell@2
Expand Down Expand Up @@ -154,7 +154,7 @@ jobs:
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=x86 -host_arch=x86
rmdir /s /q build.x86.debug > nul 2> nul
cmake.exe -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DVCPKG_DEVELOPMENT_WARNINGS=ON -DVCPKG_WARNINGS_AS_ERRORS=ON -DVCPKG_BUILD_BENCHMARKING=ON -DVCPKG_BUILD_FUZZING=ON -DVCPKG_BUILD_TLS12_DOWNLOADER=ON -DVCPKG_ARTIFACTS_DEVELOPMENT=ON -B build.x86.debug
ninja.exe -C build.x86.debug all generate-message-map
ninja.exe -C build.x86.debug vcpkg generate-message-map
failOnStderr: true
- task: CodeQL3000Finalize@0
displayName: 'CodeQL Finalize'
Expand All @@ -170,11 +170,11 @@ jobs:
inputs:
PathtoPublish: '$(DiffFile)'
ArtifactName: 'format.diff'
- script: build.x86.debug\vcpkg-test.exe
displayName: "Run vcpkg tests"
failOnStderr: true
env:
VCPKG_ROOT: UNIT_TESTS_SHOULD_NOT_USE_VCPKG_ROOT
#- script: build.x86.debug\vcpkg-test.exe
# displayName: "Run vcpkg tests"
# failOnStderr: true
# env:
# VCPKG_ROOT: UNIT_TESTS_SHOULD_NOT_USE_VCPKG_ROOT
- task: PowerShell@2
displayName: 'Run vcpkg end-to-end tests'
inputs:
Expand Down
27 changes: 12 additions & 15 deletions include/vcpkg/base/downloads.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

#include <vcpkg/base/fwd/downloads.h>
#include <vcpkg/base/fwd/messages.h>
#include <vcpkg/base/fwd/optional.h>

#include <vcpkg/base/expected.h>
#include <vcpkg/base/files.h>
#include <vcpkg/base/optional.h>
#include <vcpkg/base/span.h>

#include <vcpkg/binarycaching.h>
#include <vcpkg/tools.h>

#include <string>
#include <vector>

Expand Down Expand Up @@ -41,40 +45,33 @@ namespace vcpkg
StringView request = "PUT");
std::vector<int> url_heads(View<std::string> urls, View<std::string> headers, View<std::string> secrets);

struct DownloadManagerConfig
{
Optional<std::string> m_read_url_template;
std::vector<std::string> m_read_headers;
Optional<std::string> m_write_url_template;
std::vector<std::string> m_write_headers;
std::vector<std::string> m_secrets;
bool m_block_origin = false;
Optional<std::string> m_script;
};

// Handles downloading and uploading to a content addressable mirror
struct DownloadManager
{
DownloadManager() = default;
explicit DownloadManager(const DownloadManagerConfig& config) : m_config(config) { }
explicit DownloadManager(DownloadManagerConfig&& config) : m_config(std::move(config)) { }

void download_file(Filesystem& fs,
void download_file(Optional<const ToolCache&> tool_cache,
Filesystem& fs,
const std::string& url,
View<std::string> headers,
const Path& download_path,
const Optional<std::string>& sha512,
MessageSink& progress_sink) const;

// Returns url that was successfully downloaded from
std::string download_file(Filesystem& fs,
std::string download_file(Optional<const ToolCache&> tool_cache,
Filesystem& fs,
View<std::string> urls,
View<std::string> headers,
const Path& download_path,
const Optional<std::string>& sha512,
MessageSink& progress_sink) const;

ExpectedL<int> put_file_to_mirror(const Filesystem& fs, const Path& file_to_put, StringView sha512) const;
ExpectedL<int> put_file_to_mirror(Optional<const ToolCache&> tool_cache,
const Filesystem&,
const Path& file_to_put,
StringView sha512) const;

private:
DownloadManagerConfig m_config;
Expand Down
1 change: 1 addition & 0 deletions include/vcpkg/base/fwd/message_sinks.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ namespace vcpkg

struct FileSink;
struct CombiningSink;
struct BGMessageSink;
}
2 changes: 2 additions & 0 deletions include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2540,6 +2540,7 @@ DECLARE_MESSAGE(UploadingBinariesUsingVendor,
(msg::spec, msg::vendor, msg::path),
"",
"Uploading binaries for '{spec}' using '{vendor}' \"{path}\".")
DECLARE_MESSAGE(UploadRemainingPackages, (msg::count), "", "Upload remaining {count} package(s)")
DECLARE_MESSAGE(UseEnvVar,
(msg::env_var),
"An example of env_var is \"HTTP(S)_PROXY\""
Expand Down Expand Up @@ -2765,6 +2766,7 @@ DECLARE_MESSAGE(VSExaminedPaths, (), "", "The following paths were examined for
DECLARE_MESSAGE(VSNoInstances, (), "", "Could not locate a complete Visual Studio instance")
DECLARE_MESSAGE(WaitingForChildrenToExit, (), "", "Waiting for child processes to exit...")
DECLARE_MESSAGE(WaitingToTakeFilesystemLock, (msg::path), "", "waiting to take filesystem lock on {path}...")
DECLARE_MESSAGE(WaitUntilPackagesUploaded, (msg::count), "", "Wait until the remaining packages ({count}) are uploaded")
DECLARE_MESSAGE(WarningMessage, (), "", "warning: ")
DECLARE_MESSAGE(WarningMessageMustUsePrintWarning,
(msg::value),
Expand Down
28 changes: 28 additions & 0 deletions include/vcpkg/base/message_sinks.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <vcpkg/base/files.h>
#include <vcpkg/base/messages.h>

#include <mutex>

namespace vcpkg
{

Expand Down Expand Up @@ -87,4 +89,30 @@ namespace vcpkg
CombiningSink(MessageSink& first, MessageSink& second) : m_first(first), m_second(second) { }
void print(Color c, StringView sv) override;
};

struct BGMessageSink : MessageSink
{
BGMessageSink(MessageSink& out_sink) : out_sink(out_sink) { }
~BGMessageSink() { publish_directly_to_out_sink(); }
// must be called from producer
void print(Color c, StringView sv) override;

// must be called from consumer (synchronizer of out)
void print_published();

void publish_directly_to_out_sink();

private:
MessageSink& out_sink;

std::mutex m_lock;
// guarded by m_lock
std::vector<std::pair<Color, std::string>> m_published;
// buffers messages until newline is reached
// guarded by m_print_directly_lock
std::vector<std::pair<Color, std::string>> m_unpublished;

std::mutex m_print_directly_lock;
bool m_print_directly_to_out_sink = false;
};
}
20 changes: 16 additions & 4 deletions include/vcpkg/base/optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,22 @@ namespace vcpkg
{
constexpr OptionalStorage() noexcept : m_t(nullptr) { }
constexpr OptionalStorage(const T& t) : m_t(&t) { }
constexpr OptionalStorage(const Optional<T>& t) : m_t(t.get()) { }
constexpr OptionalStorage(const Optional<const T>& t) : m_t(t.get()) { }
constexpr OptionalStorage(Optional<T>&& t) = delete;
constexpr OptionalStorage(Optional<const T>&& t) = delete;
template<typename U,
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain why this change was necessary? Optional stores T, not T*, so whether T is abstract should not matter. (is_abstract is almost never the right trait; usually people are looking for is_constructible or similar....)

Copy link
Contributor

Choose a reason for hiding this comment

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

From Discord:

the problem is OptionalStorage<const U&, B> wanting a Optional<U> and U = Interface due to deduction
(https://godbolt.org/z/4Gf4e7PKT uncomment line 295 for the error)

Copy link
Contributor

Choose a reason for hiding this comment

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

I also don't see how you would use is_constructible here since the input args are unknown. U might be constructible given the correct args (which we don't know given the context) however if U is an abstract class Optional<U> can simply not exist.

Copy link
Contributor

Choose a reason for hiding this comment

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

So the question is if the following is a valid expressions: T a; independent of the question if it can be constructed or not.

Copy link
Member

@BillyONeal BillyONeal Mar 3, 2023

Choose a reason for hiding this comment

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

Oh, I see, the problem is that given Optional<const T&> we try to form Optional<T> due to:

 template<class T, bool B>
 struct OptionalStorage<const T&, B>
 {
     // T doesn't have the 'const&' here
     constexpr OptionalStorage(const Optional<T>& t) : m_t(t.get()) { }
 };

I believe the correct fix is just to put the const& back on rather than this SFINAE. That is, in struct OptionalStorage<T&, B>,

constexpr OptionalStorage(Optional<T>& t) : m_t(t.get()) { }

should be

constexpr OptionalStorage(Optional<T&>& t) : m_t(t.get()) { }

and in struct OptionalStorage<const T&, B>,

constexpr OptionalStorage(const Optional<T>& t) : m_t(t.get()) { }
constexpr OptionalStorage(const Optional<const T>& t) : m_t(t.get()) { }
constexpr OptionalStorage(Optional<T>&& t) = delete;
constexpr OptionalStorage(Optional<const T>&& t) = delete;

should just be

constexpr OptionalStorage(const Optional<const T&>& t) : m_t(t.get()) { }

std::enable_if_t<std::is_same_v<T, std::decay_t<U>> && !std::is_abstract_v<T>, int*> = nullptr>
constexpr OptionalStorage(const Optional<U>& t) : m_t(t.get())
{
}
template<typename U,
std::enable_if_t<std::is_same_v<T, std::decay_t<U>> && !std::is_abstract_v<T>, int*> = nullptr>
constexpr OptionalStorage(const Optional<const U>& t) : m_t(t.get())
{
}
template<typename U,
std::enable_if_t<std::is_same_v<T, std::decay_t<U>> && !std::is_abstract_v<T>, int*> = nullptr>
constexpr OptionalStorage(Optional<U>&& t) = delete;
template<typename U,
std::enable_if_t<std::is_same_v<T, std::decay_t<U>> && !std::is_abstract_v<T>, int*> = nullptr>
constexpr OptionalStorage(Optional<const U>&& t) = delete;

constexpr bool has_value() const { return m_t != nullptr; }

Expand Down
Loading