Skip to content

Commit

Permalink
chore: create facility in spawned thread
Browse files Browse the repository at this point in the history
  • Loading branch information
thevaibhav-dixit committed Jan 23, 2025
1 parent eecf5a8 commit 8985ae0
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 71 deletions.
2 changes: 1 addition & 1 deletion lana/sim-bootstrap/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Default for BootstrapConfig {
}

fn default_num_facilities() -> u32 {
4
1
}

fn default_num_customers() -> u32 {
Expand Down
115 changes: 45 additions & 70 deletions lana/sim-bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ mod config;

use futures::StreamExt;
use rust_decimal_macros::dec;
use std::sync::{Arc, Mutex};

use std::collections::HashSet;

use lana_app::{
app::LanaApp,
Expand All @@ -20,76 +17,89 @@ pub use config::*;

pub async fn run(
superuser_email: String,
app: LanaApp,
app: &LanaApp,
config: BootstrapConfig,
) -> anyhow::Result<()> {
dbg!(&config);
let sub = superuser_subject(&superuser_email, &app).await?;
let sub = superuser_subject(&superuser_email, app).await?;

let customer_ids = create_customers(&sub, &app, &config).await?;
let customer_ids = create_customers(&sub, app, &config).await?;

make_deposit(&sub, &app, &customer_ids, &config).await?;
make_deposit(&sub, app, &customer_ids, &config).await?;

let mut facility_ids = HashSet::new();
let mut handles = Vec::new();

for customer_id in customer_ids {
for _ in 0..config.num_facilities {
let id = create_facility_for_customer(&sub, &app, customer_id).await?;
facility_ids.insert(id);
let spawned_app = app.clone();

let handle = tokio::spawn(async move {
create_and_process_facility(sub.clone(), customer_id.clone(), spawned_app).await
});
handles.push(handle);
}
}

let facility_ids = Arc::new(Mutex::new(facility_ids));

let spawned_app = app.clone();
let _handle = tokio::spawn(async move {
let _ = process_repayment(sub, facility_ids, spawned_app).await;
});

println!("waiting for real time");
sim_time::wait_until_realtime().await;
println!("done");

Ok(())
}

async fn process_repayment(
async fn create_and_process_facility(
sub: Subject,
facility_ids: Arc<Mutex<HashSet<CreditFacilityId>>>,
customer_id: CustomerId,
app: LanaApp,
) -> anyhow::Result<()> {
let terms = std_terms();

let cf = app
.credit_facilities()
.initiate(
&sub,
customer_id,
UsdCents::try_from_usd(dec!(10_000_000))?,
terms,
)
.await?;

let mut stream = app.outbox().listen_persisted(None).await?;

while let Some(msg) = stream.next().await {
match &msg.payload {
Some(LanaEvent::Credit(CreditEvent::AccrualExecuted {
id: cf_id, amount, ..
})) if {
let ids = facility_ids.lock().unwrap();
ids.contains(cf_id) && amount > &UsdCents::ZERO
} =>
Some(LanaEvent::Credit(CreditEvent::FacilityApproved { id })) if cf.id == *id => {
app.credit_facilities()
.update_collateral(&sub, cf.id, Satoshis::try_from_btc(dec!(230))?)
.await?;
}
Some(LanaEvent::Credit(CreditEvent::FacilityActivated { id, .. })) if cf.id == *id => {
app.credit_facilities()
.initiate_disbursal(&sub, cf.id, UsdCents::try_from_usd(dec!(1_000_000))?)
.await?;
}
Some(LanaEvent::Credit(CreditEvent::AccrualExecuted { id, amount, .. }))
if { cf.id == *id && amount > &UsdCents::ZERO } =>
{
let _ = app
.credit_facilities()
.record_payment(&sub, *cf_id, *amount)
.record_payment(&sub, *id, *amount)
.await;
let mut cf = app
let mut facility = app
.credit_facilities()
.find_by_id(&sub, *cf_id)
.find_by_id(&sub, *id)
.await?
.expect("cf exists");
if cf.interest_accrual_in_progress().is_none() {
if facility.interest_accrual_in_progress().is_none() {
app.credit_facilities()
.record_payment(&sub, cf.id, cf.outstanding().total())
.record_payment(&sub, facility.id, facility.outstanding().total())
.await?;
app.credit_facilities()
.complete_facility(&sub, cf.id)
.complete_facility(&sub, facility.id)
.await?;
}
}
Some(LanaEvent::Credit(CreditEvent::FacilityCompleted { id: cf_id, .. })) => {
let mut ids = facility_ids.lock().unwrap();
if ids.remove(cf_id) && ids.is_empty() {
Some(LanaEvent::Credit(CreditEvent::FacilityCompleted { id, .. })) => {
if cf.id == *id {
break;
}
}
Expand Down Expand Up @@ -177,41 +187,6 @@ async fn superuser_subject(superuser_email: &String, app: &LanaApp) -> anyhow::R
Ok(Subject::from(superuser.id))
}

async fn create_facility_for_customer(
sub: &Subject,
app: &LanaApp,
customer_id: CustomerId,
) -> anyhow::Result<CreditFacilityId> {
let terms = std_terms();

let cf = app
.credit_facilities()
.initiate(
sub,
customer_id,
UsdCents::try_from_usd(dec!(10_000_000))?,
terms,
)
.await?;

let id = cf.id;

// hack to ensure that credit facility is activated
tokio::time::sleep(std::time::Duration::from_millis(500)).await;

app.credit_facilities()
.update_collateral(sub, id, Satoshis::try_from_btc(dec!(230))?)
.await?;

// hack to ensure that credit facility is activated
tokio::time::sleep(std::time::Duration::from_millis(500)).await;

app.credit_facilities()
.initiate_disbursal(sub, id, UsdCents::try_from_usd(dec!(1_000_000))?)
.await?;
Ok(id)
}

fn std_terms() -> TermValues {
TermValues::builder()
.annual_rate(dec!(12))
Expand Down

0 comments on commit 8985ae0

Please sign in to comment.