network programming without goto

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • kent sin

    #1

    network programming without goto

    Please help:

    I was really blocked here. without goto I really do
    not known how to do it.

    The problem is to use PyZ3950 to consult a lists of
    hosts and for each of them to search for a list of
    targets. Since the network is undetermined, there were
    always some exceptions: I would like to allow it to
    retry for 3 times. Moreover, during the query process,
    the conn will timeout (set by the remote server).
    Reconnect is preferred before fail the current search,
    but the reconnect may fail even if the first try is
    succeed.


    for host in hostlist:
    try:
    # sometimes the host may fail
    conn =zoom.Connecton (host.ip, host.port)
    except:
    continue # Next host? But How to give it some
    chance? 3 times?
    ...
    reconnect = 0
    for t in targets:
    # ?
    if reconnect:
    # if conn timeout, reconnect
    try:
    # Fail??? 3 chances rules here?
    conn = zoom.Connection (host.ip,
    host.port)
    except:
    # ? Where should I go?
    q = buildquery(t)
    try: # Hay, any things can be broken
    # and after some iteration, conn should
    timeout
    r = conn.search(q)
    except:
    reconnect = 1
    #??? how to retry this t?

  • Roy Smith

    #2
    Re: network programming without goto (refactoring)

    In article <mailman.6783.1 101394437.5135. python-list@python.org >,
    kent sin <kentsin@yahoo. com> wrote:
    [color=blue]
    > Please help:
    >
    > I was really blocked here. without goto I really do
    > not known how to do it.
    >
    > The problem is to use PyZ3950 to consult a lists of
    > hosts and for each of them to search for a list of
    > targets. Since the network is undetermined, there were
    > always some exceptions: I would like to allow it to
    > retry for 3 times. Moreover, during the query process,
    > the conn will timeout (set by the remote server).
    > Reconnect is preferred before fail the current search,
    > but the reconnect may fail even if the first try is
    > succeed.[/color]


    [spaghetti code deleted for brevity]

    The real problem you've got is that you're trying to smash too much
    stuff into one function. You've got several things going on here at
    once. First, you're iterating over several hosts to try. Next, you're
    making several attempts to connect to each host. Lastly, you've got
    some buildquery()/search() stuff going on (whatever that may be). I'm
    not at all sure what you're trying to do with "for t in targets", but
    I'm going to assume it's somehow related to iterating over the various
    hosts.

    What you want to do is refactor this into a number of smaller functions,
    each one encapsulating one piece of the puzzle. To start, I'd build a
    function which handled the multiple connection attempts to a given host.
    Maybe something like this:

    #
    # Untested code -- this is just to give you some ideas
    # and get you thinking in the right direction
    #
    def connectWithRetr ies (host, port, retryLimit):
    attempts = 0
    while attempts < retryLimit:
    try:
    connection = zoom.Connection (host, port)
    return connection
    except ConnectionError :
    attempts += 1
    throw ConnectionError

    Then, I'd handle the iteration over multiple hosts:

    def connectToSomeHo st (hostlist, port):
    for host in hostlist:
    try:
    connection = connectWithRetr ies (host, port)
    return connection
    except ConnectionError :
    # ignore
    throw ConnectionError

    Finally, It's time to implement your query logic, which I'll leave as an
    exercise for the reader (mostly because I don't really understand what
    you're trying to do with that).

    None of this is network-specfic or even Python-specific. The idea of
    breaking up a complex operation into smaller steps and implementing each
    one in its own function is pretty much a universal idea. Each function
    can be easily designed and tested on its own (and, later, understood by
    a future reader).

    The question then becomes, how to decide what stuff to put in what
    function? There's no hard and fast rules, but the general idea is that
    each function should do one thing, or a small set of very closely
    related things. For example, I could imagine possibly combining
    connectWithRetr ies() and connectToSomeHo st into a single larger function
    that did both tasks, because they're both part of the basic "get a
    connection to a host" concept. But, getting the connection and using it
    to perform a query definitely don't belong together.

    Here's some rules of thumb:

    Several smaller functions are usually better than one larger one.

    If you can't see the entire function code without scrolling in your
    editor, it's too big. With todays windowing systems, that probably
    means about 40 lines.

    If it's got more than a couple of loops, or more than a couple of try
    blocks, you're probably doing too much in a single function.

    If you can't explain to somebody in a single sentence what your function
    is doing, it's doing too much.

    The take-home assignment is to DAGS for "refactorin g". There's been a
    lot written on the subject in the last 5-10 years. A lot of what's been
    written assumes an object oriented environment (in a C++ or Java like
    language), but the basic concepts hold for all languages, and for
    procedural as well as OO styles.

    Comment

    • Caleb Hattingh

      #3
      Re: network programming without goto

      On Thu, 25 Nov 2004 06:53:53 -0800 (PST), kent sin <kentsin@yahoo. com>
      wrote:[color=blue]
      >
      > for host in hostlist:
      > try:
      > # sometimes the host may fail
      > conn =zoom.Connecton (host.ip, host.port)
      > except:
      > continue # Next host? But How to give it some
      > chance? 3 times?
      > ...[/color]

      Roy really posted the definitive answer here, but there is something else
      you may find it interesting to try: recursive functions. I played around
      with this for a random POV-Ray texture generator I made a while ago
      (anyone interested? It's decent :) - nesting levels were somewhat
      flexible, and I made the number of nesting levels in different sections
      (texture maps, normal maps, etc.) randomised as well.

      You do something like

      ***
      def funnyWalk(stuff , NUMBER_OF_THIS_ TRY, NESTING_LEVEL)
      if NUMBER_OF_THIS_ TRY > NESTING_LEVEL:
      # We're done.
      break # Is this valid??? I confuse pascal and python easily :(
      NailParrotsFeet ()
      if NEED_ANOTHER_CA LL == true:
      funnyWalk(stuff ,NUMBER_OF_THIS _TRY+1)

      NESTINGLEVEL = 3
      funnyWalk(stuff ,1,NESTINGLEVEL )
      ***

      And "NailParrotsFee t()" function will get run 3 times.

      Comment

      • Jeff Shannon

        #4
        Re: network programming without goto (refactoring)

        Roy Smith wrote:
        [color=blue]
        >What you want to do is refactor this into a number of smaller functions,
        >each one encapsulating one piece of the puzzle. To start, I'd build a
        >function which handled the multiple connection attempts to a given host.
        >Maybe something like this:
        >
        >#
        ># Untested code -- this is just to give you some ideas
        ># and get you thinking in the right direction
        >#
        >def connectWithRetr ies (host, port, retryLimit):
        > attempts = 0
        > while attempts < retryLimit:
        > try:
        > connection = zoom.Connection (host, port)
        > return connection
        > except ConnectionError :
        > attempts += 1
        > throw ConnectionError
        >
        >[/color]

        IMO, Roy's advice here is spot-on, with one minor technical detail. In
        Python, exceptions use 'raise', not 'throw'...

        Jeff Shannon
        Technician/Programmer
        Credit International


        Comment

        • Roy Smith

          #5
          Re: network programming without goto (refactoring)

          In article <10qfcmta665kbe b@corp.supernew s.com>,
          Jeff Shannon <jeff@ccvcorp.c om> wrote:
          [color=blue]
          > In Python, exceptions use 'raise', not 'throw'...[/color]

          Doh! I guess it shows that I've been doing a lot of C++ lately :-)

          Comment

          • Nick Coghlan

            #6
            Re: network programming without goto (refactoring)

            Roy Smith wrote:[color=blue]
            > In article <10qfcmta665kbe b@corp.supernew s.com>,
            > Jeff Shannon <jeff@ccvcorp.c om> wrote:
            >
            >[color=green]
            >>In Python, exceptions use 'raise', not 'throw'...[/color]
            >
            >
            > Doh! I guess it shows that I've been doing a lot of C++ lately :-)[/color]

            Heh. I'm working on a Python test harness that uses a C++ hardware interface
            module. I keep writing raise on the C++ side and throw on the Python side.

            However, that's nothing compared to the amount of swearing regarding the
            uselessness of C++ vectors as compared to Python lists. . .

            Cheers,
            Nick.

            Comment

            • Sibylle Koczian

              #7
              Re: network programming without goto (refactoring)

              Nick Coghlan schrieb:[color=blue]
              > Roy Smith wrote:
              >[color=green]
              >> Jeff Shannon <jeff@ccvcorp.c om> wrote:
              >>[color=darkred]
              >>> In Python, exceptions use 'raise', not 'throw'...[/color]
              >>
              >> Doh! I guess it shows that I've been doing a lot of C++ lately :-)[/color]
              >
              > Heh. I'm working on a Python test harness that uses a C++ hardware
              > interface module. I keep writing raise on the C++ side and throw on the
              > Python side.
              >[/color]
              Isn't "throw something" a much more aggressive act than "raise
              something", and might that help? But English isn't my native language so
              I may be quite wrong.

              --
              Dr. Sibylle Koczian
              Universitaetsbi bliothek, Abt. Naturwiss.
              D-86135 Augsburg

              Tel.: (0821) 598-2400, Fax : (0821) 598-2410
              e-mail : Sibylle.Koczian @Bibliothek.Uni-Augsburg.DE

              Comment

              • Dennis Lee Bieber

                #8
                Re: network programming without goto (refactoring)

                On Mon, 29 Nov 2004 16:02:01 +0100, Sibylle Koczian
                <Sibylle.Koczia n@Bibliothek.Un i-Augsburg.de> declaimed the following in
                comp.lang.pytho n:
                [color=blue]
                > Isn't "throw something" a much more aggressive act than "raise
                > something", and might that help? But English isn't my native language so
                > I may be quite wrong.[/color]

                Well... "throw" has the imagery that one it tossing it to a
                known target, while "raise" is more "hey, I've got a problem here"...
                <G>

                So do we

                raise cain

                or

                throw aFit

                <G>

                --[color=blue]
                > =============== =============== =============== =============== == <
                > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                > wulfraed@dm.net | Bestiaria Support Staff <
                > =============== =============== =============== =============== == <
                > Home Page: <http://www.dm.net/~wulfraed/> <
                > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                Comment

                Working...