master
h 88 lines 3.21 KB
Raw
1 // Copyright (C) Microsoft Corporation. All rights reserved.
2
3 #pragma once
4
5 #include <chrono>
6 #include <condition_variable>
7 #include <cstdint>
8 #include <deque>
9 #include <map>
10 #include <mutex>
11 #include <optional>
12 #include <string>
13 #include <vector>
14 #include "wslc.h"
15 #include "wslc_schema.h"
16
17 namespace wsl::windows::service::wslc {
18
19 class WSLCSession;
20
21 class EventStore
22 {
23 public:
24 static constexpr size_t c_eventRingCapacity = 256;
25
26 void Record(std::string&& Type, std::string&& Action, const std::string& ActorId, std::map<std::string, std::string> ActorAttributes, std::int64_t Time) noexcept;
27
28 Microsoft::WRL::ComPtr<IWSLCEventStream> CreateStream(
29 Microsoft::WRL::ComPtr<WSLCSession> Session, int64_t SinceTime, int64_t UntilTime, std::map<std::string, std::vector<std::string>> Filters);
30
31 // Returns the next event at or after SequenceNumber that falls within [Since, Until) and matches
32 // Filters, advancing SequenceNumber past it. A nullopt SequenceNumber starts a fresh reader at the
33 // oldest buffered event (no gap is reported). If the reader has since fallen behind the ring,
34 // resyncs SequenceNumber to the oldest buffered event and throws WSLC_E_EVENTS_LOST. Returns
35 // nullopt once the Until window has closed.
36 std::optional<wsl::windows::common::wslc_schema::Event> Get(
37 std::optional<uint64_t>& SequenceNumber,
38 std::optional<std::chrono::sys_seconds> Since,
39 std::optional<std::chrono::sys_seconds> Until,
40 const std::map<std::string, std::vector<std::string>>& Filters);
41
42 void OnSessionTerminating();
43
44 private:
45 void Append(wsl::windows::common::wslc_schema::Event Event);
46
47 // Blocks until the event at SequenceNumber is buffered, its slot is evicted, or the session
48 // terminates. Returns false only when Until elapsed with no event ready. Throws E_ABORT if the
49 // session terminated while waiting.
50 bool WaitForEvent(std::unique_lock<std::mutex>& Lock, uint64_t SequenceNumber, std::optional<std::chrono::sys_seconds> Until);
51
52 std::optional<wsl::windows::common::wslc_schema::Event> GetLockHeld(uint64_t SequenceNumber);
53
54 std::mutex m_lock;
55 std::condition_variable m_updated;
56
57 _Guarded_by_(m_lock) std::deque<wsl::windows::common::wslc_schema::Event> m_events;
58 _Guarded_by_(m_lock) uint64_t m_firstSequenceNumber = 1;
59
60 _Guarded_by_(m_lock) bool m_terminating = false;
61 };
62
63 class EventStream
64 : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCEventStream, IFastRundown>
65 {
66 public:
67 HRESULT RuntimeClassInitialize(
68 Microsoft::WRL::ComPtr<WSLCSession> Session,
69 EventStore* Store,
70 int64_t SinceTime,
71 int64_t UntilTime,
72 std::map<std::string, std::vector<std::string>> Filters);
73
74 IFACEMETHOD(GetNext)(_Outptr_result_z_ LPSTR* EventJson) override;
75
76 private:
77 Microsoft::WRL::ComPtr<WSLCSession> m_session;
78 EventStore* m_store = nullptr;
79
80 std::optional<std::chrono::sys_seconds> m_since;
81 std::optional<std::chrono::sys_seconds> m_until;
82 std::map<std::string, std::vector<std::string>> m_filters;
83
84 std::mutex m_lock;
85 _Guarded_by_(m_lock) std::optional<uint64_t> m_nextSequenceNumber;
86 };
87
88 } // namespace wsl::windows::service::wslc