pid lookup via global

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

pid lookup via global

Nato-3
Hi list

I have a gen_statem where I am creating simple_one_for_one
children and using the global+term strategy. So each child's
key, as it were, is a term. I have read the manuals for
global, supervisor, sys, and can't seem to find a way to
reverse lookup a child's id, via its known Pid. I suppose
I was expecting global to have a way to do this... something
I'm missing, no doubt.

Right now, via a collect on `supervisor:which_children(foo_sup)`
I can access the child Pids, and in an unsavory way, for
each, matching on a whopper term via `sys:get_status/1`
I can extract the Id in a `header' tuple. Is there
another way?



--
Nato
Reply | Threaded
Open this post in threaded view
|

Re: pid lookup via global

Karl Velicka
Hi,

Firstly - I think that your use case is not quite what global is made for.

In my company's codebase we have a behaviour called tracked_supervisor which does almost exactly what you're describing - it has a simple_one_for_one supervisor for supervising some children where each child has a unique id (which is just a term) and there's also a tracker module (a gen_server) which is responsible for starting the children and keeping the pid->name mapping in an ETS table. Our behaviour does not do the reverse lookup (pid -> name) but it would be trivial to add such a feature.

There's also a library called Director that seems to do something similar - https://github.com/pouriya/director, however it round-trips a process for every lookup which may be unacceptable performance-wise (lookups in both global and aforementioned tracked_supervisor are direct ETS reads).

Last but not least, I'd recommend that you look into the global module itself (lib/kernel/src/global.erl in the OTP repo). It's not complicated and you can see what the shape of the data in its ETS table is. With that knowledge you could use ets:match to get the name of your pid directly from global's ETS table. However, this is NOT something I would recommend unless you're _certain_ you know what you're doing - I'm sure that the OTP team makes no guarantee that internal data structures retain their shape so code relying on such details may break one day with no warning whatsoever! I only mention this to encourage people to not be afraid to look under the covers of the OTP platform because a number of often used modules are implemented in plain Erlang so it's not at all difficult to understand how they work.

Hope this helps!

Karl

On Fri, 8 May 2020 at 09:14, Nato <[hidden email]> wrote:
Hi list

I have a gen_statem where I am creating simple_one_for_one
children and using the global+term strategy. So each child's
key, as it were, is a term. I have read the manuals for
global, supervisor, sys, and can't seem to find a way to
reverse lookup a child's id, via its known Pid. I suppose
I was expecting global to have a way to do this... something
I'm missing, no doubt.

Right now, via a collect on `supervisor:which_children(foo_sup)`
I can access the child Pids, and in an unsavory way, for
each, matching on a whopper term via `sys:get_status/1`
I can extract the Id in a `header' tuple. Is there
another way?



--
Nato
Reply | Threaded
Open this post in threaded view
|

Re: pid lookup via global

Nato-3
Karl,

Yes. This helps tremendously. Thank-you!



--
Nato