Add message store abstraction
Introduce a messageStore type, which will allow for multiple implementations (e.g. in the DB or in-memory instead of on-disk).
The message store is per-user so that we don't need to deal with locking and it's easier to implement per-user limits.