Skip to content

Commit ef9ff93

Browse files
authored
Add support for parsing raw events using custom transform in PushInputAdapter (#678)
* Add support for a callback event parser in PushInputAdapter Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com> * Address comments, and cleanup Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com> * Simplify API for parsing raw events Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com> * Address comments Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com> --------- Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
1 parent f298599 commit ef9ff93

5 files changed

Lines changed: 760 additions & 19 deletions

File tree

cpp/csp/engine/PendingPushEvents.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,10 @@ void PendingPushEvents::processPendingEvents( std::vector<PushGroup*> & dirtyGro
7777
//for ungrouped events we'll never process more than one at a time
7878
auto * event = it -> second.head;
7979
it -> second.head = event -> next;
80-
bool rv = it -> first -> consumeEvent( event, dirtyGroups );
81-
(void)rv;
82-
assert( rv == true );
80+
// reconsuming=true: event was already transformed on the first pass, skip transformRawEvent
81+
PushEvent * pending_event = it -> first -> consumeEvent( event, dirtyGroups, true );
82+
(void)pending_event;
83+
assert( pending_event == nullptr );
8384

8485
if( it -> second.head == nullptr )
8586
it = m_ungroupedEvents.erase( it );
@@ -99,19 +100,20 @@ void PendingPushEvents::processPendingEvents( std::vector<PushGroup*> & dirtyGro
99100
{
100101
PushEvent * next = event -> next;
101102

102-
bool consumed = event -> adapter() -> consumeEvent( event, dirtyGroups );
103+
// reconsuming=true: event was already transformed on the first pass, skip transformRawEvent
104+
PushEvent * pending_event = event -> adapter() -> consumeEvent( event, dirtyGroups, true );
103105

104-
if( !consumed )
106+
if( pending_event != nullptr )
105107
{
106-
if( !deferred_head )
108+
if( !deferred_head )
107109
{
108-
deferred_head = event;
109-
deferred_tail = event;
110+
deferred_head = pending_event;
111+
deferred_tail = pending_event;
110112
}
111113
else
112114
{
113-
deferred_tail -> next = event;
114-
deferred_tail = event;
115+
deferred_tail -> next = pending_event;
116+
deferred_tail = pending_event;
115117
}
116118
}
117119

cpp/csp/engine/PushInputAdapter.h

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class PushInputAdapter : public InputAdapter
7979
{
8080
public:
8181
PushInputAdapter( Engine * engine, CspTypePtr & type, PushMode pushMode,
82-
PushGroup * group = nullptr ) : InputAdapter( engine, type, pushMode ),
83-
m_group( group )
82+
PushGroup * group = nullptr, bool transformEvents = false )
83+
: InputAdapter( engine, type, pushMode ), m_group( group ), m_transformEvents( transformEvents )
8484
{
8585
}
8686

@@ -91,12 +91,23 @@ class PushInputAdapter : public InputAdapter
9191
void pushTick( T &&value, PushBatch *batch = nullptr );
9292

9393
//called from engine processing thread
94-
//will delete event if processed, returns true if processed
95-
bool consumeEvent( PushEvent *, std::vector<PushGroup *> & dirtyGroups );
94+
//returns nullptr if event was consumed, otherwise returns the (possibly transformed) event for reconsuming on a later cycle
95+
//reconsuming=true indicates the event was already transformed and should not be transformed again
96+
PushEvent * consumeEvent( PushEvent *, std::vector<PushGroup *> & dirtyGroups, bool reconsuming = false );
97+
98+
// Override to transform a raw event into a new parsed event for the csp engine.
99+
// The implementation must:
100+
// - delete the original raw event
101+
// - preserve event properties (e.g. isGroupEnd flag) on the new event
102+
virtual PushEvent * transformRawEvent( PushEvent * raw_event ) { return nullptr; };
96103

97104
private:
98105

99106
PushGroup * m_group;
107+
// When enabled, consumeEvent will call transformRawEvent on the first pass to convert pushed events
108+
// before consumption. On reconsuming (from PendingPushEvents), the transform is skipped since
109+
// the event was already transformed on the first pass.
110+
bool m_transformEvents = false;
100111
};
101112

102113
template<typename T>
@@ -119,10 +130,18 @@ inline void PushInputAdapter::pushTick( T &&value, PushBatch *batch )
119130
rootEngine() -> schedulePushEvent( event );
120131
}
121132

122-
inline bool PushInputAdapter::consumeEvent( PushEvent * event, std::vector<PushGroup *> & dirtyGroups )
133+
inline PushEvent * PushInputAdapter::consumeEvent( PushEvent * event, std::vector<PushGroup *> & dirtyGroups, bool reconsuming )
123134
{
135+
// transform the raw event, if enabled and not reconsuming
136+
if( m_transformEvents && !reconsuming )
137+
{
138+
PushEvent * raw_event = event;
139+
event = transformRawEvent( raw_event );
140+
CSP_ASSERT( event != nullptr );
141+
}
142+
124143
if( m_group && m_group -> state == PushGroup::LOCKED )
125-
return false;
144+
return event;
126145

127146
bool isGroupEnd = event -> isGroupEnd();
128147

@@ -136,6 +155,7 @@ inline bool PushInputAdapter::consumeEvent( PushEvent * event, std::vector<PushG
136155
delete tevent;
137156
return consumed;
138157
} );
158+
139159
if( m_group )
140160
{
141161
if( pushMode() == PushMode::NON_COLLAPSING )
@@ -152,7 +172,10 @@ inline bool PushInputAdapter::consumeEvent( PushEvent * event, std::vector<PushG
152172
}
153173
}
154174

155-
return consumed;
175+
if( consumed )
176+
return nullptr;
177+
else
178+
return event;
156179
}
157180

158181
inline void PushBatch::append( PushEvent * event )

cpp/csp/engine/RootEngine.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ void RootEngine::processPushEventQueue( PushEvent * event, std::vector<PushGroup
128128
{
129129
PushEvent * next = event -> next;
130130

131-
if( !event -> adapter() -> consumeEvent( event, dirtyGroups ) )
132-
m_pendingPushEvents.addPendingEvent( event );
131+
auto * pending_event = event -> adapter() -> consumeEvent( event, dirtyGroups );
132+
if( pending_event != nullptr )
133+
m_pendingPushEvents.addPendingEvent( pending_event );
133134

134135
event = next;
135136
}

0 commit comments

Comments
 (0)