WorkloadContext

Struct WorkloadContext 

Source
pub struct WorkloadContext(/* private fields */);
Expand description

Wrapper around the C FDBWorkloadContext

Implementations§

Source§

impl WorkloadContext

Source

pub fn trace<S, S2, S3>( &self, severity: Severity, name: S, details: &[(S2, S3)], )
where S: Into<Vec<u8>>, S2: AsRef<str>, S3: AsRef<str>,

Add a log entry in the FoundationDB logs

Examples found in repository?
examples/noop/lib.rs (lines 15-19)
13    async fn setup(&mut self, _db: SimDatabase) {
14        println!("rust_setup({}_{})", self.name, self.client_id);
15        self.context.trace(
16            Severity::Debug,
17            "Test",
18            &[("Layer", "Rust"), ("Stage", "Setup")],
19        );
20    }
21    async fn start(&mut self, _db: SimDatabase) {
22        println!("rust_start({}_{})", self.name, self.client_id);
23        self.context.trace(
24            Severity::Debug,
25            "Test",
26            &[("Layer", "Rust"), ("Stage", "Start")],
27        );
28    }
29    async fn check(&mut self, _db: SimDatabase) {
30        println!("rust_check({}_{})", self.name, self.client_id);
31        self.context.trace(
32            Severity::Debug,
33            "Test",
34            &[("Layer", "Rust"), ("Stage", "Check")],
35        );
36    }
More examples
Hide additional examples
examples/atomic/lib.rs (lines 62-69)
43    async fn start(&mut self, db: SimDatabase) {
44        println!("rust_start({})", self.client_id);
45        // Only use a single client
46        if self.client_id == 0 {
47            for _ in 0..self.expected_count {
48                let trx = db.create_trx().expect("Could not create transaction");
49
50                // Enable idempotent txn
51                trx.set_option(TransactionOption::AutomaticIdempotency)
52                    .expect("could not setup automatic idempotency");
53
54                let buf: [u8; 8] = 1i64.to_le_bytes();
55
56                trx.atomic_op(&Subspace::all().pack(&COUNT_KEY), &buf, MutationType::Add);
57
58                match trx.commit().await {
59                    Ok(_) => self.success_count += 1,
60                    Err(err) => {
61                        if err.is_maybe_committed() {
62                            self.context.trace(
63                                Severity::Warn,
64                                "Detected an maybe_committed transactions with idempotency",
65                                details![
66                                    "Layer" => "Rust",
67                                    "Client" => self.client_id
68                                ],
69                            );
70                            self.maybe_committed_count += 1;
71                        } else {
72                            self.error_count += 1;
73                        }
74                    }
75                }
76
77                self.context.trace(
78                    Severity::Info,
79                    "Successfully setup workload",
80                    details![
81                        "Layer" => "Rust",
82                        "Client" => self.client_id
83                    ],
84                );
85            }
86        }
87    }
88    async fn check(&mut self, db: SimDatabase) {
89        println!("rust_check({})", self.client_id);
90        if self.client_id == 0 {
91            // even if buggify is off in checks, transactions can failed because of the randomized knob,
92            // so we need to wrap the check in a db.run
93            let count = db
94                .run(|trx, _maybe_committed| async move {
95                    match trx.get(&Subspace::all().pack(&COUNT_KEY), true).await {
96                        Err(e) => Err(FdbBindingError::from(e)),
97                        Ok(None) => Ok(0),
98                        Ok(Some(byte_count)) => {
99                            let count = i64::from_le_bytes(byte_count[..8].try_into().unwrap());
100                            Ok(count as usize)
101                        }
102                    }
103                })
104                .await
105                .expect("could not check using db.run");
106
107            if self.success_count == count {
108                self.context.trace(
109                    Severity::Info,
110                    "Atomic count match",
111                    details![
112                        "Layer" => "Rust",
113                        "Client" => self.client_id,
114                        "Expected" => self.expected_count,
115                        "Found" => count,
116                        "CommittedCount" => self.success_count,
117                        "MaybeCommitted" => self.maybe_committed_count,
118                    ],
119                );
120            } else {
121                self.context.trace(
122                    Severity::Error,
123                    "Atomic count doesn't match",
124                    details![
125                        "Layer" => "Rust",
126                        "Client" => self.client_id,
127                        "Expected" => self.expected_count,
128                        "Found" => count,
129                        "CommittedCount" => self.success_count,
130                        "MaybeCommitted" => self.maybe_committed_count,
131                    ],
132                );
133            }
134        }
135    }
Source

pub fn get_process_id(&self) -> u64

Get the process id of the workload

Source

pub fn set_process_id(&self, id: u64)

Set the process id of the workload

Source

pub fn now(&self) -> f64

Get the current simulated time in seconds (starts at zero)

Source

pub fn rnd(&self) -> u32

Get a determinist 32-bit random number

Source

pub fn get_option<T>(&self, name: &str) -> Option<T>
where T: FromStr,

Get the value of a parameter from the simulation config file

/!\ getting an option consumes it, following call on that option will return None

Examples found in repository?
examples/atomic/lib.rs (line 30)
27    fn new(_name: String, context: WorkloadContext) -> Self {
28        Self {
29            client_id: context.client_id(),
30            expected_count: context.get_option("count").expect("Could not get count"),
31            context,
32            success_count: 0,
33            error_count: 0,
34            maybe_committed_count: 0,
35        }
36    }
More examples
Hide additional examples
examples/noop/lib.rs (line 70)
64    fn create(name: String, context: WorkloadContext) -> WrappedWorkload {
65        let client_id = context.client_id();
66        let client_count = context.client_count();
67        println!("RustWorkloadFactory::create({name})[{client_id}/{client_count}]");
68        println!(
69            "my_c_option: {:?}",
70            context.get_option::<String>("my_c_option")
71        );
72        println!(
73            "my_c_option: {:?}",
74            context.get_option::<String>("my_c_option")
75        );
76        match name.as_str() {
77            "NoopWorkload" => WrappedWorkload::new(NoopWorkload::new(name, client_id, context)),
78            _ => panic!("Unknown workload name: {name}"),
79        }
80    }
Source

pub fn client_id(&self) -> i32

Get the client id of the workload

Examples found in repository?
examples/atomic/lib.rs (line 29)
27    fn new(_name: String, context: WorkloadContext) -> Self {
28        Self {
29            client_id: context.client_id(),
30            expected_count: context.get_option("count").expect("Could not get count"),
31            context,
32            success_count: 0,
33            error_count: 0,
34            maybe_committed_count: 0,
35        }
36    }
More examples
Hide additional examples
examples/noop/lib.rs (line 65)
64    fn create(name: String, context: WorkloadContext) -> WrappedWorkload {
65        let client_id = context.client_id();
66        let client_count = context.client_count();
67        println!("RustWorkloadFactory::create({name})[{client_id}/{client_count}]");
68        println!(
69            "my_c_option: {:?}",
70            context.get_option::<String>("my_c_option")
71        );
72        println!(
73            "my_c_option: {:?}",
74            context.get_option::<String>("my_c_option")
75        );
76        match name.as_str() {
77            "NoopWorkload" => WrappedWorkload::new(NoopWorkload::new(name, client_id, context)),
78            _ => panic!("Unknown workload name: {name}"),
79        }
80    }
Source

pub fn client_count(&self) -> i32

Get the client id of the workload

Examples found in repository?
examples/noop/lib.rs (line 66)
64    fn create(name: String, context: WorkloadContext) -> WrappedWorkload {
65        let client_id = context.client_id();
66        let client_count = context.client_count();
67        println!("RustWorkloadFactory::create({name})[{client_id}/{client_count}]");
68        println!(
69            "my_c_option: {:?}",
70            context.get_option::<String>("my_c_option")
71        );
72        println!(
73            "my_c_option: {:?}",
74            context.get_option::<String>("my_c_option")
75        );
76        match name.as_str() {
77            "NoopWorkload" => WrappedWorkload::new(NoopWorkload::new(name, client_id, context)),
78            _ => panic!("Unknown workload name: {name}"),
79        }
80    }
Source

pub fn shared_random_number(&self) -> i64

Get a determinist 64-bit random number

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V