This is how I would code the program to:
- have the worker function,
singleq_test, return both the average running time and, for example, the results of the query
- show how to assign to each pool process its own connection in case a single connection cannot be used across processes
- make the program runnable on platforms that use either the spawn method (e.g. Windows) or fork method (e.g. Linux) for starting new child processes
import time
from multiprocessing import Pool, TimeoutError
def init_pool_processes():
global conn
conn = new_connex(0) #instatiate neo4j connector
def singleq_test(q: str):
ar = []
ntest = 5
#time.sleep(ti)
print("inside singleq")
for n in range(ntest):
starttime = time.time()
qtest = conn.query(q) #getting response
runtime = time.time()-starttime
ar.append(runtime)
#
averageruntime = sum(ar)/ntest
# return average runtime and query results as a tuple:
return (averageruntime, qtest)
def qlist_test(ql: list):
with Pool(initializer=init_pool_processes) as po:
print("inside pool")
res = po.map_async(singleq_test, ql)
try:
# Get list of tuples:
tpls = res.get(timeout=20)
for tpl in tpls:
# Unpack each tuple:
averageruntime, qtest = tuple
print(averageruntime, qtest)
except TimeoutError:
print('map_async timed out')
qltimes = []
return qltimes
if __name__ == '__main__':
qlist = [
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:person) RETURN n LIMIT 9300",
"Match (n:company) RETURN n LIMIT 2" ,
"Match (n:compound) RETURN n LIMIT 1"
]
qlist_test(qlist)
If a single connection can be shared among all processes, then:
import time
from multiprocessing import Pool, TimeoutError
def init_pool_processes(the_connection):
global conn
conn = the_connection
def singleq_test(q: str):
ar = []
ntest = 5
#time.sleep(ti)
print("inside singleq")
for n in range(ntest):
starttime = time.time()
qtest = conn.query(q) #getting response
runtime = time.time()-starttime
ar.append(runtime)
#
averageruntime = sum(ar)/ntest
# return average runtime and query results as a tuple:
return (averageruntime, qtest)
def qlist_test(ql: list):
conn = new_connex(0) #instatiate neo4j connector
with Pool(initializer=init_pool_processes, initargs=(conn,)) as po:
print("inside pool")
res = po.map_async(singleq_test, ql)
try:
# Get list of tuples:
tpls = res.get(timeout=20)
for tpl in tpls:
# Unpack each tuple:
averageruntime, qtest = tuple
print(averageruntime, qtest)
except TimeoutError:
print('map_async timed out')
qltimes = []
return qltimes
if __name__ == '__main__':
qlist = [
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:company) RETURN n.country_code LIMIT 100",
"Match (n:person) RETURN n LIMIT 9300",
"Match (n:company) RETURN n LIMIT 2" ,
"Match (n:compound) RETURN n LIMIT 1"
]
qlist_test(qlist)
Note
Since the work being performed by singleq_test is primarily database access, I would think that a multithreading pool would work just as well if not better -- at least it is something to try. The only change you need to make is:
from multiprocessing.pool import ThreadPool as Pool, TimeoutError
Now the question becomes whether a single connection can be shared among multiple threads running in the same process or not.