[erlang-questions] advice needed: cleanup after a timeout (using gproc?)

Mihai Balea mihai@REDACTED
Sat Jul 20 00:30:05 CEST 2013

The "traditional" way of doing this would be to keep track of connections yourself by monitoring connection processes and keeping count of them in your main service process.

The gproc approach is elegant and would save you some effort but, as you already realized, you will have problems trying to figure out when the counter goes down to 0.
Polling for 0 in a process would expose you to race conditions, in addition to potentially  not being correct.

Personally, I would probably go with the traditional approach. There might be 3rd party libraries that already implement this pattern, but I am not familiar with any. Anyways, no big deal to implement.

Hope this helps,

On Jul 19, 2013, at 5:31 PM, Paul Rubin wrote:

> I'm running a server that does something sort of similar to inetd.  It sits there quietly until a client connection arrives on a certain socket, at which point it starts up a service which handles client requests.  Starting the service involves spinning up external database connections and some other slightly expensive things.  While the service is running, more client connections (potentially a lot of them arriving very fast) can come and go.  When the last client connection closes, I'd like to keep the service running for another minute or so (to avoid having to restart if new connections arrive soon afterwards), then shut it off if things have stayed quiet.  The 1 minute doesn't have to be precise: let's say anything between 1 and 5 minutes is fine.  There will actually be a lot of similar but separate instances of these services, i.e. there will be maybe a dozen active and a few thousand idle at any given moment.  Expecting clients to update some global state before exiting isn't good, since per Erlang tradition, they might crash ungracefully.
> My thought is to use a gproc aggregated counter to track the number of client connections.  Each new connection spawns a gen_server whose init increments the counter by 1, and the counter automatically decrements when the process terminates (through a monitor in the gproc server, I guess).  I don't see an obvious way for my application to detect when the counter reaches zero.  I can have a separate process waking up once a minute and checking the counts, but that doesn't say that a count has stayed zero for a full minute.  E.g. the count can reach zero at time T, then some connections arrive and quickly exit, so the count is again zero at time T+60.  I suppose I could update a timestamp in some ETS table whenever a connection arrives, but that doesn't seem in Erlang's mutation-avoiding spirit.  
> Another idea is to add "zero-crossing detection" to gproc itself, but before I ask Ulf whether he'd accept such a patch, I thought I'd ask here if the idea is repulsive and if there are easier ways (it seems to me like a pattern potentially common enough to be useful).  The notion is to pass gproc a callback ({M,F,A}) to associate with the counter key, that would get called whenever the aggregated count changes from zero to nonzero or the reverse.  Then I'd supply a callback that starts a timer when the counter reaches zero, and cancels it if the counter becomes nonzero again before the timer expires.  I guess it would be ok for zero crossing to use gproc:send despite the message passing overhead.
> It looks like I can *almost* do this with the conditional publication stuff in gproc_ps.  But I'd need a way to generate events when an aggregated counter changes value, and the publish condition would have to know the internal ETS table representation of the aggregated counter, which doesn't seem good.
> Thanks for any thoughts.
> Paul
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list