uwiger / locks

A scalable, deadlock-resolving resource locker
Mozilla Public License 2.0
204 stars 26 forks source link

compile error in r16 #3

Closed sendtopms closed 10 years ago

sendtopms commented 10 years ago

rebar compile ==> examples (compile) ==> locks (compile) src/locks_agent.erl: error in parse transform 'locks_watcher': {{badmatch, {ok, {locks_watcher, [{abstract_code, no_abstract_code}]}}}, [{locks_watcher,get_exprs,2, [{file,"src/locks_watcher.erl"}, {line,111}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,71}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,96}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,100}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,95}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,98}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,98}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,100}]}]} make: *\ [compile] Error 1

uwiger commented 10 years ago

I can't reproduce that. The no_abstract_code error means that it can't find the debug_info. I'm not sure how that can be, since the locks_watcher.erl module has the -compile(debug_info) hard-coded in the source.

sendtopms commented 10 years ago

I am Erlang OTP R16 (R16B03-1), is that an issue?

uwiger commented 10 years ago

I have tried with R16B02 and R16B03. Have you tried running rebar clean compile?

sendtopms commented 10 years ago

I tried but got same error

$ rebar clean compile ==> examples (clean) ==> locks (clean) ==> examples (compile) Compiled src/gdict.erl src/test_cb.erl:39: Warning: behaviour locks_leader undefined Compiled src/test_cb.erl ==> locks (compile) Compiled src/locks_watcher.erl src/locks_leader.erl:129: Warning: opaque type election() is not exported Compiled src/locks_leader.erl Compiled src/locks_app.erl Compiled src/locks.erl Compiled src/locks_cycles.erl Compiled src/locks_sup.erl src/locks_agent.erl: error in parse transform 'locks_watcher': {{badmatch, {ok, {locks_watcher, [{abstract_code, no_abstract_code}]}}}, [{locks_watcher,get_exprs,2, [{file,"src/locks_watcher.erl"}, {line,110}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,70}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,95}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,99}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,94}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,97}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,97}]}, {locks_watcher,transform,1, [{file,"src/locks_watcher.erl"}, {line,99}]}]}

uwiger commented 10 years ago

Is your locks repository current? Can you try with a clean checkout of master?

sendtopms commented 10 years ago

Thank you Ulf, I actually got old version of rebar, I updated it and now it is compiling.

uwiger commented 10 years ago

Glad it was resolved.

sendtopms commented 10 years ago

thanks

sendtopms commented 10 years ago

Ulf, Can you guide me to the simple example of begin_transaction and end_transaction. Do I need to implement lock_leader for all the cases or can I just use begin/end transaction?

uwiger commented 10 years ago

Sure. You don't need to use lock_leader in order to use locking. Lock_leader is implemented on top of the locker.

Eshell V5.10.3  (abort with ^G)
1> application:start(locks).
ok
2> F = fun() ->
           {ok,A} = locks:spawn_agent(),
           try locks:lock(A,[lock],write),
                io:fwrite("~p: ~p has the lock!~n", [time(),self()]),
                timer:sleep(15000)
           after
              locks:end_transaction(A)
           end, receive stop -> ok end
        end.          
#Fun<erl_eval.20.80484245>
3> {P1 = spawn(F), P2 = spawn(F)}.
{<0.41.0>,<0.42.0>}
{10,26,34}: <0.41.0> has the lock!
{10,26,49}: <0.42.0> has the lock!
4> erlang:is_process_alive(P1).
true

In the above case, we have two processes trying for the same lock. P1 gets it first, sits on it for 15 seconds, then ends the transaction, at which time P2 gets the lock.

If the process that started a transaction dies, the lock is automatically released.

5> f(P1),f(P2), {P1 = spawn(F), P2 = spawn(F)}.
{10,31,40}: <0.47.0> has the lock!
{<0.47.0>,<0.48.0>}
6> exit(P1,kill).
{10,31,48}: <0.48.0> has the lock!
true
sendtopms commented 10 years ago

Thank you Ulf, I could not locate locks:spawn_agent() instead can I use begin transaction locks:begin_transaction

uwiger commented 10 years ago

Ouch, sorry. That is a function I have not yet pushed (note to self: push those changes soon)

locks:begin_transaction() does [roughly] the same thing, but is synchronous, and has a different return value.

sendtopms commented 10 years ago

Ohh.... when can I expect new APIs? For meantime should i use {ok, A} = locks_agent:start_link(). ?

uwiger commented 10 years ago

Yes, that's the one I used to use. Then I introduced spawn_agent() for performance reasons.

Most of the upcoming changes are performance-related, specifically aimed at scalability.

sendtopms commented 10 years ago

Great expecting to use it in my project.

uwiger commented 10 years ago

I pushed my local changes to the branch uw-optimizations and created a pull request, #4 .

Feedback is welcome. I would like to do some more testing work before merging it.

sendtopms commented 10 years ago

Thanks for the new code. I will try to test it later today.