The MatrixAttribute caches rows for each record, both as an array and as a json string, to facilitate faster retrieval of arbitrary rows/columns without having to dip into postgres and deserialize JSON all the time.
However, since this caching occurs in a variable in ruby, it won't be shared between threads. Each thread will have its own MatrixAttribute object with its own cache of the data.
This is bad. First, we aren't sharing the cache between threads. Second, we aren't sharing the invalidation between threads.
At first it seemed to me the obvious solution was to use a Redis cache shared between threads - but this doesn't allow us to take advantage of in-memory caching in our Ruby process - it would pretty much only allow json string caching. Since we don't want to proliferate hundreds of cached versions of all of the possible slices of our matrix, we can essentially only cache entire rows of the matrix as json in Redis (i.e. @cached_rows_json in the MatrixAttribute). The in-memory cache (@cached_rows) allows us to make slices quickly, but can't be shared across threads.
One possible solution is a little matrix microservice - each of the threads can ask for slices from this microservice, which can also talk to postgres and get its own data. The threads also post invalidations to this service.
In the interim the only way to reset the cache is to restart the magma service.
The MatrixAttribute caches rows for each record, both as an array and as a json string, to facilitate faster retrieval of arbitrary rows/columns without having to dip into postgres and deserialize JSON all the time.
However, since this caching occurs in a variable in ruby, it won't be shared between threads. Each thread will have its own MatrixAttribute object with its own cache of the data.
This is bad. First, we aren't sharing the cache between threads. Second, we aren't sharing the invalidation between threads.
At first it seemed to me the obvious solution was to use a Redis cache shared between threads - but this doesn't allow us to take advantage of in-memory caching in our Ruby process - it would pretty much only allow json string caching. Since we don't want to proliferate hundreds of cached versions of all of the possible slices of our matrix, we can essentially only cache entire rows of the matrix as json in Redis (i.e. @cached_rows_json in the MatrixAttribute). The in-memory cache (@cached_rows) allows us to make slices quickly, but can't be shared across threads.
One possible solution is a little matrix microservice - each of the threads can ask for slices from this microservice, which can also talk to postgres and get its own data. The threads also post invalidations to this service.
In the interim the only way to reset the cache is to restart the magma service.