[erlang-questions] [Code Review] Is this a good idea? I linking 3 process manually (not using recursive)

I Gusti Ngurah Oka Prinarjaya okaprinarjaya@REDACTED
Mon Mar 11 12:03:19 CET 2019


Hi Andreas Schultz,

>> The reason is that there is no guarantee that `call_the_third()` will be
executed after any of the spawn has succeeded or the register was invoked.
1. Did you mean this code? https://pastebin.com/ECf3jhZ2
2. and did you mean spawn_link/3 and register/2 is racy?
3. I've test this code many times, and never get error in each call_the_*
function, even call_the_third/0 function.

Here: https://learnyousomeerlang.com/the-hitchhikers-guide-to-concurrency,
and here: https://learnyousomeerlang.com/more-on-multiprocessing and
here: https://learnyousomeerlang.com/errors-and-processes teach me to do
that. Oh My God, where in this earth i can read the best erlang process
tutorial ? so i can use erlang in the right way.

>> In order to get ordering guarantees you need to wait for the processes
to be past the init stage.
>> The normal way to do that is to wait for a message from the init
function of you child process.
Please give me a short pseudo-code clue to do this. I do really shocked
because of this code: https://pastebin.com/ECf3jhZ2 still not correct after
2 times revision.

Thank you :)



Pada tanggal Sen, 11 Mar 2019 pukul 14.55 Andreas Schultz <
andreas.schultz@REDACTED> menulis:

> You do realize that your code is still "racy" ?
>
> Invoking it like
>
>     2> procslinked:starter(), procslinked:call_the_third().
>
> has a good chance of not producing the expected result. Most times it will
> simply fail with:
>
>     ** exception error: bad argument
>          in function  procslinked:call_the_third/0 (procslinked.erl, line
> 54)
>
> The reason is that there is no guarantee that `call_the_third()` will be
> executed after any of the spawn has succeeded or the register was invoked.
> In order to get ordering guarantees you need to wait for the processes to
> be past the init stage. The normal way to do that is to wait for a message
> from the init function of you child process.
>
> BTW: this is exactly what proc_lib:init_ack does, but I guess you are
> trying to implement that yourself as a learning exercise.
>
> Andreas
>
> I Gusti Ngurah Oka Prinarjaya <okaprinarjaya@REDACTED> schrieb am So.,
> 10. März 2019 um 23:38 Uhr:
>
>> Hi Bengt,
>>
>> Thank you very much for all of your hints and suggestions. It's clear
>> now.
>>
>>
>>
>> Pada tanggal Sen, 11 Mar 2019 05.20, bengt <cean.ebengt@REDACTED>
>> menulis:
>>
>>> I think your code is about learning erlang. Do that first. OTP is the
>>> next step.
>>>
>>> Yes, splitting a gen_server into callback module and interface module is
>>> not the OTP way (as described in documentation), so while good for a
>>> beginner it can be considered bad style by experienced programmers.
>>>
>>> Sorry, but I have not seen any tutorial about how to avoid thinking the
>>> same function/module is always in the same process. It is a very
>>> fundamental concept (them not being) in Erlang, so just keep it in mind.
>>> One way would be to try and make all your three functions the same
>>> function, just have different arguments to the loop. Then you must think
>>> about it.
>>>
>>>
>>> On 10 Mar 2019, at 11:11, I Gusti Ngurah Oka Prinarjaya <
>>> okaprinarjaya@REDACTED> wrote:
>>>
>>> Hi Bengt,
>>>
>>> Thank you for your review :)
>>>
>>> I don't quite understand with some of your thought. Then i hope you not
>>> mind to give more explanation.
>>>
>>> >> Seasoned Erlang programmers will tell you this is not the OTP way, or
>>> a waste of modules
>>> Did you mean my code here: https://pastebin.com/ECf3jhZ2 wasn't the OTP
>>> way?
>>> I learn from here: https://learnyousomeerlang.com/errors-and-processes
>>> and i do really a beginner at programming with erlang.
>>>
>>> >> So only do this until you have a better understanding.
>>> What is that? Did you mean *doing one module with the interface
>>> functions to a gen_server and one module for the gen_server callbacks.?*
>>> or what?
>>>
>>> >> Conflating the function (or even more often, module) and the process
>>> is a common mistake in the beginning. When my fellow programmers are
>>> experienced, but not used >> to process oriented programming.
>>>  Any tutorials / reference for me to avoid this mistake ?
>>>
>>> Thank you :)
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Pada tanggal Min, 10 Mar 2019 pukul 14.49 bengt <cean.ebengt@REDACTED>
>>> menulis:
>>>
>>>> Conflating the function (or even more often, module) and the process is
>>>> a common mistake in the beginning. When my fellow programmers are
>>>> experienced, but not used to process oriented programming, I have found
>>>> that it helps to put the code that is run in different process in different
>>>> modules. Ex: one module with the interface functions to a gen_server and
>>>> one module for the gen_server callbacks. Seasoned Erlang programmers will
>>>> tell you this is not the OTP way, or a waste of modules. So only do this
>>>> until you have a better understanding.
>>>>
>>>> bengt
>>>>
>>>> On 10 Mar 2019, at 04:57, I Gusti Ngurah Oka Prinarjaya <
>>>> okaprinarjaya@REDACTED> wrote:
>>>>
>>>> Hi Bengt,
>>>>
>>>> Thank you for the idea,
>>>>
>>>> I've implement your idea, from performance side, i think using two
>>>> version of function will have better performance because there's no need to
>>>> checking using IF statement.
>>>>
>>>> I worry at first to implement this idea, because i think different
>>>> version of function will have different PID, hahaha it turns out exactly
>>>> have same PID.
>>>> this is  my new code https://pastebin.com/ECf3jhZ2 . Please review if
>>>> there's any improvement needs.
>>>>
>>>> Thank you
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Pada tanggal Min, 10 Mar 2019 pukul 05.23 bengt <cean.ebengt@REDACTED>
>>>> menulis:
>>>>
>>>>> Greetings,
>>>>>
>>>>> The error happens the second time any of the three processes call
>>>>> erlang:register/2. They already registered themselves the first time. If
>>>>> you want this structure, but not the error, you have to do the register
>>>>> before starting the loop. Eg, split the functions into two. One that do the
>>>>> register and then calls the second that does the loop.
>>>>>
>>>>> bengt
>>>>>
>>>>> On 9 Mar 2019, at 14:41, I Gusti Ngurah Oka Prinarjaya <
>>>>> okaprinarjaya@REDACTED> wrote:
>>>>>
>>>>> Hi Attila Rajmund Nohl,
>>>>>
>>>>> After i implement your suggestion, i get error when execute any of
>>>>> function call_the_*_p()
>>>>> for example:
>>>>>
>>>>> 3> newbie:starter().
>>>>> <0.112.0>
>>>>> 4> newbie:call_the_second().
>>>>> =ERROR REPORT==== 9-Mar-2019::20:35:15.069388 ===
>>>>> Error in process <0.113.0> with exit value:
>>>>> {badarg,[{erlang,register,[pidsecondp,<0.113.0>],[]},
>>>>>          {newbie,the_second_p,0,
>>>>>
>>>>> [{file,"/Users/okaprinarjaya/Oprek/Erlang-Oprek/oprek-lagi/src/newbie.erl"},
>>>>>                   {line,17}]}]}
>>>>>
>>>>> {<0.113.0>,"the_second_p()","Halo second p!"}
>>>>>
>>>>> This is my new modified code https://pastebin.com/iYCxkkuz
>>>>>
>>>>>
>>>>> Pada tanggal Jum, 8 Mar 2019 pukul 21.03 Attila Rajmund Nohl <
>>>>> attila.r.nohl@REDACTED> menulis:
>>>>>
>>>>>> I Gusti Ngurah Oka Prinarjaya <okaprinarjaya@REDACTED> ezt írta
>>>>>> (időpont: 2019. márc. 8., P, 12:11):
>>>>>> >
>>>>>> > Hi Folks,
>>>>>> >
>>>>>> > I need your help to review my code. I create and linking 3 process
>>>>>> manually without using recursive. And inside p1 and p2 i using IF statement
>>>>>> to check to make sure spawning process will only once.
>>>>>> >
>>>>>> > I mean, is part code below is a good idea?
>>>>>> >
>>>>>> > IsPidExists = whereis(xxx),
>>>>>> >   if IsPidExists =:= undefined ->
>>>>>> >     Pid = spawn_link(?MODULE, the_p, []),
>>>>>> >     register(xxx, Pid);
>>>>>> >     true -> true
>>>>>> >   end,
>>>>>>
>>>>>> Generally this is not a good idea, there's a race condition between
>>>>>> checking that the process is registered (the whereis/1 call) and
>>>>>> registering the new process. A better idea is to start the process and
>>>>>> let the process itself to register. If register fails, it means that
>>>>>> there's already a process registered, so the just started process can
>>>>>> terminate. So your code could look like something like this:
>>>>>>
>>>>>> starter() ->
>>>>>>   spawn(?MODULE, the_first_p, []).
>>>>>>
>>>>>> the_first_p() ->
>>>>>>   register(pidfirstp, self()),
>>>>>>   spawn_link(?MODULE, the_second_p, []),
>>>>>>   ...
>>>>>>   the_first_p().
>>>>>>
>>>>>> Actually if the register call fails, it throws a badarg and the
>>>>>> process dies automatically, simplifying the code.
>>>>>>
>>>>> _______________________________________________
>>>>> erlang-questions mailing list
>>>>> erlang-questions@REDACTED
>>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> erlang-questions mailing list
>>>>> erlang-questions@REDACTED
>>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>>
>>>>
>>>> _______________________________________________
>>>> erlang-questions mailing list
>>>> erlang-questions@REDACTED
>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>
>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
> --
> --
> Dipl.-Inform. Andreas Schultz
>
> ----------------------- enabling your networks ----------------------
> Travelping GmbH                     Phone:  +49-391-81 90 99 0
> Roentgenstr. 13                     Fax:    +49-391-81 90 99 299
> 39108 Magdeburg                     Email:  info@REDACTED
> GERMANY                             Web:    http://www.travelping.com
>
> Company Registration: Amtsgericht Stendal        Reg No.:   HRB 10578
> Geschaeftsfuehrer: Holger Winkelmann          VAT ID No.: DE236673780
> ---------------------------------------------------------------------
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190311/f818e240/attachment.htm>


More information about the erlang-questions mailing list