How to write a generic IRC client the OTP way?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Ale
Reply | Threaded
Open this post in threaded view
|

How to write a generic IRC client the OTP way?

Ale
Hello All,

As a learning experience I want to make a generic IRC client. My
question is regarding the path to genericness, what would be the right
way to do this, or the OTP way?

At first I thought that I could use gen_server to hide logic there. A
client would call gen_server:call(ircclient, {nick, ale}) to set the
nickname for example. Since call is synchronous, and setting the nick
in irc, might take a couple of (micro)seconds, the process calling
will have to wait until it receives an answer and the client (calling
gen_server) might loose some interactivity (or the ability to do
something else while the response of the "NICK" irc command comes
back)

The next thought was to use gen_server:cast(ircclient, {nick, ale}),
but then how would the client would get the response? As far as I
understood there is no way to get a deferred reply from gen_server.
The calling process has to wait, even if we use gen_server:call with
norepley and then gen_server:reply (which as far as I understood it is
useful, when making the gen_server container or process non blocking).

I could pass a callback function to gen_server:call, like this
gen_server:cast(ircclient, {nick, ale, fun CallbackFun/1}), and
CallbackFun takes the result and does something with it. This migh
work, but then that doesn't look very "OTP" to me.

This is what I'm having trouble the most understanding if "gen_*"
processes can call back in a deferred manner to the client using the
"gen_*" process.  "Hey gen_server, call me back when you get this
done".

Probably my design is wrong?

Finally researching a bit, I thought that it might be a good idea to
write a behaviour. But the same question comes up, how do I callback
the client? (diagram: http://i.imgur.com/6N6Je.png)

Hopefully I explained my problem, and questions.

Thanks,

Regards,
--
Ale.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: How to write a generic IRC client the OTP way?

Jon Watte
A client would call gen_server:call(ircclient, {nick, ale}) to set the nickname for example.
The "Erlang Way" is said to be to export actual functions (setnick, getnick, ...) from the gen_server module public API, and have those functions do the gen_server calls. This means that you can change the gen_server message format without breaking compatibility.
 
Also, for synchronous calls (where you want the status), waiting the necessary amount of time is pretty much what you expect to do. You *can* make arrangements to use cast, and pass in a respond-to-PID parameter as part of the request, but in most cases, that adds significant extra complexity for very little benefit.
 
Note that gen_server:call also takes a timeout parameter -- it defaults to 5,000 milliseconds, so if the gen_server is "wedged" then the timeout will kick in.
 
Sincerely,
 
jw

--
Americans might object: there is no way we would sacrifice our living standards for the benefit of people in the rest of the world. Nevertheless, whether we get there willingly or not, we shall soon have lower consumption rates, because our present rates are unsustainable.


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: How to write a generic IRC client the OTP way?

mazenharake
In reply to this post by Ale
Try eirc here: https://github.com/mazenharake/eirc

Trying to do synchronous IRC is doomed to fail imho. eirc sends a
message everytime you get an event/response and by keeping your own
state you put context to these events to know what they mean. IRC
wasn't really made for computer programs but rather for a telnet
prompt so that is why this protocol is flawed in many ways (but very
easy).

eirc is under the 2-clause BSD license so do what ever you want with it.

On 30 June 2011 04:06, Ale <[hidden email]> wrote:

> Hello All,
>
> As a learning experience I want to make a generic IRC client. My
> question is regarding the path to genericness, what would be the right
> way to do this, or the OTP way?
>
> At first I thought that I could use gen_server to hide logic there. A
> client would call gen_server:call(ircclient, {nick, ale}) to set the
> nickname for example. Since call is synchronous, and setting the nick
> in irc, might take a couple of (micro)seconds, the process calling
> will have to wait until it receives an answer and the client (calling
> gen_server) might loose some interactivity (or the ability to do
> something else while the response of the "NICK" irc command comes
> back)
>
> The next thought was to use gen_server:cast(ircclient, {nick, ale}),
> but then how would the client would get the response? As far as I
> understood there is no way to get a deferred reply from gen_server.
> The calling process has to wait, even if we use gen_server:call with
> norepley and then gen_server:reply (which as far as I understood it is
> useful, when making the gen_server container or process non blocking).
>
> I could pass a callback function to gen_server:call, like this
> gen_server:cast(ircclient, {nick, ale, fun CallbackFun/1}), and
> CallbackFun takes the result and does something with it. This migh
> work, but then that doesn't look very "OTP" to me.
>
> This is what I'm having trouble the most understanding if "gen_*"
> processes can call back in a deferred manner to the client using the
> "gen_*" process.  "Hey gen_server, call me back when you get this
> done".
>
> Probably my design is wrong?
>
> Finally researching a bit, I thought that it might be a good idea to
> write a behaviour. But the same question comes up, how do I callback
> the client? (diagram: http://i.imgur.com/6N6Je.png)
>
> Hopefully I explained my problem, and questions.
>
> Thanks,
>
> Regards,
> --
> Ale.
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Ale
Reply | Threaded
Open this post in threaded view
|

Re: How to write a generic IRC client the OTP way?

Ale
In reply to this post by Jon Watte
Hello Jon,

Thanks for your answer, sorry for the delay.

> Also, for synchronous calls (where you want the status), waiting the
> necessary amount of time is pretty much what you expect to do. You *can*
> make arrangements to use cast, and pass in a respond-to-PID parameter as
> part of the request, but in most cases, that adds significant extra
> complexity for very little benefit.

I think one of the problems I'm having is that I'm confusing
synchronous calls of erlang processes and the actual process of the
interpreter.

I was wondering if I make a synchronous call from a wx process to a
gen_server process (using gen_server:call for example) if the whole wx
application would block. For example, would I be able to click a
button mean while the call completes?

I suppose that depends on the application, wouldn't it? I mean if I
spawn another process to call gen_server the wx wouldn't block.

>
> Note that gen_server:call also takes a timeout parameter -- it defaults to
> 5,000 milliseconds, so if the gen_server is "wedged" then the timeout will
> kick in.
>

I'll see into it.

Thanks again for your answer,
--
Ale.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Ale
Reply | Threaded
Open this post in threaded view
|

Re: How to write a generic IRC client the OTP way?

Ale
In reply to this post by mazenharake
Hello Mazen,

2011/6/30 Mazen Harake <[hidden email]>:
> Try eirc here: https://github.com/mazenharake/eirc
>
> Trying to do synchronous IRC is doomed to fail imho. eirc sends a
> message everytime you get an event/response and by keeping your own
> state you put context to these events to know what they mean.

Thanks, I'll be checking it out, sounds very intersting.

> IRC wasn't really made for computer programs but rather for a telnet
> prompt so that is why this protocol is flawed in many ways (but very
> easy).
>

It's also fun :-)

> eirc is under the 2-clause BSD license so do what ever you want with it.

That's great!

Thanks for your help,
--
Ale.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions