-
Notifications
You must be signed in to change notification settings - Fork 0
Caching Users in App
The UserAccount struct is defined as follows:
struct UserAccount {
username: String,
password: String,
id: Option<i32>,
pending_orders: AccountPendingOrders,
recent_trades: Vec<Trade>,
recent_markets: HashMap<String, i32>,
modified: bool
}
Of these fields, the most interesting are the last 4: pending_orders, recent_trades, recent_markets and modified. We explain each field below.
-
pending_orders: A struct that stores the pending orders belonging to this user. -
recent_trades: The trades that this user has been a part of since they were brought into cache. -
recent_markets: A HashMap of {market symbol: pending order count}, wherepending order countis the change in the number of pending orders in that market since the user was brought into cache. For example, if the user has had 1 order in$FBfilled, they would have {$FB: -1}. -
modified: A bool that simply represents whether this user has been modified since the Buffers were flushed. I am not sure that this is needed any longer, as it was originally used for cache eviction (which we now do in other ways).
TODO: Write about the actual Users struct, and the id_map.
We set a limit on the number of users in the cache at compile time. I'm not particularly happy with this, since it doesn't take physical RAM limits into consideration, but I figure if we cap it at a low enough number, we can avoid -ENOMEM.
We try to decrease memory usage by only calling fetch_account_pending_orders if absolutely necessary, but I suspect that after some time the entire cache will be full of accounts with full views of their orders, since we prioritize eviction of empty accounts.
We evict users once we've reached +90% of our cache capacity. The process is simple, we scan the cache and try to evict any account that hasn't called fetch_account_pending_orders. We do this because we want to avoid calling it again for accounts that already have that information. Realistically, a better caching mechanism would probably be considering average access frequency (or something like that).
When an account is evicted from cache, we flush the recent_trades and recent_markets to Redis. See the Trades and Pending Orders sections of the Redis page on the Wiki for explanations of how these are stored.