clockwork_pool/state/
pool.rs

1use {
2    anchor_lang::{prelude::*, AnchorDeserialize},
3    std::{collections::VecDeque, convert::TryFrom},
4};
5
6pub const SEED_POOL: &[u8] = b"pool";
7
8/**
9 * Pool
10 */
11
12#[account]
13#[derive(Debug)]
14pub struct Pool {
15    pub name: String,
16    pub size: usize,
17    pub workers: VecDeque<Pubkey>,
18}
19
20impl Pool {
21    pub fn pubkey(name: String) -> Pubkey {
22        Pubkey::find_program_address(&[SEED_POOL, name.as_bytes()], &crate::ID).0
23    }
24}
25
26impl TryFrom<Vec<u8>> for Pool {
27    type Error = Error;
28    fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
29        Pool::try_deserialize(&mut data.as_slice())
30    }
31}
32
33/**
34 * PoolSettings
35 */
36
37#[derive(AnchorSerialize, AnchorDeserialize)]
38pub struct PoolSettings {
39    pub size: usize,
40}
41
42/**
43 * PoolAccount
44 */
45
46pub trait PoolAccount {
47    fn init(&mut self, name: String, size: usize) -> Result<()>;
48
49    fn rotate(&mut self, worker: Pubkey) -> Result<()>;
50
51    fn update(&mut self, settings: &PoolSettings) -> Result<()>;
52}
53
54impl PoolAccount for Account<'_, Pool> {
55    fn init(&mut self, name: String, size: usize) -> Result<()> {
56        self.name = name;
57        self.size = size;
58        self.workers = VecDeque::new();
59        Ok(())
60    }
61
62    fn rotate(&mut self, worker: Pubkey) -> Result<()> {
63        // Pop a worker out of the pool
64        self.workers.pop_front();
65
66        // Push provided worker into the pool
67        self.workers.push_back(worker);
68
69        // Drain pool to the configured size limit
70        while self.workers.len() > self.size {
71            self.workers.pop_front();
72        }
73
74        Ok(())
75    }
76
77    fn update(&mut self, settings: &PoolSettings) -> Result<()> {
78        self.size = settings.size;
79        Ok(())
80    }
81}