master
h 77 lines 3.48 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 BuildImageCallback.h
8
9 Abstract:
10
11 This file contains the BuildImageCallback definition
12
13 --*/
14 #pragma once
15 #include "ContainerModel.h"
16 #include "Terminal.h"
17 #include "SessionService.h"
18 #include "VTSupport.h"
19 #include <deque>
20 #include <map>
21
22 namespace wsl::windows::wslc::services {
23 class DECLSPEC_UUID("3EDD5DBF-CA6C-4CF7-923A-AD94B6A732E5") BuildImageCallback
24 : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IProgressCallback, IFastRundown>
25 {
26 public:
27 // The cancel event handle must remain valid for the lifetime of this callback.
28 // Mode selects the rendering style (Auto is expected to already be resolved to Tty/Plain by the caller).
29 BuildImageCallback(Terminal& terminal, HANDLE cancelEvent, bool verbose, models::ProgressMode mode = models::ProgressMode::Tty) :
30 m_terminal(terminal), m_verbose(verbose), m_cancelEvent(cancelEvent), m_mode(mode), m_color(mode == models::ProgressMode::Tty)
31 {
32 }
33 ~BuildImageCallback();
34 HRESULT OnProgress(LPCSTR status, LPCSTR id, ULONGLONG current, ULONGLONG total) override;
35
36 private:
37 static constexpr int c_maxDisplayLines = 16;
38 static constexpr auto c_redrawInterval = std::chrono::milliseconds(50);
39 static constexpr size_t c_maxAllLinesBytes = 10 * 1024 * 1024; // 10 MiB cap on retained log output for error replay.
40
41 void CollapseWindow();
42 void Redraw();
43 void RedrawIfNeeded();
44 bool IsCancelled() const;
45 // Appends a log chunk to the error-replay buffer, enforcing the retained-bytes cap.
46 void CaptureForReplay(std::string_view text);
47 // Returns the sequence when color is enabled for this callback, else an empty (no-op) sequence so
48 // the Terminal emits nothing for it. Used to strip color from the sequences emitted in Tty mode.
49 const wsl::windows::common::vt::Sequence& Color(const wsl::windows::common::vt::Sequence& sequence) const;
50
51 Terminal& m_terminal;
52 const bool m_verbose;
53 const HANDLE m_cancelEvent;
54 const models::ProgressMode m_mode;
55 const bool m_color;
56 // In-place rendering (cursor moves, erases and redraws) is only used for Tty mode on a VT
57 // console. Plain mode appends one line at a time so its output carries no cursor control and
58 // is identical whether it goes to a console or a redirected stream.
59 bool m_renderInPlace = m_mode == models::ProgressMode::Tty && m_terminal.IsVTEnabled(Terminal::Level::Info);
60 std::deque<std::string> m_lines;
61 // Each entry already contains the trailing newline so the bytes match what's replayed.
62 // TODO: Track logs per step so the destructor can replay only the failing step's
63 // logs on error, rather than every line captured during the build.
64 std::deque<std::string> m_allLines;
65 size_t m_allLinesBytes = 0;
66 std::string m_pendingLine;
67 int m_displayedLines = 0;
68 std::chrono::steady_clock::time_point m_lastRedraw{};
69 // Per-entry pull progress lines, keyed by entry id. Updated in place by Redraw. std::map so order is consistent.
70 std::map<std::string, std::string> m_pullLines;
71 // Reused across Redraw() calls so the backing allocation grows to the high-water
72 // mark and is then reused rather than re-allocated every frame.
73 std::wstring m_frameBuffer;
74 // Captured at construction so the destructor can detect destruction during exception unwinding.
75 int m_uncaughtExceptions = std::uncaught_exceptions();
76 };
77 } // namespace wsl::windows::wslc::services