You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I can't help but notice that the L1/L2 sync is tightly coupled into global sync function. The sync allows only specific functions to be used for separate L1 and L2 syncing, de facto coupling it with event processing. See sync.
The result is a set of "manually" managed jobs that just pull data from L1/L2 and send it to respective channels. Yet the channels do not leave the sync scope, thus effectively event producers and consumers are tightly coupled. This leads to extra effort with testing things, making potentially simple unit-tests into integration- or even system-tests, that require extensive test data and mocks to be set up. The problem with too much mocking is that at some point instead of testing that necessary side-effects appear and invariants hold, the mock assertions just "cement" existing implementation, which in turn lead to extra efforts when code needs to be updated or extended.
I was thinking that splitting pulling the L1/L2/whatever events ("producer") and processing them ("consumer") into separate entities would allow way simple test setup and thus code modifications. This might look like following: for a number of events A, B, C (united into enum Event) and pull-functions pull_a(&ctx) -> Event, pull_b(&ctx) -> Event, pull_c(&ctx) -> Event, constructing a composed source:
let ctx = Arc::new(Mutex::new(Context::new(...)));
let src = Source::new(ctx.clone());
src.add("A", pull_a, 1 minute).await;
src.add("B", pull_b, 5 minutes).await;
src.add("C", pull_c, 15 minutes).await;
let mut src = src.run(); // start polling
Then consuming the necessary events using handle_a(&ctx, A), handle_b(&ctx, B), handle_c(&ctx, C) trivially dispatched under single handle(&ctx, Event):
while let Some(event) = src.get().await {
let ctx = ctx.clone();
tokio::task::spawn(async move {
handle(ctx, event).await;
});
}
Note that each {poll, handle}_{a,b,c} should be test-friendly with single test data setup via shared Context. Integration tests would require mocking external sources (e.g. via httpmock), but should be clearly extendable from unit-test setup.
The described event-Source approach decouples event consumers and producers completely, is testing-friendly and easily extendable in a clean and type-safe manner (mostly thanks to Rust type system). This will allow for seamless extension of syncing, including peer-to-peer.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I can't help but notice that the L1/L2 sync is tightly coupled into global
syncfunction. Thesyncallows only specific functions to be used for separate L1 and L2 syncing, de facto coupling it with event processing. Seesync.The result is a set of "manually" managed jobs that just pull data from L1/L2 and send it to respective channels. Yet the channels do not leave the
syncscope, thus effectively event producers and consumers are tightly coupled. This leads to extra effort with testing things, making potentially simple unit-tests into integration- or even system-tests, that require extensive test data and mocks to be set up. The problem with too much mocking is that at some point instead of testing that necessary side-effects appear and invariants hold, the mock assertions just "cement" existing implementation, which in turn lead to extra efforts when code needs to be updated or extended.I was thinking that splitting pulling the L1/L2/whatever events ("producer") and processing them ("consumer") into separate entities would allow way simple test setup and thus code modifications. This might look like following: for a number of events
A,B,C(united into enumEvent) and pull-functionspull_a(&ctx) -> Event,pull_b(&ctx) -> Event,pull_c(&ctx) -> Event, constructing a composed source:Then consuming the necessary events using
handle_a(&ctx, A),handle_b(&ctx, B),handle_c(&ctx, C)trivially dispatched under singlehandle(&ctx, Event):Note that each
{poll, handle}_{a,b,c}should be test-friendly with single test data setup via sharedContext. Integration tests would require mocking external sources (e.g. viahttpmock), but should be clearly extendable from unit-test setup.The described event-
Sourceapproach decouples event consumers and producers completely, is testing-friendly and easily extendable in a clean and type-safe manner (mostly thanks to Rust type system). This will allow for seamless extension of syncing, including peer-to-peer.All reactions