Search code examples
pythonmultithreadingconcurrencyabstraction

How to Abstract the way this concrete Thread classes are called?


I'm making concrete classes that are subclassed from Thread class, so in fact they are threads. Class A and B in my example.

My class Foo gets a settings dict, and gets a list of accounts (dict items too). For each account then I create a thread A that takes two arguments, the whole settings dict, and the account list index that corresponds to each account.

But this example can't use class B. Because the call to my Thread Class A is hardcoded. How I could abstract Foo class to use class A or B on demand (dynamically) ? As If They were pluggable actions...

I'm very new to threads and in python in general. I would accept any other way of archieving the same behaviour. Or if there's a better way, please tell me.

class Foo(object):

    def __init__(self, settings):
        self.settings = settings
        self.accounts = [
            {
                'username': 'DummyUser',
                'password': 'FIXME',
            },
            #...
        ]

    def start_threads(self):
        threads = []
        for i in range(len(self.accounts)):
            post_thread = A(self.settings, self.accounts[i])
            post_thread.setName(self.accounts[i]['username'])
            threads.append(post_thread)

        for t in threads:
            t.start() # Start running the threads!
            t.join()  # Wait for the threads to finish...

class A(Thread):

    def __init__(self, settings, account):
        Thread.__init__(self)
        self.settings = settings
        self.account = account

    def run(self):
        # Stuff...
        print('%s sleeping for %d seconds...' % (self.getName(), 60))
        time.sleep(60)

class B(Thread):

    def __init__(self, settings, account):
        Thread.__init__(self)
        self.settings = settings
        self.account = account

    def run(self):
        # Stuff...
        print('%s sleeping for %d seconds...' % (self.getName(), 60))
        time.sleep(60)

if __name__ == '__main__':
    settings = {
        'setting1': 'value1',
        'setting2': 'value2',
        #...
    }

    Foo(settings).start_threads()

Solution

  • class Foo:
        def __init__(self, settings, pluggable_action):
           ...
           self.pluggable_action = pluggable_action
        def start_threads(self):
           ....
           post_thread = self.pluggable_action(...)
           ...
    
     foo = Foo(settings, A) # or B