Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor supervisor, and store children in a map instead of a list #1602

Merged

Conversation

sirihansen
Copy link
Contributor

This is based on PR-1467, but re-implemented upon a refactored version of supervisor. The refactoring is included in this PR.

For the time being, I have chosen not to remove the child ID from the child record (as suggested in the original PR), since that would only save one word per child and the current solutions gives a bit cleaner code.

@sirihansen sirihansen force-pushed the siri/supervisor/store-children-in-map branch from 3162477 to 8f03f08 Compare October 17, 2017 07:54
@sirihansen sirihansen added enhancement team:MW testing currently being tested, tag is used by OTP internal CI waiting waiting for changes/input from author and removed waiting waiting for changes/input from author labels Oct 17, 2017
{abort,{failed_to_start_child,Id,Reason}}
end
end,
ch_map(Fun,Children).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be easier to understand if you changed Fun to Start and ch_map to children_map so that last
line would read children_map(Start, Children).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree!

{update,Child#child{pid=undefined}}
end,
{ok,NChildren} = ch_map(Fun, Children),
NChildren.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be easier to understand if you changed Fun to Terminate and ch_map to children_map so that next to last line would read {ok, Nchildren} = children_map(Terminate, Children).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! :)

child_type = ChildType, modules = Mods}) ->
{Id, Pid, ChildType, Mods}
end,
State#state.children),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think list_children could be a better name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or children_to_list?? To comply with children_map|fold ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not consistency is normally a good thing :)

end, {0,0,0,0}, State#state.children),
ch_fold(fun(_Id, Child, Counts) ->
count_child(Child, Counts)
end, {0,0,0,0}, State#state.children),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ch_foldl -> children_fold
I think it is not unbearable long and clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do!

Copy link
Contributor

@IngelaAndin IngelaAndin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these changes improves the supervisor and opens up for further improvements.

@sirihansen sirihansen added testing currently being tested, tag is used by OTP internal CI and removed testing currently being tested, tag is used by OTP internal CI labels Oct 24, 2017
@sirihansen sirihansen changed the title Store supervisor's children in a map instead of a list Refactor supervisor, and store children in a map instead of a list Oct 30, 2017
start_children(Children, SupName) ->
Start =
fun(Id,Child) ->
case do_start_child(SupName, Child) of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for a comment on the style but I believe this is indented too much.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually a bit strange - it's the indentation done by the erlang emacs mode on funs... I will check why...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, this is a correct indentation - it is like this to cover for a combination of multiple fun clauses in combination with newline before guards.. e.g.

fun(X)
      when X > 0 ->
        positive;
   (X)
      when X < 0 ->
        negative;
   (0) ->
        zero
end

... and the main problem lies in the second clause, where it would be very strange if one indentation level was removed:

fun(X)
  when X > 0 ->
    positive;
   (X)
  when X < 0 ->
    negative;
   (0) ->
    zero
end

start_children([], NChildren, _SupName) ->
{ok, NChildren}.
start_children(Children, SupName) ->
Start =

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason why this function is inline instead of being its own named function? It would help make stacktraces more clear, imo, if the Start function was named something like attempt_start_child/2 or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, there is no particular reason for this. I'll make it a separate function. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I answered this one a bit too quickly. The reason for it being inline is that it uses the bound variable SupName. Moving it out would make the code less clean, and I don't believe that it is really justified by the gain. As is, the stack trace of a crashed child start function is as follows:

** exception exit: {shutdown,
                       {failed_to_start_child,1,
                           {'EXIT',
                               {undef,
                                   [{test_gen_server,start_link,[],[]},
                                    {supervisor,do_start_child_i,3,[{file,"supervisor.erl"},{line,365}]},
                                    {supervisor,do_start_child,2,[{file,"supervisor.erl"},{line,351}]},
                                    {supervisor,'-start_children/2-fun-0-',3,[{file,"supervisor.erl"},{line,335}]},
                                    {supervisor,ch_map,4,[{file,"supervisor.erl"},{line,1148}]},
                                    {supervisor,init_children,2,[{file,"supervisor.erl"},{line,301}]},
                                    {gen_server,init_it,2,[{file,"gen_server.erl"},{line,369}]},
                                    {gen_server,init_it,6,[{file,"gen_server.erl"},{line,337}]}]}}}}

which I believe is clear enough.

{abort,{failed_to_start_child,Id,Reason}}
end
end,
children_map(Start,Children).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be children_map(fun attempt_start_child/2, Children).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I see your function closes over SupName. Thanks for considering it.

@sirihansen sirihansen force-pushed the siri/supervisor/store-children-in-map branch from 53296db to 9cdceb1 Compare November 8, 2017 10:26
@sirihansen sirihansen force-pushed the siri/supervisor/store-children-in-map branch from 9cdceb1 to 18bddf3 Compare November 9, 2017 14:16
@sverker sverker removed the testing currently being tested, tag is used by OTP internal CI label Nov 9, 2017
@sirihansen sirihansen added the testing currently being tested, tag is used by OTP internal CI label Nov 10, 2017
@sirihansen sirihansen force-pushed the siri/supervisor/store-children-in-map branch from 18bddf3 to a03895d Compare November 14, 2017 13:51
@sirihansen sirihansen merged commit 41e6eaa into erlang:master Nov 15, 2017
@sirihansen sirihansen removed the testing currently being tested, tag is used by OTP internal CI label Nov 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants