clockwork_pool_program/objects/
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 pubkey(&self) -> Pubkey;
48
49    fn init(&mut self, name: String, size: usize) -> Result<()>;
50
51    fn rotate(&mut self, worker: Pubkey) -> Result<()>;
52
53    fn update(&mut self, settings: &PoolSettings) -> Result<()>;
54}
55
56impl PoolAccount for Account<'_, Pool> {
57    fn pubkey(&self) -> Pubkey {
58        Pool::pubkey(self.name.clone())
59    }
60
61    fn init(&mut self, name: String, size: usize) -> Result<()> {
62        self.name = name;
63        self.size = size;
64        self.workers = VecDeque::new();
65        Ok(())
66    }
67
68    fn rotate(&mut self, worker: Pubkey) -> Result<()> {
69        // Pop a worker out of the pool
70        self.workers.pop_front();
71
72        // Push provided worker into the pool
73        self.workers.push_back(worker);
74
75        // Drain pool to the configured size limit
76        while self.workers.len() > self.size {
77            self.workers.pop_front();
78        }
79
80        Ok(())
81    }
82
83    fn update(&mut self, settings: &PoolSettings) -> Result<()> {
84        self.size = settings.size;
85        Ok(())
86    }
87}