#!/usr/bin/env python
# encoding: utf-8

#=============================================================================================
#
#=============================================================================================

#---------------------------------------------------------------------------------------------
# For parallel processing:

from multiprocessing import Process, pool, Pool, cpu_count, connection, active_children, Pipe, Lock
PROC_LIMIT = cpu_count()
child_procs = []
proc_lock = Lock()

#=============================================================================================
def spawnProcess(*args, **kwargs):
    ''' Spawn a process. Arguments are passed along to the Process constructor.
        Using this method provides some resource control to limit the number of
        created processes. Tracks all processes it creates to be cleaned up later
        by joinProcess().

        *** This method is ONLY intended to be called by code in the main Python parent process! ***

        @return: The Process object created

    '''
    with proc_lock:
        #active_procs = active_children()
        #print("Active Procss before request a new one: {}".format(len(active_procs)))
        while len(active_children()) >= PROC_LIMIT:
            try:
                # This should work more efficiently on Python 3
                done = connection.wait([proc.sentinel for proc in active_children()], timeout=30)
            except:
                # For maintaining Python 2.7 compatiblity
                time.sleep(1)

        # Wait to spawn another process if using too much memory
        '''children = psutil.Process().children(recursive=True)
        while np.sum([child.memory_percent('vms') for child in children] + [psutil.Process().memory_percent('vms')]) > 50:
            psutil.wait_procs(children, timeout=1)
        '''
        new_proc = Process(*args, **kwargs)

        try:
            new_proc.start()
            child_procs.append(new_proc)
        except:
            print("FORK FAILED!", file=sys.stderr)

        active_procs = active_children()
        print("# of active procss(es) after request this new processing: {}".format(len(active_procs)))

    return new_proc


def joinProcesses():
    ''' Joins all processes created by the process spawner

    '''
    with proc_lock:

        while child_procs:
            child_procs.pop().join()


#=============================================================================================
#The end
