fn fanout() {
    let self_id = api::id();

    let network_topology =
        NETWORK_TOPOLOGY.with(|network_topology| network_topology.borrow().clone());

    for canisters in network_topology {
        if canisters.is_empty() {
            continue;
        }

        if canisters.contains(&self_id.get().as_slice().to_vec()) {
            // Same subnet
            continue;
        }

        for _ in 0..PER_SUBNET_RATE.with(|r| *r.borrow()) {
            let idx = RNG.with(|rng| rng.borrow_mut().gen_range(0, canisters.len()));
            let canister = canisters[idx].clone();

            let seq_no = STATE.with(|s| s.borrow_mut().next_out_seq_no(canister.clone()));

            let msg = candid_encode_padded(&Request {
                seq_no,
                time_nanos: time_nanos(),
            });

            let err_code = api::call_raw(
                api::CanisterId::try_from(canister.clone()).unwrap(),
                "handle_request",
                &msg[..],
                on_reply,
                on_reject,
                None,
                std::ptr::null_mut(),
                api::Funds::zero(),
            );

            if err_code != 0 {
                log(&format!(
                    "{} call failed with {}",
                    time_nanos() / 1_000_000,
                    err_code
                ));
                METRICS.with(|m| m.borrow_mut().call_errors += 1);
            } else {
                METRICS.with(move |m| m.borrow_mut().requests_sent += 1);
            }
        }
    }
}
/// Sends `PER_SUBNET_RATE` messages to random canisters on the remote subnets.
/// Invoked by the canister heartbeat handler as long as `RUNNING` is `true`
/// (`start()` was and `stop()` was not yet called).
Sends `PER_SUBNET_RATE` messages to random canisters on the remote subnets.
Sends ` PER_SUBNET_RATE ` messages to random canisters on the remote subnets .
fn fanout() {
    let self_id = api::id();
    let network_topology =
        NETWORK_TOPOLOGY.with(|network_topology| network_topology.borrow().clone());
    for canisters in network_topology {
        if canisters.is_empty() {
            continue;
        }
        if canisters.contains(&self_id.get().as_slice().to_vec()) {
            // Same subnet
            continue;
        }
        for _ in 0..PER_SUBNET_RATE.with(|r| *r.borrow()) {
            let idx = RNG.with(|rng| rng.borrow_mut().gen_range(0, canisters.len()));
            let canister = canisters[idx].clone();
            let seq_no = STATE.with(|s| s.borrow_mut().next_out_seq_no(canister.clone()));
            let msg = candid_encode_padded(&Request {
                seq_no,
                time_nanos: time_nanos(),
            });
            let err_code = api::call_raw(
                api::CanisterId::try_from(canister.clone()).unwrap(),
                "handle_request",
                &msg[..],
                on_reply,
                on_reject,
                None,
                std::ptr::null_mut(),
                api::Funds::zero(),
            );
            if err_code != 0 {
                log(&format!(
                    "{} call failed with {}",
                    time_nanos() / 1_000_000,
                    err_code
                ));
                METRICS.with(|m| m.borrow_mut().call_errors += 1);
            } else {
                METRICS.with(move |m| m.borrow_mut().requests_sent += 1);
            }
        }
    }
}
fn fanout ( ) { let self_id = api :: id ( ) ; let network_topology = NETWORK_TOPOLOGY . with ( | network_topology | network_topology . borrow ( ) . clone ( ) ) ; for canisters in network_topology { if canisters . is_empty ( ) { continue ; } if canisters . contains ( & self_id . get ( ) . as_slice ( ) . to_vec ( ) ) { // Same subnet continue ; } for _ in 0 .. PER_SUBNET_RATE . with ( | r | * r . borrow ( ) ) { let idx = RNG . with ( | rng | rng . borrow_mut ( ) . gen_range ( 0 , canisters . len ( ) ) ) ; let canister = canisters [ idx ] . clone ( ) ; let seq_no = STATE . with ( | s | s . borrow_mut ( ) . next_out_seq_no ( canister . clone ( ) ) ) ; let msg = candid_encode_padded ( & Request { seq_no , time_nanos : time_nanos ( ) , } ) ; let err_code = api :: call_raw ( api :: CanisterId :: try_from ( canister . clone ( ) ) . unwrap ( ) , " " , & msg [ .. ] , on_reply , on_reject , None , std :: ptr :: null_mut ( ) , api :: Funds :: zero ( ) , ) ; if err_code != 0 { log ( & format ! ( " " time_nanos ( ) 1_000_000 err_code ) ) ; METRICS . with ( | m | m . borrow_mut ( ) . call_errors += 1 ) ; } else { METRICS . with ( move | m | m . borrow_mut ( ) . requests_sent += 1 ) ; } } } }
Sends `PER_SUBNET_RATE` messages to random canisters on the remote subnets.
Sends ` PER_SUBNET_RATE ` messages to random canisters on the remote subnets .