Note that there are some explanatory texts on larger screens.

plurals
  1. POhow do we efficiently handle time related constraints on mnesia records?
    primarykey
    data
    text
    <p>i am writing records into mnesia which should be kept there only for an allowed time (24 hours). after 24 hours, before a user modifies part of them, the system should remove them automatically. forexample, a user is given free airtime (for voice calls) which they should use in a given time. if they do not use it, after 24 hours, the system should remove these resource reservation from the users record.</p> <p>Now, this has brought in timers. an example of a record structure is:</p> <pre> -record(free_airtime, { reference_no, timer_object, %% value returned by timer:apply_after/4 amount }). </pre> <p>The timer object in the record is important because in case the user finally puts to use the resources reserved before they are timed out (or if they time out),the system can call <code>timer:cancel/1</code> so as to relieve the timer server from this object. Now the problem, i have two ways of handling timers on these records:</p> <p>Option 1: timers handled within the transaction</p> <pre> reserve_resources(Reference_no,Amnt)-&gt; F = fun(Ref_no,Amount) -&gt; case mnesia:read({free_airtime,Ref_no}) of [] -&gt; case mnesia:write(#free_airtime{reference_no = Ref_no,amount = Amount}) == ok of true -&gt; case timer:apply_after(timer:hours(24),?MODULE,reference_no_timed_out,[Ref_no]) of {ok,Timer_obj} -&gt; [Obj] = mnesia:read({free_airtime,Ref_no}), mnesia:write(Obj#free_airtime{timer_object = Timer_obj}); _ -&gt; mnesia:abort({error,failed_to_time_object}) end; false -&gt; mnesia:abort({error,write_failed}) end; [_] -&gt; mnesia:abort({error,exists,Ref_no}) end end, mnesia:activity(transaction,F,[Reference_no,Amnt],mnesia_frag). </pre> <p>About the above option.</p> <p>Mnesia docs say that transactions maybe repeated by the tm manager (due to some reason) until they are successful, and so when you put code which is <code>io:format/2</code> or any other which has nothing to do with writes or reads, it may get executed several times. This statement made me pause at this point and think of a way of handling timers out of the transaction it self, so i modified the code as follows:</p> <p>Option 2: timers handled outside the transaction</p> <pre> reserve_resources(Reference_no,Amnt)-&gt; F = fun(Ref_no,Amount) -&gt; case mnesia:read({free_airtime,Ref_no}) of [] -&gt; P = #free_airtime{reference_no = Ref_no,amount = Amount}, ok = mnesia:write(P), P; [_] -&gt; mnesia:abort({error,exists,Ref_no}) end end, Result = try mnesia:activity(transaction,F,[Reference_no,Amnt],mnesia_frag) of Any -&gt; Any catch exit:{aborted,{error,exists,XX}} -&gt; {exists,XX} E1:E2 -&gt; {error,{E1,E2}} end, on_reservation(Result). on_reservation(#free_airtime{reference_no = Some_Ref})-&gt; case timer:apply_after(timer:hours(24),?MODULE,reference_no_timed_out,[Some_Ref]) of {ok,Timer_obj} -&gt; [Obj] = mnesia:activity(transaction,fun(XX) -&gt; mnesia:read({free_airtime,XX}) end,[Some_Ref],mnesia_frag), ok = mnesia:activity(transaction,fun(XX) -&gt; mnesia:write(XX) end,[Obj#free_airtime{timer_object = Timer_obj}],mnesia_frag); _ -&gt; ok = mnesia:activity(transaction,fun(XX) -&gt; mnesia:delete({free_airtime,XX}) end,[Some_Ref],mnesia_frag), {error,failed_to_time_object} end; on_reservation(Any)-&gt; Any. </pre> <p>The code to handle time out of the reservation:</p> <pre> reference_no_timed_out(Ref_no)-&gt; do_somethings_here..... then later remove this reservation from the database....below.. ok = mnesia:activity(transaction,fun(XX) -&gt; mnesia:delete({free_airtime,XX}) end,[Ref_no],mnesia_frag). </pre> <p>Now i thought that in option 2, i am safer by keeping the timer processing code out, even when mnesia_tm re-executes the transaction due to its reasons , this piece of code is not run twice (i avoid having several timer objects against the same record).</p> <p><b>Question 1:</b> Which of these two implementations is right? and/or wrong? Tell me (also) wether both of them are wrong</p> <p><b>Question 2:</b> The module timer, is it well suited for handling large numbers of timer jobs in production?</p> <p><b>Question 3:</b> As compared to Sean Hinde's <b><a href="http://cean.process-one.net/packages/index.yaws?action=detail&amp;name=timer_mn" rel="nofollow">timer_mn-1.1</a></b>, which runs on top of mnesia, is the timer module (possibly running on top of Ets tables) less capable (for real) in production? (am asking this because using Sean Hinde's timer_mn on a system which itself is using mnesia appears to be a problem in terms schema changes, node problems e.t.c)</p> <p>If any one has another way of handling timer related problems with mnesia, update me thanx guys...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload