2
votes

Say I have a supervisor sup supervise some workers, when a worker started, it register itself with some name, like worker_1, worker_2, etc.. When worker_N crashed and get restarted by sup, how to register the newly created process as worker_N, i.e., how to let the name of a worker survive a restart?

How to restart child with custom state using Erlang OTP supervisor behaviour? gives no answer, since I only want the name, there maybe a solution.

1

1 Answers

3
votes

You could have the worker register itself when it is started by having it call register(Name, self()) in init and passing Name as an argument there. This is global across the node, so it doesn't matter what process does the registering.

BUT

It looks like you are dynamically creating atoms because you want to use registered processes everywhere. This is a very common mistake -- but there is hope!

Instead of dynamically creating atoms to name every child worker in existence, consider a few things first:

  • You don't need them all named. Workers have a limited job description (and if they don't you have bigger problems) and they are nearly always tied to their resources, their caller or their spawner, who already knows them.
  • You do need them named (but really, you probably don't) because they represent concrete elements of a large system, like a location in a game, a channel in chat, your stalking victim's Twitter feed, etc. Name them a different way, by keeping a digest of [{Key, Value}] where [{AnyTerm, Pid}]. This lets you know more about the process by looking at its name and keeps the global spaces of your system free of private worker detritus.

There's more...

If you are naming processes integers you are either making the same mistake countless web developers make when using relational databases (making everything have an integer primary key), or you are dealing with workers that don't need names.

If you actually do need them named (it happens), consider using the global module (it lets you name any process any term you want, and the names are usable across all nodes -- magic!), "process groups" in the pg2 module, or gproc (a library written to handle this exact problem, and also lets you use any term you want to name processes).

A personal note

If you ever find yourself in a situation where generating dynamic atoms seems like a good idea (for whatever reason) you should always stop whatever you are doing and think very hard about what you are doing. This is because generating atoms is a strong indication that you're doing it wrong. Try to discover why you are fighting the system so hard -- Erlang isn't meant to work that way.

In every case I've either encountered in my own code or witnessed in the work of others, this sort of thing is a sign that a cleaner, more Erlangy way of doing things exists, and everything just gets easier if I discover whatever that way is instead of adding more layers to the big knot of tangled logic I'm working on. The good news is that accumulating Erlang idioms is quick and they are hard to forget because they usually make so much sense in retrospect (nearly always you find you were reinventing the wheel before discovering the accepted solution -- and wind up with a "ah, great minds think alike" feeling at the end).