mirror of https://github.com/Trivernis/bromine.git
commit
e457670d2b
@ -0,0 +1,33 @@
|
||||
name: Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
pull_request:
|
||||
branches: [ main, develop ]
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Cache build data
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
target
|
||||
~/.cargo/
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
- name: Build
|
||||
run: cargo build --verbose
|
||||
|
||||
- name: Run tests
|
||||
run: cargo test --verbose
|
@ -1,3 +1,19 @@
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
pub mod error_event;
|
||||
pub mod event;
|
||||
pub mod event_handler;
|
||||
|
||||
/// Generates a new event id
|
||||
pub(crate) fn generate_event_id() -> u64 {
|
||||
lazy_static::lazy_static! {
|
||||
static ref COUNTER: Arc<AtomicU64> = Arc::new(AtomicU64::new(0));
|
||||
}
|
||||
let epoch_elapsed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
|
||||
(epoch_elapsed.as_secs() % u16::MAX as u64) << 48
|
||||
| (epoch_elapsed.subsec_millis() as u64) << 32
|
||||
| COUNTER.fetch_add(1, Ordering::SeqCst)
|
||||
}
|
||||
|
@ -1,5 +1,54 @@
|
||||
use crate::context::Context;
|
||||
use crate::error_event::{ErrorEventData, ERROR_EVENT_NAME};
|
||||
use crate::events::event_handler::EventHandler;
|
||||
use crate::Event;
|
||||
use std::sync::Arc;
|
||||
use tokio::net::tcp::OwnedReadHalf;
|
||||
|
||||
pub mod builder;
|
||||
pub mod client;
|
||||
pub mod context;
|
||||
pub mod server;
|
||||
pub mod stream_emitter;
|
||||
|
||||
/// Handles listening to a connection and triggering the corresponding event functions
|
||||
async fn handle_connection(handler: Arc<EventHandler>, mut read_half: OwnedReadHalf, ctx: Context) {
|
||||
while let Ok(event) = Event::from_async_read(&mut read_half).await {
|
||||
// check if the event is a reply
|
||||
if let Some(ref_id) = event.reference_id() {
|
||||
// get the listener for replies
|
||||
if let Some(sender) = ctx.get_reply_sender(ref_id).await {
|
||||
// try sending the event to the listener for replies
|
||||
if let Err(event) = sender.send(event) {
|
||||
handle_event(Context::clone(&ctx), Arc::clone(&handler), event);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
handle_event(Context::clone(&ctx), Arc::clone(&handler), event);
|
||||
}
|
||||
log::debug!("Connection closed.");
|
||||
}
|
||||
|
||||
/// Handles a single event in a different tokio context
|
||||
fn handle_event(ctx: Context, handler: Arc<EventHandler>, event: Event) {
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = handler.handle_event(&ctx, event).await {
|
||||
// emit an error event
|
||||
if let Err(e) = ctx
|
||||
.emitter
|
||||
.emit(
|
||||
ERROR_EVENT_NAME,
|
||||
ErrorEventData {
|
||||
message: format!("{:?}", e),
|
||||
code: 500,
|
||||
},
|
||||
)
|
||||
.await
|
||||
{
|
||||
log::error!("Error occurred when sending error response: {:?}", e);
|
||||
}
|
||||
log::error!("Failed to handle event: {:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
use crate::events::generate_event_id;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn event_ids_work() {
|
||||
let mut ids = HashSet::new();
|
||||
|
||||
// simple collision test
|
||||
for _ in 0..100000 {
|
||||
assert!(ids.insert(generate_event_id()))
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
mod ipc_tests;
|
||||
mod utils;
|
||||
mod event_tests;
|
||||
|
Loading…
Reference in New Issue