Base integration with user apps
This commit is contained in:
parent
5e70da47dd
commit
c7b38a6506
@ -100,7 +100,7 @@ ok
|
|||||||
“code”: 0,
|
“code”: 0,
|
||||||
“value”: 0.6321,
|
“value”: 0.6321,
|
||||||
“comment”: “in progress, all right”
|
“comment”: “in progress, all right”
|
||||||
}
|
}
|
||||||
|
|
||||||
Если, например, клиент ошибся в tid или пытается получить доступ к чужой задаче, сервер даст ответ
|
Если, например, клиент ошибся в tid или пытается получить доступ к чужой задаче, сервер даст ответ
|
||||||
{
|
{
|
||||||
|
84
server.py
84
server.py
@ -54,6 +54,7 @@ class LocalServer:
|
|||||||
self.log = open('log.txt', 'w')
|
self.log = open('log.txt', 'w')
|
||||||
self.WriteToLog('local server initialized')
|
self.WriteToLog('local server initialized')
|
||||||
|
|
||||||
|
for i in xrange(2):
|
||||||
worker = Worker(self.jobs_queue, self.queue_lock)
|
worker = Worker(self.jobs_queue, self.queue_lock)
|
||||||
worker.start()
|
worker.start()
|
||||||
|
|
||||||
@ -125,42 +126,50 @@ class LocalServer:
|
|||||||
with self.queue_lock:
|
with self.queue_lock:
|
||||||
self.jobs_queue.append(job)
|
self.jobs_queue.append(job)
|
||||||
WriteToLog('Job added')
|
WriteToLog('Job added')
|
||||||
|
return job
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
class Worker(threading.Thread):
|
class Worker(threading.Thread):
|
||||||
|
number = 0
|
||||||
|
|
||||||
def __init__(self, queue, lock):
|
def __init__(self, queue, lock):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.lock = lock
|
self.lock = lock
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
WriteToLog('worker started')
|
WriteToLog('worker started')
|
||||||
|
self.id = Worker.number
|
||||||
|
Worker.number += 1
|
||||||
|
|
||||||
def FindNext(self):
|
def Cycle(self):
|
||||||
result = None
|
|
||||||
for job in self.queue:
|
|
||||||
if job.GetState() == JOB_READY:
|
|
||||||
result = job
|
|
||||||
return result
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
job = None
|
job = None
|
||||||
# найти следующее готовое к выполнению задание
|
# найти следующее готовое к выполнению задание
|
||||||
with self.lock:
|
with self.lock:
|
||||||
job = self.FindNext()
|
for j in self.queue:
|
||||||
|
if not j.IsBusy():
|
||||||
|
job = j
|
||||||
|
job.SetBusy()
|
||||||
|
break
|
||||||
# и, если нашли, приступаем к выполнению
|
# и, если нашли, приступаем к выполнению
|
||||||
if job:
|
if job:
|
||||||
|
WriteToLog("{} started!".format(self.id))
|
||||||
job.Start()
|
job.Start()
|
||||||
|
WriteToLog("{} finished!".format(self.id))
|
||||||
else:
|
else:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
self.Cycle()
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
JOB_READY = 0
|
JOB_READY = 0
|
||||||
JOB_RUNNING = 1
|
JOB_BUSY = 1
|
||||||
JOB_STOPPED = 2
|
JOB_RUNNING = 2
|
||||||
JOB_COMPLETED = 3
|
JOB_STOPPED = 3
|
||||||
|
JOB_COMPLETED = 4
|
||||||
|
|
||||||
class Job:
|
class Job:
|
||||||
def __init__(self, taskd, datadump):
|
def __init__(self, taskd, datadump):
|
||||||
@ -168,16 +177,36 @@ class Job:
|
|||||||
self.datad = datadump
|
self.datad = datadump
|
||||||
self.state = JOB_READY
|
self.state = JOB_READY
|
||||||
self.percent = 0.0
|
self.percent = 0.0
|
||||||
|
self.comment = ''
|
||||||
self.result = None
|
self.result = None
|
||||||
self.proc = None
|
self.proc = None
|
||||||
|
|
||||||
def ProcessMsg(self, msg):
|
def ProcessMsg(self, msg):
|
||||||
WriteToLog(msg.strip())
|
# разбираем полученный ответ
|
||||||
|
data = json.loads(msg)
|
||||||
|
# извлекаем оттуда ответ
|
||||||
|
ans = data['answer']
|
||||||
|
# ответ получен ок или предупреждение
|
||||||
|
# записываем значение прогресса, если имеется
|
||||||
|
if ans == 'ok' or ans == 'warning':
|
||||||
|
self.percent = data.get('value', 0.0)
|
||||||
|
# в ответе пришел результат вычислений
|
||||||
|
# помещаем в секцию результата
|
||||||
|
elif ans == 'result':
|
||||||
|
self.result = data['result']
|
||||||
|
# произошла ошибка
|
||||||
|
elif ans == 'error':
|
||||||
|
WriteToLog('Error!')
|
||||||
|
# недокументированный ответ приложения
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
# возможно, комментарий прольет свет на проблему
|
||||||
|
self.comment = data.get('comment', '')
|
||||||
|
|
||||||
|
|
||||||
def Start(self):
|
def Start(self):
|
||||||
#try:
|
try:
|
||||||
self.state = JOB_RUNNING
|
self.state = JOB_RUNNING
|
||||||
WriteToLog('Job started')
|
|
||||||
execpath = self.taskd.execpath
|
execpath = self.taskd.execpath
|
||||||
# запускаем процесс на выполнение
|
# запускаем процесс на выполнение
|
||||||
self.proc = subprocess.Popen([execpath, '-r'], shell = True,
|
self.proc = subprocess.Popen([execpath, '-r'], shell = True,
|
||||||
@ -192,14 +221,27 @@ class Job:
|
|||||||
while self.proc.poll() == None:
|
while self.proc.poll() == None:
|
||||||
try:
|
try:
|
||||||
msg = ostream.readline()
|
msg = ostream.readline()
|
||||||
|
#msg = msg.strip()
|
||||||
self.ProcessMsg(msg)
|
self.ProcessMsg(msg)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
WriteToLog('Income msg failed' + str(e))
|
#WriteToLog('Income msg failed: ' + str(e))
|
||||||
|
pass
|
||||||
self.state = JOB_COMPLETED
|
self.state = JOB_COMPLETED
|
||||||
WriteToLog('Job done')
|
except Exception, e:
|
||||||
#except:
|
WriteToLog('Job loop failed: ' + str(e))
|
||||||
#WriteToLog('Job loop failed')
|
self.state = JOB_STOPPED
|
||||||
#self.state = JOB_STOPPED
|
|
||||||
|
def SetBusy(self):
|
||||||
|
self.state = JOB_BUSY
|
||||||
|
|
||||||
|
def IsBusy(self):
|
||||||
|
return self.state != JOB_READY
|
||||||
|
|
||||||
|
def IsRunning(self):
|
||||||
|
return self.state == JOB_BUSY or self.state == JOB_RUNNING
|
||||||
|
|
||||||
|
def IsFinished(self):
|
||||||
|
return self.state == JOB_COMPLETED or self.state == JOB_STOPPED
|
||||||
|
|
||||||
def Stop(self):
|
def Stop(self):
|
||||||
if self.proc and self.proc.poll() != None:
|
if self.proc and self.proc.poll() != None:
|
||||||
|
31
task.py
31
task.py
@ -11,6 +11,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
class TaskDescription:
|
class TaskDescription:
|
||||||
"""
|
"""
|
||||||
Description of the task. Task runs on server.
|
Description of the task. Task runs on server.
|
||||||
@ -113,8 +115,7 @@ class DataDefinition:
|
|||||||
self.params = {}
|
self.params = {}
|
||||||
for param in self.DD.pdata:
|
for param in self.DD.pdata:
|
||||||
self.params[param] = self.DD[param].GetDefault()
|
self.params[param] = self.DD[param].GetDefault()
|
||||||
|
self.job = None
|
||||||
self.taskjob = None
|
|
||||||
|
|
||||||
def __getitem__(self, label):
|
def __getitem__(self, label):
|
||||||
return self.params[label]
|
return self.params[label]
|
||||||
@ -125,6 +126,12 @@ class DataDefinition:
|
|||||||
else:
|
else:
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
|
def Copy(self):
|
||||||
|
res = copy.copy(self)
|
||||||
|
res.params = copy.copy(self.params)
|
||||||
|
res.job = None
|
||||||
|
return res
|
||||||
|
|
||||||
def PackParams(self):
|
def PackParams(self):
|
||||||
package = []
|
package = []
|
||||||
owner = self
|
owner = self
|
||||||
@ -138,7 +145,7 @@ class DataDefinition:
|
|||||||
def Flush(self):
|
def Flush(self):
|
||||||
server = self.DD.taskd.server
|
server = self.DD.taskd.server
|
||||||
datadump = self.PackParams()
|
datadump = self.PackParams()
|
||||||
server.AddJob(self.DD.taskd, datadump)
|
self.job = server.AddJob(self.DD.taskd, datadump)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -157,14 +164,24 @@ def main():
|
|||||||
|
|
||||||
mdef = DataDefinition(model)
|
mdef = DataDefinition(model)
|
||||||
pprint(mdef.DD.data)
|
pprint(mdef.DD.data)
|
||||||
mdef['x'] = 20
|
mdef['r'] = 3.14
|
||||||
|
mdef['n'] = 5
|
||||||
|
mdef['d'] = 0
|
||||||
|
mdef2 = mdef.Copy()
|
||||||
|
mdef2['d'] = 30
|
||||||
p = mdef.PackParams()
|
p = mdef.PackParams()
|
||||||
pprint(p)
|
pprint(p)
|
||||||
|
p = mdef2.PackParams()
|
||||||
|
pprint(p)
|
||||||
|
|
||||||
mdef.Flush()
|
mdef.Flush()
|
||||||
mdef.Flush()
|
mdef2.Flush()
|
||||||
|
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
print 'RESULT'
|
||||||
|
pprint(mdef.job.result)
|
||||||
|
pprint(mdef2.job.result)
|
||||||
|
|
||||||
time.sleep(15)
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
"models": {
|
"models": {
|
||||||
|
|
||||||
"simpleexample": {
|
"sintaylor": {
|
||||||
|
|
||||||
"title": "Simple model for example",
|
"title": "Simple model for example",
|
||||||
"author": "Anton Vakhrushev",
|
"author": "Anton Vakhrushev",
|
||||||
@ -14,20 +14,21 @@
|
|||||||
|
|
||||||
"params": {
|
"params": {
|
||||||
|
|
||||||
"x": {
|
"r": {
|
||||||
"type": "int",
|
"type": "double",
|
||||||
"default": 10,
|
"default": 6.28,
|
||||||
"title": "Main parameter"
|
"comment": "Right edge"
|
||||||
},
|
},
|
||||||
|
|
||||||
"u": {
|
"d": {
|
||||||
"type": "double",
|
"type": "int",
|
||||||
"default": 3.14
|
"default": 5,
|
||||||
|
"comment": "Number of members in taylor serie"
|
||||||
},
|
},
|
||||||
|
|
||||||
"n": {
|
"n": {
|
||||||
"type": "int",
|
"type": "int",
|
||||||
"default": 1000,
|
"default": 10,
|
||||||
"title": "Steps",
|
"title": "Steps",
|
||||||
"comment": "Number of steps for algorithm"
|
"comment": "Number of steps for algorithm"
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,91 @@
|
|||||||
#! coding: utf-8
|
#! coding: utf-8
|
||||||
|
|
||||||
|
# Тестовое приложение для проекта Opal
|
||||||
|
# Вычисление значений синуса по формулам Тейлора
|
||||||
|
# Вычисляет значения для указанного диапазона с заданной точностью
|
||||||
|
# и нужным количеством шагов
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
def write(msg):
|
def write(msg):
|
||||||
sys.stdout.write(msg + '\n')
|
sys.stdout.write(str(msg) + '\n')
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def sin_taylor(x, n):
|
||||||
|
f = 1
|
||||||
|
s = 0.0
|
||||||
|
e = 1.0
|
||||||
|
x0 = x
|
||||||
|
for i in xrange(n + 1):
|
||||||
|
#print e, f, x
|
||||||
|
f *= (2 * i) * (2 * i + 1) if i else 1
|
||||||
|
s += e * x / f
|
||||||
|
x *= x0 * x0
|
||||||
|
e *= -1
|
||||||
|
return s
|
||||||
|
|
||||||
|
def answer(p):
|
||||||
|
return json.dumps({
|
||||||
|
"answer": "ok",
|
||||||
|
"value": p
|
||||||
|
})
|
||||||
|
|
||||||
|
def error(msg):
|
||||||
|
return json.dumps({
|
||||||
|
"answer": "error",
|
||||||
|
"comment": msg
|
||||||
|
})
|
||||||
|
|
||||||
|
def result(r):
|
||||||
|
return json.dumps({
|
||||||
|
"answer": "result",
|
||||||
|
"result": {
|
||||||
|
"table": {
|
||||||
|
"head": [{"x": "double"}, {"y": "double"}],
|
||||||
|
"body": r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
# try:
|
try:
|
||||||
|
|
||||||
if sys.argv[1] == '-i':
|
if sys.argv[1] == '-i':
|
||||||
|
|
||||||
with open('testt.json') as f:
|
with open('testt.json') as f:
|
||||||
d = json.load(f)
|
d = json.load(f)
|
||||||
write(json.dumps(d, indent = 2))
|
write(json.dumps(d, indent = 2))
|
||||||
|
|
||||||
elif sys.argv[1] == '-r':
|
elif sys.argv[1] == '-r':
|
||||||
textdata = raw_input()
|
|
||||||
#data = json.loads(data)
|
|
||||||
for i in xrange(10):
|
|
||||||
time.sleep(0.5)
|
|
||||||
write(json.dumps({ "hello": "world" }))
|
|
||||||
|
|
||||||
# except:
|
textdata = raw_input()
|
||||||
# print 'Error!'
|
data = json.loads(textdata)
|
||||||
# sys.exit(-1)
|
|
||||||
|
if not len(data) and data[0]['label'] != 'sintaylor':
|
||||||
|
write(error('Unknown model'))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
params = data[0]['params']
|
||||||
|
l = 0 # левая граница
|
||||||
|
r = params['r'] # правая граница
|
||||||
|
n = params['n'] # количество шагов
|
||||||
|
d = params['d'] # количество членов в разложении Тейлора
|
||||||
|
h = float(r - l) / n # шаг сетки по х
|
||||||
|
res = [] # таблица резултатов
|
||||||
|
|
||||||
|
while l <= r:
|
||||||
|
y = sin_taylor(l, d)
|
||||||
|
res.append([l, y])
|
||||||
|
write(answer(round(l / r, 2)))
|
||||||
|
l += h
|
||||||
|
|
||||||
|
write(result(res))
|
||||||
|
|
||||||
|
except:
|
||||||
|
write(error('Fatal error'))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
Loading…
Reference in New Issue
Block a user