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\$
2
  • \$\begingroup\$ Is the while statement supposed to be in the process_results function? \$\endgroup\$ Aug 24, 2013 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, 2013 at 6:57

1 Answer 1

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))
\$\endgroup\$
6
  • \$\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, 2013 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, 2013 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, 2013 at 9:56
  • \$\begingroup\$ The code which uses target=partial is segfaulting, please see the SO question. \$\endgroup\$
    – dotancohen
    Sep 2, 2013 at 17:55
  • \$\begingroup\$ Sorry, I don't know much about debugging segfaults. Have you tried using gdb ? \$\endgroup\$
    – Changaco
    Sep 3, 2013 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.