uwiger / gproc

Extended process registry for Erlang
Apache License 2.0
1.07k stars 232 forks source link

Uw resource counts #95

Closed uwiger closed 9 years ago

uwiger commented 9 years ago

(based on PR #94 but doesn't depend on it)

Inspired by #93, and thinking that there is no good way to add threshold monitoring in aggregated counters without noticeable performance penalty (would have been nice if there were).

Work in process. Currently, only local scope implemented, and no docs or test suite.

The idea: A new non-unique type: 'r' (resource), and a new unique type: 'rc' (resource count). 'rc' entries maintain the number of existing 'r' entries with the same name and scope, similar to the relationship between counters and aggregated counters.

Adding an attribute, {'on_zero', Actions} to the 'rc' entry, actions can be triggered when the resource count reaches zero. Currently supported actions are:

Example:

Eshell V5.10.4  (abort with ^G)
1> application:start(gproc).
ok
2> gproc:reg({rc,l,my_r}).
true
3> gproc:get_value({rc,l,my_r}).
0
4> gproc:reg({r,l,my_r}).
true
5> gproc:get_value({rc,l,my_r}).
1
6> gproc:unreg({r,l,my_r}).
true
7> gproc:get_value({rc,l,my_r}).
0
8> gproc:reg_shared({p,l,shared_p}).
true
9> gproc:select([{{{p,l,shared_p},'_','_'},[],['$_']}]).
[{{p,l,shared_p},shared,undefined}]
10> gproc:reg({p,l,p_on_zero}).
true
11> gproc:set_attributes({rc,l,my_r},[{on_zero,[{unreg_shared,p,shared_p},{send,{p,l,p_on_zero}}]}]).
true
12> gproc:reg({r,l,my_r}).
true
13> gproc:unreg({r,l,my_r}).
true                 
14> flush().
Shell got {gproc,resource_on_zero,l,my_r,<0.32.0>}
ok
15> gproc:select([{{{p,l,shared_p},'_','_'},[],['$_']}]).
[]                   
benbro commented 9 years ago

I like the API. This will help creating traffic limiting and shaping with algorithms like leaky bucket.

In the example you lost me at step 8. Not sure how gproc:reg_shared({p, l, value}) is related to 'r' and 'rc'.

uwiger commented 9 years ago

@benbro it's step 11 that links them: The on_zero attribute describes what should happen when the resource count reaches zero, and one possible action is to unregister a shared entry (unregistering an entry owned by the same pid as the rc entry might also be an option).

In step 15, I verify that the shared property really did get deleted.

benbro commented 9 years ago

I might be wrong but it seems that 'r' is similar to shared 'p'. Both let you create a shared key. Do you need both 'p' and 'r' types? Maybe 'rc' can count references to 'p'?

uwiger commented 9 years ago

The problem with adding reference counting to existing types (or 'on_zero' behavior to aggr counters) is that it adds performance overhead (however slight). While one could reference-count shared properties, this seems of limited value, since they have to be explicitly deleted. Process-local properties are registered in the calling process, so there would be a race condition around the 'on_zero' event.

benbro commented 9 years ago

Thanks

benoitc commented 9 years ago

:+1: works perfectly there. All tests pass also. Would be cool to have a release with it soon :)