summaryrefslogtreecommitdiff
path: root/prolog/engine.py
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@araneo.org>2015-08-20 17:45:38 +0200
committerTimotej Lazar <timotej.lazar@araneo.org>2015-08-20 17:45:38 +0200
commite70efb2c36493dd9413d76cd7a1a60bbfb8cdfd6 (patch)
tree9c199779a33d6d5b7282656d0de61aa9a9275701 /prolog/engine.py
parent78d81e2c5e1e00796ac74fea445d0b664e97d351 (diff)
Add a timeout option for prolog.engine requests
Diffstat (limited to 'prolog/engine.py')
-rw-r--r--prolog/engine.py43
1 files 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'})