# A test firing off a lot of senseless queries, mixing sync and async.
# This is a desperate attempt to find the stillborn worker process bug.

import warnings
from astropy.utils.exceptions import AstropyWarning, AstropyUserWarning
warnings.simplefilter('ignore', AstropyUserWarning)
warnings.simplefilter('ignore', AstropyWarning)

import collections
import os
import time

import pyvo

ENDPOINT_URL = os.environ.get("ENDPOINT_URL",
	"http://localhost:8080/tap")
#	"http://dc.zah.uni-heidelberg.de/tap")


def get_tables(svc):
	for row in svc.run_sync("SELECT table_name from tap_schema.tables"):
		yield row["table_name"]


class Runner(object):
	def __init__(self, svc):
		self.svc = svc
		self.tables = collections.deque(
			get_tables(self.svc))
		self.jobs = set()
	
	def start_a_job(self):
		next_table = self.tables.popleft()
		new_job = self.svc.submit_job(
			"select top 200 * from {}".format(next_table))
		new_job.run()
		self.jobs.add((next_table, new_job))

	def clean_running_jobs(self):
		expired = set()
		for table_name, job in self.jobs:
			if job.phase not in ('QUEUED', 'EXECUTING'):
				expired.add((table_name, job))
				self.tables.append(table_name)
				if job.phase!="COMPLETED":
					print "!!!", job.phase
				else:
					print "async", len(job.fetch_result().table)
		self.jobs = self.jobs-expired
	
	def ensure_n_jobs_running(self, n):
		while len(self.jobs)<n:
			self.start_a_job()

	def run_sync_job(self):
		next_table = self.tables.popleft()
		self.tables.append(next_table)
		try:
			print "sync", len(self.svc.run_sync(
				"select top 200 * from {}".format(next_table)))
		except Exception, msg:
			print "Failure while querying {}: {}".format(
				next_table, msg)


def main():
	svc = pyvo.dal.TAPService(ENDPOINT_URL)
	runner = Runner(svc)
	while True:
		runner.ensure_n_jobs_running(5)
		runner.run_sync_job()
		runner.clean_running_jobs()


if __name__=="__main__":
	main()
