Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Handling of Unknown EventKind in EventIterator #102

Open
msk opened this issue Jun 22, 2023 · 0 comments
Open

Improved Handling of Unknown EventKind in EventIterator #102

msk opened this issue Jun 22, 2023 · 0 comments
Labels
good first issue Good for newcomers

Comments

@msk
Copy link
Contributor

msk commented Jun 22, 2023

Description

EventIterator currently navigates through events stored in EventDb, deserializing them based on their EventKind. When encountering an EventKind not present in the EventKind enum, EventIterator::next returns Some(Err(InvalidEvent::Key(k))).

This behavior can cause issues when a review agent sends a new type of event that's not represented in the EventKind enum and stores it in the database. We need to enhance EventIterator's handling of unknown event kinds to ensure smooth processing.

Current Implementation

The current implementation extracts and checks the event kind as follows:

let key: [u8; 16] = if let Ok(key) = k.as_ref().try_into() {
    key
} else {
    return Some(Err(InvalidEvent::Key(k)));
};
let key = i128::from_be_bytes(key);
let time = Utc.timestamp_nanos((key >> 64).try_into().expect("valid i64"));
let kind_num = (key & 0xffff_ffff_0000_0000) >> 32;
let Some(kind) = EventKind::from_i128(kind_num) else {
    return Some(Err(InvalidEvent::Key(k)));
};

Suggested Enhancement

Instead of returning Some(Err(InvalidEvent::Key(k))) for unknown event kinds, we propose a change where EventIterator logs a warning message and continues to retrieve the next events until a valid event type is encountered. This approach avoids interrupting the iteration process due to unknown event kinds.

The updated implementation is as follows:

let mut key: [u8; 16];
let mut kind_num: i128;
let mut kind: Option<EventKind>;

loop {
    let (k, v) = match self.inner.next().transpose().ok().flatten() {
        Some(kv) => kv,
        None => return None,  // No more elements to iterate over
    };

    key = match k.as_ref().try_into() {
        Ok(key) => key,
        Err(_) => return Some(Err(InvalidEvent::Key(k))),
    };

    key = i128::from_be_bytes(key);
    let time = Utc.timestamp_nanos((key >> 64).try_into().expect("valid i64"));
    kind_num = (key & 0xffff_ffff_0000_0000) >> 32;
    kind = EventKind::from_i128(kind_num);

    if kind.is_none() {
        warn!("Encountered an unknown event kind: {}", kind_num);
    } else {
        break;  // Found a valid event type, exit the loop
    }
}

In this approach, EventIterator::next() continues to fetch the next event until it finds a valid event type. Upon encountering an unknown event kind, it logs a warning and continues the loop until it finds a known event type or there are no more events to iterate over.

Benefits

This improvement enhances EventIterator's resilience against unknown event kinds, ensuring the iteration process remains uninterrupted even with the introduction of new, currently unknown event kinds. The change increases overall robustness and eases the integration of new event kinds in the future.

@msk msk added the good first issue Good for newcomers label Jun 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant