Skip to content

Commit 8f2cdcc

Browse files
authored
Issue #159 event reducer (#163)
* sentry - event_reducer - fn `reduce` & `unimplemented!()` for fn `merge_impression_ev` * sentry - event_reducer - impl fn `merge_impression_ev` primitives - sentry - `derive(Clone)` for `AggregateEvents` * sentry - event_reducer - add `allow[dead_code]` for `reduce` * sentry - even_reduce - test `fn reduce()` - fix some logic - change API of the fn - primitives - sentry - `derive(Default)` for `AggregateEvents` * primitives - sentry - AggregateEvents - Remove `Option` for `event_counts` * primitives - sentry - make `AggregateEvents.event_counts` an `Option`
1 parent 49b438d commit 8f2cdcc

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

primitives/src/sentry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub struct EventAggregate {
6969
pub events: HashMap<String, AggregateEvents>,
7070
}
7171

72-
#[derive(Debug, Serialize, Deserialize)]
72+
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
7373
#[serde(rename_all = "camelCase")]
7474
pub struct AggregateEvents {
7575
#[serde(default, skip_serializing_if = "Option::is_none")]

sentry/src/event_reducer.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use primitives::sentry::{AggregateEvents, Event, EventAggregate};
2+
use primitives::Channel;
3+
4+
// @TODO: Remove attribute once we use this function!
5+
#[allow(dead_code)]
6+
pub(crate) fn reduce(channel: &Channel, initial_aggr: &mut EventAggregate, ev: &Event) {
7+
match ev {
8+
Event::Impression { publisher, .. } => {
9+
let impression = initial_aggr.events.get("IMPRESSION");
10+
11+
let merge = merge_impression_ev(impression, &publisher, &channel);
12+
13+
initial_aggr.events.insert("IMPRESSION".to_owned(), merge);
14+
}
15+
Event::Close => {
16+
let creator = channel.creator.clone();
17+
let close_event = AggregateEvents {
18+
event_counts: Some(vec![(creator.clone(), 1.into())].into_iter().collect()),
19+
event_payouts: vec![(creator, channel.deposit_amount.clone())]
20+
.into_iter()
21+
.collect(),
22+
};
23+
initial_aggr.events.insert("CLOSE".to_owned(), close_event);
24+
}
25+
_ => {}
26+
};
27+
}
28+
29+
fn merge_impression_ev(
30+
impression: Option<&AggregateEvents>,
31+
earner: &str,
32+
channel: &Channel,
33+
) -> AggregateEvents {
34+
let mut impression = impression.map(Clone::clone).unwrap_or_default();
35+
36+
let event_count = impression
37+
.event_counts
38+
.get_or_insert_with(Default::default)
39+
.entry(earner.into())
40+
.or_insert_with(|| 0.into());
41+
42+
*event_count += &1.into();
43+
44+
let event_payouts = impression
45+
.event_payouts
46+
.entry(earner.into())
47+
.or_insert_with(|| 0.into());
48+
*event_payouts += &channel.spec.min_per_impression;
49+
50+
impression
51+
}
52+
53+
#[cfg(test)]
54+
mod test {
55+
use super::*;
56+
use chrono::Utc;
57+
use primitives::util::tests::prep_db::DUMMY_CHANNEL;
58+
use primitives::BigNum;
59+
60+
#[test]
61+
fn test_reduce() {
62+
let mut channel: Channel = DUMMY_CHANNEL.clone();
63+
channel.deposit_amount = 100.into();
64+
// make immutable again
65+
let channel = channel;
66+
67+
let mut event_aggr = EventAggregate {
68+
channel_id: channel.id.clone(),
69+
created: Utc::now(),
70+
events: Default::default(),
71+
};
72+
73+
let event = Event::Impression {
74+
publisher: "myAwesomePublisher".to_string(),
75+
ad_unit: None,
76+
};
77+
78+
for _ in 0..101 {
79+
reduce(&channel, &mut event_aggr, &event);
80+
}
81+
82+
assert_eq!(event_aggr.channel_id, channel.id);
83+
84+
let impression_event = event_aggr
85+
.events
86+
.get("IMPRESSION")
87+
.expect("Should have an Impression event");
88+
89+
let event_counts = impression_event
90+
.event_counts
91+
.as_ref()
92+
.expect("there should be event_counts set")
93+
.get("myAwesomePublisher")
94+
.expect("There should be myAwesomePublisher event_counts key");
95+
assert_eq!(event_counts, &BigNum::from(101));
96+
97+
let event_payouts = impression_event
98+
.event_counts
99+
.as_ref()
100+
.expect("there should be event_counts set")
101+
.get("myAwesomePublisher")
102+
.expect("There should be myAwesomePublisher event_payouts key");
103+
assert_eq!(event_payouts, &BigNum::from(101));
104+
}
105+
}

sentry/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub mod routes {
1313

1414
pub mod access;
1515
pub mod db;
16+
pub mod event_reducer;
1617

1718
pub struct Application<A: Adapter> {
1819
adapter: A,

0 commit comments

Comments
 (0)