Welcome, guest | Sign In | My Account | Store | Cart
# Author: Miguel Martinez Lopez
#
# Uncomment the next line to see my email
# print("Author's email: %s"%"61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex"))


"""
I provide in this module the function "
exec_async".

"
exec_async" executes the function "computation" asyncronously with the provided "args" and "kwargs".
If "
callback" is provided, it will be called with the result when the computation is finnished.
"
Polling" will be the frequency to poll to check for results.
There is two methods to execute the task: using multiprocessing or using threads.
"""


import traceback

MULTIPROCESSING
= 0
THREADS
= 1


def exec_async(window, computation, args=(), kwargs={}, callback=None, polling=100, method=MULTIPROCESSING):
   
if method == MULTIPROCESSING:
        _request_results
= _request_results_using_multiprocessing
   
elif method == THREADS:
        _request_results
= _request_results_using_threads

    future_result
= _request_results(computation, args=args, kwargs=kwargs)
   
   
if callback:
        _after_completion
(window, future_result, callback, polling)
       
   
return future_result

def _request_results_using_multiprocessing(func, args, kwargs):
   
import multiprocessing

    future_result
= multiprocessing.Queue()
    request_parameters
= func, args, kwargs, future_result

    worker
= multiprocessing.Process(target=_compute_result, args=request_parameters)
    worker
.daemon = True
    worker
.start()

   
return future_result

def _request_results_using_threads(func, args, kwargs):
   
import threading
   
import Queue

    future_result
= Queue.Queue()
    request_parameters
= func, args, kwargs, future_result

    worker
= threading.Thread(target=_compute_result, args=request_parameters)
    worker
.daemon = True
    worker
.start()

   
return future_result


def _after_completion(window, future_result, callback, polling):
   
def check():
       
try:
            result
= future_result.get(block=False)
       
except:
            window
.after(polling, check)
       
else:
            callback
(result)
               
    window
.after(0, check)

def _compute_result(func, func_args, func_kwargs, future_result):
   
try:
        _result
= func(*func_args, **func_kwargs)
   
except Exception as errmsg:
        _result
= Exception(traceback.format_exc())

    future_result
.put(_result)


if __name__ == "__main__":
   
try:
       
from Tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
       
import tkMessageBox as messagebox
   
except ImportError:
       
from tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
       
from tkinter import messagebox

   
def fibonnacci(n):
       
if n == 0: return 0
       
elif n == 1: return 1
       
else: return fibonnacci(n-1)+fibonnacci(n-2)

    disabled
= False
   
def calculate_fibonacci():
       
global disabled
       
if disabled:
            messagebox
.showinfo("warning", "It's still calculating...")
           
return

       
def callback(result):
           
global disabled
            disabled
= False
            result_var
.set(result)

        disabled
= True
        exec_async
(root, fibonnacci, args=(n.get(),), callback=callback)

    root
= Tk()
   
    n
= IntVar(value=1)
    row
= Frame(root)
    row
.pack()
   
Entry(row, textvariable=n).pack(side=LEFT)
   
Button(row, text="Calculate fibonnaci", command =calculate_fibonacci).pack(side=LEFT)
   
Button(row, text="It's responsive", command= lambda: messagebox.showinfo("info", "it's responsive")).pack(side=LEFT)
   
    result_var
= StringVar()
   
Label(root, textvariable=result_var).pack()
   
    root
.mainloop()

History