Note that there are some explanatory texts on larger screens.

plurals
  1. POPython function call in thread always returns same value
    primarykey
    data
    text
    <p>I'm boggled over why a function called in a thread always returns the same value. I've confirmed that the parameters are different for each call. If I call the function after acquiring a lock then the function returns the correct value. This obviously defeats the purpose of using threads, because then this function is just called sequentially, one thread after another. Here is what I have. The function is called "get_related_properties" and I've made a note of it in the code:</p> <pre><code>class ThreadedGetMultipleRelatedProperties(): def __init__(self, property_values, **kwargs): self.property_values = property_values self.kwargs = kwargs self.timeout = kwargs.get('timeout', 20) self.lock = threading.RLock() def get_result_dict(self): queue = QueueWithTimeout() result_dictionary = {} num_threads = len(self.property_values) threads = [] for i in range(num_threads): t = GetMultipleRelatedPropertiesThread(queue, result_dictionary, self.lock) t.setDaemon(True) try: threads.append(t) t.start() except: return {"Error": "Unable to process results at this time." } for property_value in self.property_values: kwargs_copy = dict.copy(kwargs) kwargs_copy['property_value'] = property_value queue.put(self.kwargs_copy) queue.join_with_timeout(self.timeout) # cleanup threads for i in range(num_threads): queue.put(None) for t in threads: t.join() return result_dictionary class GetMultipleRelatedPropertiesThread(threading.Thread): def __init__(self, queue, result_dictionary, lock): threading.Thread.__init__(self) self.queue = queue self.result_dictionary = result_dictionary self.lock = lock def run(self): from mixpanel_helpers import get_related_properties while True: kwargs = self.queue.get() if kwargs == None: break current_property_value = kwargs.get('property_value') self.lock.acquire() # The function call below always returns the same value if called before acquire result = get_related_properties(**kwargs) try: self.result_dictionary[current_property_value] = result finally: self.lock.release() #signals to queue job is done self.queue.task_done() </code></pre> <p>Here is get_related_properties, although it makes other calls, so I'm not sure the problem lives in here:</p> <pre><code>def get_related_properties(property_name, property_value, related_properties, properties={}, **kwargs): kwargs['exclude_detailed_data'] = True properties[property_name] = property_value result = get_multiple_mixpanel_results(properties=properties, filter_on_values=related_properties, **kwargs) result_dictionary = {} for related_property in related_properties: try: # grab the last result here, because it'll more likely have the most up to date properties current_result = result[related_property][0]['__results'][0]['label'] except Exception as e: current_result = None try: related_property = int(related_property) except: pass result_dictionary[related_property] = current_result return result_dictionary </code></pre> <p>An additional note, I've also tried to copy the function using Python's <a href="http://docs.python.org/2/library/copy.html" rel="nofollow">copy module</a>, both a deep and shallow copy and call the function copy, but neither of those worked.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload