Fix typed proxy access to generic skeleton event storage#394
Fix typed proxy access to generic skeleton event storage#394rudresh-systream wants to merge 3 commits into
Conversation
37ebeb3 to
dcb34ed
Compare
|
@rudresh-systream - thank you for your effort/fix proposal. @bemerybmw and me hat a quick 1st look. Looks promising as a short-term bugfix-solution! Will do a deeper review soon. |
|
Hi @rudresh-systream and @crimson11, I quickly reviewed this fix and also run our integration test #379 and all test cases passed for generic-typed/generic use cases. |
f015563 to
fcbca26
Compare
Signed-off-by: Rudresh Shirwal <rudresh.shirwal@systream.io>
c93dee0 to
29563be
Compare
|
@crimson11 This PR is now focused on the #311 production fix and the remaining focused unit/regression coverage. I will check PR #379 for the GenericSkeleton integration-test coverage and add review feedback there if I find any missing Generic-Typed coverage relevant to this issue. |
a94f24f to
642fdd7
Compare
| using LoLaTypedProxyEventTestFixture = LolaProxyEventFixture<ProxyEventStruct>; | ||
| TEST_F(LoLaTypedProxyEventTestFixture, ReadsSamplesFromEventMetaInfoRawStorage) | ||
| { | ||
| RecordProperty("Verifies", "SCR-6225206"); |
There was a problem hiding this comment.
Why is this RecordProperty added?
| RecordProperty("TestType", "Regression test"); | ||
| RecordProperty("DerivationTechnique", "Analysis of bug 311"); | ||
|
|
||
| const std::size_t max_sample_count_subscription{5U}; |
There was a problem hiding this comment.
All our tests should follow the given, when, then structure (e.g. https://martinfowler.com/bliki/GivenWhenThen.html)
| } | ||
|
|
||
| using LoLaTypedProxyEventTestFixture = LolaProxyEventFixture<ProxyEventStruct>; | ||
| TEST_F(LoLaTypedProxyEventTestFixture, ReadsSamplesFromEventMetaInfoRawStorage) |
There was a problem hiding this comment.
The test name should clearly state what is the expectation of the test. e.g. In the title you say it should read samples from EventMetaInfoRawStorage but I don't see that tested in the test. Most likely that's just an implementation detail and we simply need to check that GetNewSamples works?
| ProxyEventAttorney<TestSampleType> proxy_event_attorney{*test_proxy_event_}; | ||
| using SamplesMemberType = typename std::remove_reference<decltype(proxy_event_attorney.GetSamplesMember())>::type; | ||
| static_assert(std::is_const<SamplesMemberType>::value, "Proxy should hold const slot data."); | ||
| using MetaInfoMemberType = typename std::remove_reference<decltype(proxy_event_attorney.GetMetaInfoMember())>::type; |
There was a problem hiding this comment.
I would add in a new test instead of modifying the current one.
| const auto total_event_slots_size = safe_math::Multiply(aligned_sample_size, element_properties.number_of_slots); | ||
| if (!total_event_slots_size.has_value()) | ||
| { | ||
| score::mw::log::LogFatal("lola") << "Could not calculate the event slots raw array size. Terminating."; |
There was a problem hiding this comment.
Why are the others assertions and this is a terminate? You could also use the kAbortOnError return mode in safe_math
| auto& event_data_control_local = proxy_event_common_.GetConsumerEventDataControlLocal(); | ||
|
|
||
| const auto event_slots_raw_array_size = | ||
| safe_math::Multiply(aligned_sample_size_, event_data_control_local.GetMaxSampleSlots()); |
There was a problem hiding this comment.
You could also use the kAbortOnError return mode in safe_math
| aligned_sample_size_{memory::shared::CalculateAlignedSize(sizeof(SampleType), alignof(SampleType))}, | ||
| event_slots_raw_array_{nullptr} | ||
| { | ||
| InitialiseEventSlotsRawArray(); |
There was a problem hiding this comment.
This could return const std::uint8_t* and be used to directly initialize event_slots_raw_array_.
| }; | ||
|
|
||
| private: | ||
| void InitialiseEventSlotsRawArray() noexcept; |
There was a problem hiding this comment.
We should only mark destructors / move ops as noexcept
| std::optional<ProviderEventDataControlLocalView<>> provider_event_data_control_local_{}; | ||
| std::optional<ConsumerEventDataControlLocalView<>> consumer_event_data_control_local_{}; | ||
| EventDataStorage<SampleType>* event_data_storage_{nullptr}; | ||
| void* event_slots_raw_array_{nullptr}; |
There was a problem hiding this comment.
We shouldn't remove event_data_storage_. We should rather emulate the production code in which event_slots_raw_array_ is a type erased view into the event_data_storage_
|
|
||
| template <typename SampleType> | ||
| inline std::tuple<EventControl*, EventDataStorage<SampleType>*> FakeMockedServiceData::AddEvent( | ||
| inline std::tuple<EventControl*, void*> FakeMockedServiceData::AddEvent( |
There was a problem hiding this comment.
I don't think this should be changed. Same point as: https://github.com/eclipse-score/communication/pull/394/changes#r3288235207

Summary:
Implemented a compatibility fix for the GenericSkeleton ↔ typed ProxyEvent shared-memory interaction described in #311.
Root cause
The issue originates from the fact that GenericSkeleton and typed skeletons create/interprete
EventDataStoragedifferently.For typed skeletons, the storage is created through:
which internally creates a typed
DynamicArray<SampleType>.For GenericSkeleton/GenericSkeletonEvent, the storage is instead created using:
EventDataStorage<std::max_align_t>with the storage size being calculated in units of
std::max_align_t.As a result, the underlying raw memory region may be large enough, but the metadata/layout interpretation of the
DynamicArray<T>becomes incompatible between the producer and consumer sides.The typed proxy path was still assuming a typed
EventDataStorage<T>representation and therefore interpreted slot count/layout using the wrong type information. This creates an incompatibility whenever:This issue is especially visible because the DynamicArray element count depends on the template type
T, which differs between the generic and typed paths.Investigated solution approaches
Several approaches were considered:
1. Extending
DynamicArray<T>One option was to add a constructor allowing externally managed/preallocated storage while preserving a typed
DynamicArray<T>interface.This was not chosen because:
DynamicArray,2. Replacing all event storage with
DynamicArray<std::byte>Another option was to fully migrate all event storage handling to raw byte storage.
While architecturally clean, this would require significantly broader refactoring across:
Given the scope/risk, this approach was considered too invasive for the current issue.
3. Fixing typed proxy access to use raw slot storage (chosen solution)
The implemented solution changes typed proxy sample access so it no longer depends on interpreting the shared memory as
EventDataStorage<T>.Instead:
the proxy accesses the shared-memory event region through raw slot memory/meta information,
and calculates slot/sample access using:
sizeof(T)alignof(T)This keeps the existing shared-memory layout compatible while allowing typed proxies to correctly consume data produced by GenericSkeleton.
This approach was selected because it:
Files changed
score/mw/com/impl/bindings/lola/proxy_event.hMain functional fix.
Updated typed
ProxyEvent<T>sample access logic to avoid relying on interpreting the shared-memory region asEventDataStorage<T>.Instead, access is now performed through raw event slot metadata and pointer arithmetic based on the actual sample type size/alignment.
This makes typed proxies compatible with GenericSkeleton-created storage.
score/mw/com/impl/bindings/lola/skeleton_memory_manager.hscore/mw/com/impl/bindings/lola/skeleton_memory_manager.cppUpdated/supporting changes around event storage creation and raw slot metadata handling.
These changes ensure both generic and typed paths expose compatible storage information to consumers.
score/mw/com/impl/bindings/lola/skeleton.cppAdjusted skeleton-side integration to align with the updated event storage access model and metadata usage.
score/mw/com/impl/bindings/lola/proxy_event_test.cppscore/mw/com/impl/bindings/lola/test/proxy_event_test_resources.cppscore/mw/com/impl/bindings/lola/test/proxy_event_test_resources.hUpdated and extended test resources/coverage to validate:
Validation performed
The following builds/tests were executed successfully after the changes:
All relevant LoLa event/proxy/skeleton tests passed successfully after the fix.