Retrieving zero answers using mnemosyne

Sean Hinde <>
Tue Dec 21 20:08:20 CET 1999


Thanks Hakan,

I gave up and decided to implement separate tables for free and busy lists
(which is what this thing does).

This still leaves the problem of picking one entry from the free list
table..

The solution I have tried is to use mnesia:dirty_first/1 in the transaction.

This actually works, but with goodness knows what potential side effects!
What happens if I put a write lock on the table then call
mnesia:dirty_first/1? Surely if nothing can write to the table then I am
safe...?


Also, I've done a bit more digging on the mnemosyne problem. My code hangs
in the line containing mnemosyne:next_answers(Cursor,1,1). Mnemosyne appears
to get into an infinite loop in mnemosyne_exec:pending/10 while it is
waiting for the answer which will never come.

The documentation is also a little vague as it states that "If less than
Nmin answers are returned; for example, 0, there are no more answers. If
enough answers are not available, but more are expected the functions wait
for them"

This seems to imply that if there are less than Nmin answers available we
will wait forever.  As the minimum value for Nmin is 1, any time there are 0
answers available we wait.

Thoughts?

And... has anyone else out there implemented a free/busy list in erlang
which they could share with us?

Sean

-----Original Message-----
From: Hakan Mattsson [mailto:]
Sent: 21 December 1999 18:33
To: Sean Hinde
Cc: 
Subject: Re: Retrieving zero answers using mnemosyne


On Tue, 21 Dec 1999, Sean Hinde wrote:

Sean> I am writing an application which will retrieve zero or one answers
from a
Sean> mnemosyne query but have hit a problem.
Sean> 
Sean> mnemosyne:next_answers/3 appears to be the only way to get a single
answer
Sean> from a match type query but if there are no matches it hangs. The
obvious
Sean> thing to do is set Nmin to 0 but this is not allowed.
Sean> 
Sean> Has anyone come across this problem before or have any suggestions of
how to
Sean> retrieve a single match out of potentially more then one result?

Which version of Mnemosyne do you use?
In earlier versions Mnemosyne had the problem of not returning any
answers even if there was matching records. I think hovewer that
this issue has been fixed.

I don't really know why Mnemosyne hangs in your query, but I suspect
that it is the mnesia:write/1 call inside the query that is the problem.
In fact, a query is not allowed to have any side effects at all.

Picking just one answer looks rather nice in the Mnemosyne API, but in
fact all answers are fetched and allocated on the heap, possibly sent
as messages between a couple of processes and eventually one answer is
returned to you. A plain:

    assign(User) ->
        Wild = mnesia:table_info(ip_pool, wild_pattern),
        case mnesia:match_object(Wild#ip_pool{user = []}) of
            [] ->
                mnesia:abort(no_spare_ip_addresses);
            [IP | _] ->
                mnesia:write(#ip_pool{ip = IP,
                                      user = User,
                                      timestamp = now()}),
                IP
	end.
   
    mnesia:transaction(fun assign/1, [User]).

is a more efficient way to just pick one answer and then possibly
update the matching record. (And it does not hang.)

/Håkan

Sean> 
Sean> Thanks,
Sean> 
Sean> Sean
Sean> 
Sean> %% Example of what I am trying to achieve..
Sean> assign(User) ->
Sean>     Handle = 
Sean> 	query
Sean> 	    [ I.ip || I <- table(ip_pool),
Sean> 		      I.user == [] ]
Sean> 	end,
Sean>     F = fun() ->
Sean> 		Cursor = mnemosyne:cursor(Handle),
Sean> 		case mnemosyne:next_answers(Cursor,1,1) of
Sean> 		    [] ->
Sean> 			mnesia:abort(no_spare_ip_addresses);
Sean> 		    [IP] ->
Sean> 			mnesia:write(#ip_pool{ip = IP,
Sean> 					      user = User,
Sean> 					      timestamp = now()}),
Sean> 			mnemosyne:delete_cursor(Cursor),
Sean> 			IP
Sean> 		end
Sean> 	end,
Sean>     mnesia:transaction(F).
Sean> 



More information about the erlang-questions mailing list