Menu

Robust connection design

-]-[
2004-10-26
2013-05-21
  • -]-[

    -]-[ - 2004-10-26

    Hi, me again :)

    Great job on 1.1!

    From working with 1.1 I have found the following:

    In order to have a robust connection and not lose messages etc I had to implement another FSM around the gen_esme behavior.  This FSM is driven by the gen_esme responses to SMPP events like errors and bind responses.
    It has three states (unbound, session and bound)
    The unbound state is there is no valid session available.  Any message that should be sent is queued instead.
    The session state is if there is a valid session but it has not bound yet.  Messages to be sent are queueed again.  Any session error transits back to the unbound state
    The bound state is if the session is bound.  Queueed messages are all send and all messages are submitted to the SMSC immediately.  Any error in the bound state causes the session to be unbound and terminated and the unbound state is entered.

    This FSM also allows for timed connection retries by using the start_timer function.

    Since one usually has more than one connection to a given SMSC for load balancing etc it makes sense to have some manager for multiple connections.

    It worries me a bit that I created a gen_server that interfaces to a gen_fsm that manages a gen_esme driven by a gen_fsm... It just seems like there should be a shorter way to do it.  Am I missing it?  Or is this the way it should be done?

    Happy to share source code if some one might find it useful.

    -]-[einrich

     
    • Enrique Marcote Peńa

      Hello Heinrich,

      I see what you mean.  In fact when I wrote the gen_esme v1.1 as an extended gen_server, my intention was to  define a gen_esme_server and a gen_esme_fsm, both of them ESME behaviours; one acting as an extended gen_server, and the other one as an extended gen_fsm.  But to be honest, I got a bit messed up implementing the gen_esme_fsm, and since it wasn't essential for our work, I decided to postpone it :$

      I guess I'll give gen_esme_fsm another try (I plan to release version 1.2 by November, I will add the gen_esme_fsm behaviour to the todo list)...or maybe you want to do it yourself :-)... and then implement your FSM as a callback module for your gen_esme_fsm.  It'll be great if you decide to implemented it and you share this behaviour with us :-)  Should you inspect the code on gen_esme, you may find it easy to write a fsm like version of it (gen_esme doesn't do any complex work. Please let me know if you ever decide to look inside the gen_esme code, either to write the gen_esme_fsm or your own FSM).

      Apart from this, would it be possible to redesign your robust connection manager as a server? (instead of a FSM).  Maybe by having on the server state; a list for open sessions, another one for bound sessions, and a queue of messages.  If there are no bound sessions available on the server's state, messages are queued (like in the unbound state you mention).  Whenever a
      session is bound to the SMSC, all messages on the queue are submitted, if any.  When there are bound sessions available, incoming messages are submitted to
      the SMSC (selecting an availble session in a round robin fashion).

      Best

      Quique

       
    • -]-[

      -]-[ - 2004-10-27

      The structure I have at the moment is a bit more complex than I explained initially.

      I have a network gen_server.  This maintains several connection gen_fsms.  A message is submitted to a network and the network gives it to one of the connections in a round robin fassion.

      The connection is the gen_fsm that maintains the state inromation for a connection_esme as discussed before.

      Initially I tried to use one server that maintained the state for several connection_esmes.  One runs into quite complex situations with routing messages if only a subset of the sessions are bound.  In the end it was much simpler to have one connection manage only one connection_esme (and session).  Higher level routing descisions are made by the network but message queueing is done on the connection level.  In the end the network doesnt worry about the internal state of a connection because a connection will deliver all the queued messages once it manages to bind.

      When I have tested the code properly I will send it to you.  I dont have experience writing behaviors but it might be interesting to try this :)

      -]-[

       

Log in to post a comment.