[erlang-questions] Why does adding an io:format call make my accept socket remain valid?

Matthew Shapiro <>
Mon Mar 28 03:34:16 CEST 2016


Why is that?  I was under the impression that one of the advantages was
that you can test the handle call/cast/info functions without having to
stand up a full server to do a small surface area unit test.

On Sun, Mar 27, 2016 at 5:43 PM, Robert Virding <> wrote:

> To be even more specific all the 6 gen_server callbacks[*] must always be
> run within the gen_server process, this irrespective of whether you are
> testing or not.
>
> Robert
>
> [*] init/1, terminate/2, handle_call/3, handle-cast/2, handle_info/2,
> code_change/3.
>
> On 27 March 2016 at 15:13, Matthew Shapiro <> wrote:
>
>> Well duh, now I feel like an idiot.
>>
>> Thanks,
>>
>> On Sun, Mar 27, 2016 at 5:31 AM, Vimal Kumar <> wrote:
>>
>>> Matthew,
>>>
>>> Like Nathaniel said, the eunit test should involve gen_server. Do not
>>> test handle_cast/2 directly. Instead, run your test on an exported function
>>> (say: Module:accept/0) which in turn should execute:
>>>
>>> gen_server:cast(?MODULE, accept)
>>>
>>> You can start a gen_server process, execute such tests and shut it down
>>> properly using 'setup' Fixture:
>>> http://learnyousomeerlang.com/eunit#fixtures
>>>
>>> Regards,
>>> Vimal
>>>
>>> On Sun, Mar 27, 2016 at 10:15 AM, Nathaniel Waisbrot <
>>> > wrote:
>>>
>>>> I don't know about your garbage-collection question, but:
>>>>
>>>> > Why does that io:format/3 call (only when after the spawn/3 call)
>>>> keep the socket open and active for the spawned process?  I wouldn't expect
>>>> it to be garbage collected because the spawned process holds a reference to
>>>> it (and even adding it to the State in the return doesn't fix it).  Only
>>>> other thing I could think of was that handle_cast is run in it's own
>>>> process which closes the socket when it dies (since it has ownership), but
>>>> that doesn't make sense from what I've read about OTP.
>>>>
>>>>
>>>> Normally handle_cast would be run in the gen_server's process (since
>>>> that's the whole point), but it looks to me like in your test:
>>>>
>>>>
>>>> >   spawn_link(fun () -> tcp_listener_server:handle_cast(accept, State)
>>>> end),
>>>>
>>>>
>>>> you are bypassing gen_server and instead ... telling handle_cast to run
>>>> in its own one-off process.
>>>>
>>>>
>>>> Do you mean to be doing this? In your test code, you could call
>>>> gen_server:start/1 and then gen_server:cast/2 and get the actual gen_server
>>>> behavior.
>>>>
>>>> _______________________________________________
>>>> erlang-questions mailing list
>>>> 
>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160327/28b97d9e/attachment.html>


More information about the erlang-questions mailing list