Search code examples
pythonasynchronousconcurrent.futures

Access methods of class when calling ThreadPoolExecutor in another method


I have a method that asynchronously retrieves some data and has to call other method to store that data. I'm using ThreadPoolExecutor to get that data.

The class is something like this:

class A:
    [...]
    def update_balance(self, exchange_name, balance):
        if balance is not None:
            self.exchanges[exchange_name].balance = balance

    def __balance_getter(ex, this):
            balance = ex.get_balance()
            if balance is not None:
                update_balance(ex.api.name, balance) ---> Can't call update_balance. I have no ref of self

    def retrieve_all_balances(self, exchange_list):
        with concurrent.futures.ThreadPoolExecutor() as executor:
            executor.map(self.__balance_getter, exchange_list)

How could I pass to __balance_getter() a reference of self so I can call self.update_balance()?

Thanks


Solution

  • Rewrite __balance_getter so that it just returns information. Rewrite retrieve_all_balances to create a list of futures, then send the result(s) to update_balance as each future completes.

    class A:
        [...]
        def update_balance(self, exchange_name, balance):
            if balance is not None:
                self.exchanges[exchange_name].balance = balance
    
        def __balance_getter(ex, this):
                balance = ex.get_balance()
                return (ex.api.name, balance)
    #            if balance is not None:
    #                update_balance(ex.api.name, balance) ---> Can't call update_balance. I have no ref of self
    
        def retrieve_all_balances(self, exchange_list):
            with concurrent.futures.ThreadPoolExecutor() as executor:
                futures = [executor.submit(self.__balance_getter, arg) for arg in exchange_list]
                for future in concurrent.futures.as_completed(futures):
                    name,balance = future.result()
                    self.update_balance(name,balance)
    

    Can't really test if this solves your problem as you didn't provide a mcve.