sasa1977 / con_cache

ets based key/value cache with row level isolated writes and ttl support
MIT License
910 stars 71 forks source link

Persistent cache with :file2tab doesn't work #52

Closed MikaAK closed 5 years ago

MikaAK commented 5 years ago

Trying to follow #18 for persistent caching.

It seems that trying to save the cache to a tab using :file2tab works but restoring the cache doesn't

ConCache.put(:table_name, :test, "hello")

:table_name
  |> ConCache.ets
  |> :ets.tab2file('file-path.tab')

# restart and inside start_link
{:ok, ref} = :ets.file2tab('file-path.tab')
# reference returned by this is wrong and not the 
# same as `ConCache.ets(:table_name)`

:ets.tab2list(ref) # [test: "hello"]
ConCache.get(:table_name, :test) # nil
sasa1977 commented 5 years ago

Hi,

Just invoking :ets.file2tab is not sufficient. As you mention in the code comment, this creates a new ETS table, but that's not the table managed by ConCache, so your data is not yet in the cache.

After you load this table, you need to iterate the table and store each element into ConCache using ConCache.put. Once you're done with that, you should drop the table created via :ets.file2tab.

One downside here is that during priming you have two copies of the data. The one is in the temp table, another in the cache. The first copy is dropped once you prime your ConCache table, but during priming you'll use more memory than you need. Depending on the amount of the cached data, this might or might not be a problem. If it is, consider using some "iterable" persistence format, which allows you to load each entry one by one, instead of loading everything at once.

Let me know if you have further questions.

MikaAK commented 5 years ago

That does seem like a few extra hoops to jump through. Since the dataset being cached can get quite large it doesn't feel like this is a great option as there's a cost. PersistentETS may be better for what we need but it's good to know how to get persistent caching working.