Can reference() be stored in a mnesia table?

I am building an application that makes heavy use of Process.send_after/4. This documentation states send_after returns a reference().

My understanding was that mnesia could store any native erlang data type, of which a reference() appears to be one. However, I seem to remember seeing a forum post about mnesia and it’s inability to store pid().

My mnesia table is created with:
:mnesia.create_table(Completions, [attributes: [:name, :expires_at, :reaper_timer], disc_copies: [node()]])

When I try to store the reference() in my mnesia table I get:
{:aborted, {:bad_type, {Completions, "asdf", #Reference<0.1626103600.603717633.51350>}}}

Ultimately I was hoping for a ttl mechanism in mnesia. Failing that I implemented the feature with a process-per timer solution. However given that I could have tens of millions of these timers, I was not super-excited about immediately scaling to 10M+ processes. I know it should be reasonably doable, but it seems like there should be easier ways.

I am definitely working on other workarounds/solutions, but this is a question that has been nagging at me for some time.

Thoughts? Comments? Corrections?

The error message indicates you are writing with a record with 2 attributes but you defined it as a record with 3 attributes. {Completions, "asdf", #Reference<0.1626103600.603717633.51350>}
The first field of the tuple indicates the table mnesia will write to, a throwback to Erlang’s record-tuple relationship.

Short answer is yes you can store reference(),

I’m not sure where you read about mnesia’s inability to store pid() because this is blatantly false. You can store pid() in mnesia, it might not be a smart idea because the process could have died between write/read.

4 Likes

Holy schnikes I am such a dingus. Always read the error carefully! Thanks for the reply!

On the pid() piece, it was only something I thought I remembered. I must be mis-remembering the post.

Thanks again!

2 Likes