3
\$\begingroup\$

I have an application which polls a bunch of servers every few minutes. To do this, it spawns one thread per server to poll (15 servers) and writes back the data to an object:

import requests
import threading
import time


servers = ['1.1.1.1', '1.1.1.2']


class CallThreads(threading.Thread):
    """
    Auxiliary class used to provide arguments to threads
    """

    def __init__(self, target, *args):
        self.target = target
        self.args = args
        threading.Thread.__init__(self)

    def run (self):
        self.target(*self.args)


class ServerResults(object):
    def __init__(self):
        self.results_list = []

    def add_server(some_argument):
        self.results_list.append(some_argument)


def poll_server(server, results):
    response = requests.get(server, timeout=10)
    results.add_server(response.status_code);


def process_results(results):
    # Do something with the results


def main():
    while True:
        results = ServerResults()
        for s in servers:
            t = CallThreads(poll_server, s, results)
            t.daemon = True
            t.start()
        time.sleep(300)
        process_results(results.results_list)


if __name__ == '__main__':
    main()

This is my first non-trivial Python application, so I would appreciate any critique, comments, or suggestions. Thank you!

\$\endgroup\$
  • \$\begingroup\$ Is the while statement supposed to be in the process_results function? \$\endgroup\$ – Aseem Bansal Aug 24 '13 at 14:57
  • \$\begingroup\$ Thank you Aseem. No, the while statement is not in the process_results() function. I have added a main() function to clarify this. \$\endgroup\$ – dotancohen Aug 25 '13 at 6:57
2
\$\begingroup\$

The two classes seem useless to me.

ServerResults only contains a list, so just use a list. Edit: see comment below.

The CallThreads class is unnecessary, this:

t = CallThreads(poll_server, s, results)

can be written like that:

t = Thread(target=poll_server, args=(s, results))

Note that you could also use the partial function:

t = Thread(target=partial(poll_server, s, results))

or a lambda:

t = Thread(target=lambda: poll_server(s, results))
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you. ServerResults is actually much more than a list, I just show a list in this example code for simplicity's sake. I am interested in this partial function, where is this documented? Googling for python target=partial turns up some blog posts but no real documentation. Thanks! \$\endgroup\$ – dotancohen Sep 2 '13 at 9:36
  • \$\begingroup\$ Oops, I was going to put a link to the documentation but forgot. It's in the standard library: functools.partial. target is a keyword argument of Thread(), you simply had to search for python partial. \$\endgroup\$ – Changaco Sep 2 '13 at 9:45
  • \$\begingroup\$ Great, thanks. I had to add from functools import partial. I'm still playing with it, thank you. \$\endgroup\$ – dotancohen Sep 2 '13 at 9:56
  • \$\begingroup\$ The code which uses target=partial is segfaulting, please see the SO question. \$\endgroup\$ – dotancohen Sep 2 '13 at 17:55
  • \$\begingroup\$ Sorry, I don't know much about debugging segfaults. Have you tried using gdb ? \$\endgroup\$ – Changaco Sep 3 '13 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.