From e70efb2c36493dd9413d76cd7a1a60bbfb8cdfd6 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Thu, 20 Aug 2015 17:45:38 +0200 Subject: Add a timeout option for prolog.engine requests --- prolog/engine.py | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/prolog/engine.py b/prolog/engine.py index f6ce103..bdbca21 100644 --- a/prolog/engine.py +++ b/prolog/engine.py @@ -13,43 +13,57 @@ def strip_html(text): # Create a new pengine, initialize it with [code] and return Prolog's reply. # The engine is destroyed after answering one query. If [query] is given, the # first answer is returned and the engine destroyed. -def create(code='', query=''): +def create(code='', query='', timeout=10): opts = {'format': 'json-html', 'destroy': True, 'src_text': code} if query: opts['ask'] = query - reply, output = request('POST', '/pengine/create', body=json.dumps(opts)) + reply, output = request('POST', '/pengine/create', body=json.dumps(opts), timeout=timeout) # If query was given, the actual reply is nested in create/destroy objects. if query: reply = reply['answer']['data'] return reply, output -def ask(engine, query): - return send(engine, 'ask(({}),[])'.format(query)) +def abort(engine): + params = urllib.parse.urlencode({ + 'id': engine, + 'format': 'json-html'}) + try: + # We don't care about the answer here, so don't wait for it. + request('GET', '/pengine/abort?' + params, timeout=0.01) + except: + pass + +def ask(engine, query, timeout=10): + return send(engine, 'ask(({}),[])'.format(query), timeout=timeout) -def next(engine, n=1): - return send(engine, 'next({})'.format(n)) +def next(engine, n=1, timeout=10): + return send(engine, 'next({})'.format(n), timeout=timeout) -def stop(engine): - return send(engine, 'stop') +def stop(engine, timeout=10): + return send(engine, 'stop', timeout=timeout) def destroy(engine): - return send(engine, 'destroy') + try: + # We don't care about the answer here, so don't wait for it. + send(engine, 'destroy([force(true)])', timeout=0.01) + except: + pass -def send(engine, event): +def send(engine, event, timeout=10): params = urllib.parse.urlencode({ 'id': engine, 'event': event, 'format': 'json-html'}) - return request('GET', '/pengine/send?' + params) + return request('GET', path='/pengine/send?' + params, timeout=timeout) # Return the main reply and pull potential output replies. address, port = 'localhost', 3030 # TODO put this somewhere sane -def request(method, path, body=None): +def request(method, path, body=None, timeout=10): headers = {'Content-Type': 'application/json;charset=utf-8'} messages = [] try: - conn = http.client.HTTPConnection(address, port, timeout=10) + conn = http.client.HTTPConnection(address, port, timeout=timeout) conn.request(method, path, body, headers=headers) while True: response = conn.getresponse() @@ -60,7 +74,8 @@ def request(method, path, body=None): if reply.get('event') == 'output': messages.append(get_message(reply)) - # Request next reply. + # Pull the next output. These requests should return instantly + # as no additional processing needs to be done in the pengine. params = urllib.parse.urlencode({ 'id': reply['id'], 'format': 'json-html'}) -- cgit v1.2.1