New perfect server interface
This commit is contained in:
parent
a32af3237f
commit
493352ac4b
@ -44,6 +44,7 @@ class MainFrame (wx.Frame):
|
||||
# WARNING: wxPython code generation isn't supported for this widget yet.
|
||||
self.m_params = wxpg.PropertyGridManager(self,
|
||||
style = wxpg.PG_TOOLBAR)
|
||||
self.m_params.AddPage('fp')
|
||||
bSizer4.Add(self.m_params, 1, wx.EXPAND |wx.ALL, 1)
|
||||
|
||||
bSizer3.Add(bSizer4, 1, wx.EXPAND, 5)
|
||||
|
@ -29,14 +29,13 @@ class MainFrame(forms.MainFrame):
|
||||
def __init__(self):
|
||||
forms.MainFrame.__init__(self, None)
|
||||
|
||||
self.server = s = server.LocalServer()
|
||||
self.server.LoadTasksDescriptions()
|
||||
ds = s.GetTasksDescriptions()
|
||||
models = []
|
||||
for d in ds:
|
||||
models.extend(d.GetModelsDescriptions())
|
||||
model = models[0]
|
||||
s = server.LocalServer()
|
||||
s.LoadModels()
|
||||
models = s.GetModels()
|
||||
s.Start()
|
||||
self.server = s
|
||||
|
||||
model = models[0]
|
||||
|
||||
self.m_user_models.Bind(wx.EVT_TREE_SEL_CHANGED,
|
||||
self.OnModelActivated)
|
||||
@ -51,8 +50,6 @@ class MainFrame(forms.MainFrame):
|
||||
self.Bind(wx.EVT_CLOSE, self.OnClose)
|
||||
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
||||
|
||||
self.m_params.AddPage('fp')
|
||||
|
||||
ov = threading.Thread(target = self.Overseer)
|
||||
ov.daemon = 1
|
||||
ov.start()
|
||||
@ -66,26 +63,30 @@ class MainFrame(forms.MainFrame):
|
||||
|
||||
def Overseer(self):
|
||||
try:
|
||||
while True:
|
||||
if True:
|
||||
wx.MutexGuiEnter()
|
||||
#print '-- cycle --'
|
||||
um = self.m_user_models
|
||||
#um.Freeze()
|
||||
cycle_count = 0
|
||||
while True:
|
||||
wx.MutexGuiEnter()
|
||||
print 'cycle {:-8} '.format(cycle_count)
|
||||
cycle_count += 1
|
||||
item = um.GetRootItem()
|
||||
while item.IsOk():
|
||||
md = um.GetPyData(item)
|
||||
job = md.job if md else None
|
||||
if job and job.IsRunning():
|
||||
t = os.path.basename(job.taskd.execpath)
|
||||
p = job.percent * 100
|
||||
#print t, p
|
||||
um.SetItemText(item, str(job.GetState()), 1)
|
||||
um.SetItemText(item, '{}: {:.2F}%'.format(t, p), 2)
|
||||
data = um.GetPyData(item)
|
||||
if data:
|
||||
jid = data[1]
|
||||
|
||||
if jid != None and self.server.IsJobChanged(jid):
|
||||
tid = self.server.GetJobTID(jid)
|
||||
meta = self.server.GetTaskMeta(tid)
|
||||
t = os.path.basename(meta['exec'])
|
||||
state = self.server.GetJobState(jid)
|
||||
um.SetItemText(item, str(state[0]), 1)
|
||||
um.SetItemText(item, '{}: {:%}'.format(t, state[1]), 2)
|
||||
print jid, state
|
||||
|
||||
item = um.GetNext(item)
|
||||
#um.Thaw()
|
||||
wx.MutexGuiLeave()
|
||||
time.sleep(0.5)
|
||||
time.sleep(0.1)
|
||||
except Exception, e:
|
||||
print 'Error in overseer: ', e
|
||||
|
||||
@ -98,9 +99,10 @@ class MainFrame(forms.MainFrame):
|
||||
data = task.DataDefinition(model)
|
||||
|
||||
child = um.AppendItem(root, 'Default')
|
||||
um.SetPyData(child, data)
|
||||
jid = self.server.CreateJob()
|
||||
um.SetPyData(child, [data, jid])
|
||||
|
||||
def SelectUserModel(self, model_def):
|
||||
def SelectUserModel(self, model_def, jid):
|
||||
|
||||
def SelectProperty(param_type):
|
||||
"""
|
||||
@ -142,7 +144,7 @@ class MainFrame(forms.MainFrame):
|
||||
item = event.GetItem()
|
||||
data = self.m_user_models.GetPyData(item)
|
||||
if data:
|
||||
self.SelectUserModel(data)
|
||||
self.SelectUserModel(data[0], data[1])
|
||||
|
||||
def OnParamChanging(self, event):
|
||||
#value = event.GetValue()
|
||||
@ -159,26 +161,26 @@ class MainFrame(forms.MainFrame):
|
||||
param = prop.GetClientData()
|
||||
um = self.m_user_models
|
||||
id = um.GetSelection()
|
||||
md = um.GetItemPyData(id)
|
||||
md[param] = value
|
||||
data, jid = um.GetItemPyData(id)
|
||||
data[param] = value
|
||||
|
||||
def OnTest(self, event):
|
||||
|
||||
um = self.m_user_models
|
||||
id = um.GetSelection()
|
||||
md = um.GetItemPyData(id)
|
||||
#wx.MessageBox(md.PackParams())
|
||||
md.Flush()
|
||||
#wx.MessageBox('test')
|
||||
data, jid = um.GetItemPyData(id)
|
||||
|
||||
self.server.LaunchJob(jid, data)
|
||||
|
||||
def OnDuplicate(self, event):
|
||||
um = self.m_user_models
|
||||
id = um.GetSelection()
|
||||
title = um.GetItemText(id)
|
||||
parent = um.GetItemParent(id)
|
||||
md = um.GetItemPyData(id)
|
||||
md, jid = um.GetItemPyData(id)
|
||||
child = um.AppendItem(parent, title + ' Copy')
|
||||
um.SetPyData(child, md.Copy())
|
||||
jid = self.server.CreateJob()
|
||||
um.SetPyData(child, [md.Copy(), jid])
|
||||
self.SetStatusText('Copy for "{}" created'.format(title), 0)
|
||||
|
||||
def OnIdle(self, event):
|
||||
|
354
trunk/server.py
354
trunk/server.py
@ -31,22 +31,18 @@ def WriteToLog(msg):
|
||||
print msg
|
||||
|
||||
|
||||
def GenerateId(data):
|
||||
import hashlib
|
||||
title = data['title']
|
||||
author = data['author']
|
||||
id = hashlib.md5(title + author).hexdigest()
|
||||
return id
|
||||
|
||||
class LocalServer:
|
||||
def __init__(self, conf = 'tasks.conf', workers = 2):
|
||||
"""
|
||||
"""
|
||||
def __init__(self):
|
||||
self.max_workers = 2
|
||||
self.task_descrs = []
|
||||
self.jobs_queue = []
|
||||
self.log = None
|
||||
self.running = False
|
||||
self.conf = conf # файл с конфигурацией задач
|
||||
self.workers = workers # количество потоков выполнения
|
||||
self.tasks_meta = {} # идентификаор задачи
|
||||
self.models = [] # список моделей
|
||||
self.next_job_id = 0 # очередной идентификатор работы
|
||||
self.jobs = {} # очередб работ
|
||||
self.log = None #
|
||||
self.running = False #
|
||||
self.queue_lock = threading.Lock()
|
||||
|
||||
# init actions
|
||||
@ -67,25 +63,14 @@ class LocalServer:
|
||||
self.log.write(msg + '\n')
|
||||
print msg
|
||||
|
||||
def Start(self):
|
||||
self.running = True
|
||||
for i in xrange(self.max_workers):
|
||||
worker = Worker(self.jobs_queue, self.queue_lock, self.running)
|
||||
worker.start()
|
||||
|
||||
def Stop(self):
|
||||
self.running = False
|
||||
|
||||
def TestTaskData(self, data):
|
||||
pass
|
||||
|
||||
def LoadTasksDescriptions(self, source = 'tasks.conf'):
|
||||
"""
|
||||
"""
|
||||
self.task_descrs = []
|
||||
|
||||
def LoadModels(self):
|
||||
self.tasks_meta = {}
|
||||
self.models = []
|
||||
self.WriteToLog('tasks interrogation starts')
|
||||
for line in open(source, 'r'):
|
||||
for line in open(self.conf, 'r'):
|
||||
try:
|
||||
# нормализуем указанный путь
|
||||
line = os.path.normpath(line)
|
||||
@ -93,14 +78,29 @@ class LocalServer:
|
||||
# считываем данные через shell (важно для скриптовых языков)
|
||||
textdata = subprocess.check_output([line, '-i'], shell = True,
|
||||
cwd = os.path.dirname(line))
|
||||
|
||||
# загружаем данные описания задачи
|
||||
data = json.loads(textdata)
|
||||
# провряем их на корректность
|
||||
self.TestTaskData(data)
|
||||
# пакуем все в объект-описание задачи
|
||||
task_descr = task.TaskDescription(self, line, data)
|
||||
|
||||
# вычисляем псевдоуникальный идентификатор модели
|
||||
tid = hash(data['meta'])
|
||||
# сохраняем описание задачи
|
||||
self.tasks_meta[tid] = {
|
||||
'title': data.get('title', ''),
|
||||
'author': data.get('author', ''),
|
||||
'meta': data['meta'],
|
||||
'exec': line
|
||||
}
|
||||
|
||||
# выделяем описания моделей
|
||||
ms = data.get('models', {})
|
||||
for label, data in ms.iteritems():
|
||||
model_descr = task.DataDescription(None, label, data, tid)
|
||||
# добавляем в список описаний
|
||||
self.task_descrs.append(task_descr)
|
||||
self.models.append(model_descr)
|
||||
|
||||
self.WriteToLog('Task from "{}" asked'.format(line))
|
||||
except IOError, e:
|
||||
self.WriteToLog('file "{}" not found'.format(line))
|
||||
@ -109,84 +109,120 @@ class LocalServer:
|
||||
except ValueError, e:
|
||||
self.WriteToLog('file "{}" not opened, error "{}")'.format(line, e))
|
||||
|
||||
def GetTasksDescriptions(self):
|
||||
"""
|
||||
Return list with task descriptions
|
||||
"""
|
||||
return self.task_descrs
|
||||
def GetModels(self):
|
||||
return self.models
|
||||
|
||||
def GetTaskMeta(self, tid):
|
||||
return self.tasks_meta.get(tid)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def CreateJob(self):
|
||||
jid = self.next_job_id
|
||||
self.next_job_id += 1
|
||||
with self.queue_lock:
|
||||
self.jobs[jid] = Job()
|
||||
return jid
|
||||
|
||||
def GetJobsCount(self):
|
||||
pass
|
||||
return len(self.jobs)
|
||||
|
||||
def GetJob(self, index):
|
||||
pass
|
||||
def GetJobState(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
return job.GetState()
|
||||
|
||||
def AddJob(self, taskd, datadump):
|
||||
job = Job(taskd, datadump)
|
||||
with self.queue_lock:
|
||||
self.jobs_queue.append(job)
|
||||
WriteToLog('Job added')
|
||||
return job
|
||||
def IsJobChanged(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
return job.IsChanged()
|
||||
else:
|
||||
False
|
||||
|
||||
def GetJobResult(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
return job.GetResult()
|
||||
|
||||
def GetJobTID(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
return job.tid
|
||||
|
||||
def LaunchJob(self, jid, data_def):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
tid = data_def.DD.tid
|
||||
datadump = data_def.PackParams()
|
||||
job.Launch(tid, datadump)
|
||||
return True
|
||||
|
||||
def StopJob(self, jid):
|
||||
job = self.jobs.get(jid)
|
||||
if job != None:
|
||||
job.Stop()
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def Start(self):
|
||||
self.running = True
|
||||
for i in xrange(self.workers):
|
||||
worker = Worker(self)
|
||||
worker.start()
|
||||
|
||||
def Stop(self):
|
||||
self.running = False
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class Worker(threading.Thread):
|
||||
number = 0
|
||||
|
||||
def __init__(self, queue, lock, runflag):
|
||||
def __init__(self, server):
|
||||
threading.Thread.__init__(self)
|
||||
self.queue = queue
|
||||
self.lock = lock
|
||||
self.runflag = runflag
|
||||
self.server = server
|
||||
self.daemon = True
|
||||
WriteToLog('worker started')
|
||||
self.id = Worker.number
|
||||
Worker.number += 1
|
||||
WriteToLog('worker started')
|
||||
|
||||
def Cycle(self):
|
||||
job = None
|
||||
# найти следующее готовое к выполнению задание
|
||||
with self.lock:
|
||||
for j in self.queue:
|
||||
if not j.IsBusy():
|
||||
job = j
|
||||
job.SetBusy()
|
||||
break
|
||||
# и, если нашли, приступаем к выполнению
|
||||
if job:
|
||||
WriteToLog("{} started!".format(self.id))
|
||||
job.Start(self.runflag)
|
||||
WriteToLog("{} finished!".format(self.id))
|
||||
def FindNextJob(self):
|
||||
with self.server.queue_lock:
|
||||
for jid, job in self.server.jobs.iteritems():
|
||||
# если нашли ожидающую вызова работу
|
||||
if job.state == JOB_READY:
|
||||
job.state = JOB_RUNNING # пометим, как запущенную
|
||||
WriteToLog('Job ({}) found'.format(jid))
|
||||
return job
|
||||
return None
|
||||
|
||||
def ProcessJob(self, job):
|
||||
try:
|
||||
execpath = self.server.GetTaskMeta(job.tid)['exec']
|
||||
# запускаем процесс на выполнение
|
||||
proc = subprocess.Popen([execpath, '-r'], shell = True,
|
||||
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
|
||||
stderr = subprocess.STDOUT, cwd = os.path.dirname(execpath))
|
||||
job.proc = proc
|
||||
# передаем стартовые параметры
|
||||
proc.stdin.write(job.datadump + '\n')
|
||||
proc.stdin.flush()
|
||||
# пока процесс не завершится (или его не прибьют)
|
||||
while proc.poll() == None:
|
||||
msg = proc.stdout.readline()
|
||||
self.ProcessMessage(job, msg)
|
||||
if not self.server.running:
|
||||
proc.kill()
|
||||
raise KeyError
|
||||
except Exception, e:
|
||||
WriteToLog('Job loop failed: ' + str(e))
|
||||
job.Finish(JOB_STOPPED)
|
||||
else:
|
||||
time.sleep(1)
|
||||
job.Finish(JOB_COMPLETED, 1.0)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
if not self.runflag:
|
||||
return
|
||||
self.Cycle()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
JOB_READY = 0
|
||||
JOB_BUSY = 1
|
||||
JOB_RUNNING = 2
|
||||
JOB_STOPPED = 3
|
||||
JOB_COMPLETED = 4
|
||||
JOB_DROPPED = 5
|
||||
|
||||
class Job:
|
||||
def __init__(self, taskd, datadump):
|
||||
self.taskd = taskd
|
||||
self.datad = datadump
|
||||
self.state = JOB_READY
|
||||
self.percent = 0.0
|
||||
self.comment = ''
|
||||
self.result = None
|
||||
self.proc = None
|
||||
self.client_data = None
|
||||
|
||||
def ProcessMsg(self, msg):
|
||||
def ProcessMessage(self, job, msg):
|
||||
try:
|
||||
# разбираем полученный ответ
|
||||
data = json.loads(msg)
|
||||
# извлекаем оттуда ответ
|
||||
@ -194,11 +230,11 @@ class Job:
|
||||
# ответ получен ок или предупреждение
|
||||
# записываем значение прогресса, если имеется
|
||||
if ans == 'ok' or ans == 'warning':
|
||||
self.percent = data.get('value', 0.0)
|
||||
job.percent = data.get('value', 0.0)
|
||||
# в ответе пришел результат вычислений
|
||||
# помещаем в секцию результата
|
||||
elif ans == 'result':
|
||||
self.result = data['result']
|
||||
job.result = data['result']
|
||||
# произошла ошибка
|
||||
elif ans == 'error':
|
||||
WriteToLog('Error! ' + msg)
|
||||
@ -206,69 +242,111 @@ class Job:
|
||||
else:
|
||||
pass
|
||||
# возможно, комментарий прольет свет на проблему
|
||||
self.comment = data.get('comment', '')
|
||||
|
||||
|
||||
def Start(self, runflag):
|
||||
try:
|
||||
self.state = JOB_RUNNING
|
||||
execpath = self.taskd.execpath
|
||||
# запускаем процесс на выполнение
|
||||
self.proc = subprocess.Popen([execpath, '-r'], shell = True,
|
||||
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
|
||||
stderr = subprocess.STDOUT, cwd = os.path.dirname(execpath))
|
||||
# передаем стартовые параметры
|
||||
istream = self.proc.stdin
|
||||
ostream = self.proc.stdout
|
||||
istream.write(self.datad + '\n')
|
||||
istream.flush()
|
||||
# пока процесс не завершится (или его не прибьют)
|
||||
while self.proc.poll() == None:
|
||||
try:
|
||||
msg = ostream.readline()
|
||||
#msg = msg.strip()
|
||||
self.ProcessMsg(msg)
|
||||
|
||||
if not runflag:
|
||||
self.Stop()
|
||||
# todo вписать исключения, которые относятся к JSON & dict
|
||||
except Exception, e:
|
||||
#WriteToLog('Income msg failed: ' + str(e))
|
||||
job.comment = data.get('comment', '')
|
||||
# почему изменяем флаг состояния здесь в конце?
|
||||
# потому как только после правильной обработки сообщения
|
||||
# мы можем быть уверены, что состояние действительно изменилось
|
||||
job.ChangeState()
|
||||
except KeyError as e:
|
||||
pass
|
||||
except ValueError as e:
|
||||
pass
|
||||
self.state = JOB_COMPLETED
|
||||
except Exception, e:
|
||||
WriteToLog('Job loop failed: ' + str(e))
|
||||
self.state = JOB_STOPPED
|
||||
|
||||
def SetBusy(self):
|
||||
self.state = JOB_BUSY
|
||||
def Cycle(self):
|
||||
# найти следующее готовое к выполнению задание
|
||||
job = self.FindNextJob()
|
||||
# и, если нашли, приступаем к выполнению
|
||||
if job:
|
||||
WriteToLog("{} started!".format(self.id))
|
||||
self.ProcessJob(job)
|
||||
WriteToLog("{} finished!".format(self.id))
|
||||
else:
|
||||
time.sleep(1)
|
||||
|
||||
def IsBusy(self):
|
||||
return self.state != JOB_READY
|
||||
def run(self):
|
||||
while True:
|
||||
if not self.server.running:
|
||||
return
|
||||
self.Cycle()
|
||||
|
||||
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
|
||||
JOB_READY = 0
|
||||
JOB_RUNNING = 1
|
||||
JOB_STOPPED = 2
|
||||
JOB_COMPLETED = 3
|
||||
|
||||
def IsComplete(self):
|
||||
return self.GetStatus() == JOB_COMPLETE
|
||||
class Job:
|
||||
def __init__(self):
|
||||
self.tid = None
|
||||
self.datadump = None
|
||||
self.state = JOB_STOPPED # состояние выполнения работы
|
||||
self.percent = -1.0 # прогресс (от 0.0 до 1.0 или -1.0)
|
||||
self.comment = '' # комментарий к ходу выполнения
|
||||
self.result = None # результат вычислений
|
||||
self.proc = None # ссылка на субпроцесс
|
||||
self.state_id = 0
|
||||
self.last_state_id = 0
|
||||
|
||||
def ChangeState(self):
|
||||
self.state_id += 1
|
||||
|
||||
def GetState(self):
|
||||
self.last_state_id = self.state_id
|
||||
return (self.state, self.percent, self.comment)
|
||||
|
||||
def IsChanged(self):
|
||||
return self.state_id != self.last_state_id
|
||||
|
||||
def Launch(self, tid, datadump):
|
||||
self.tid = tid
|
||||
self.datadump = datadump
|
||||
self.state = JOB_READY
|
||||
self.ChangeState()
|
||||
|
||||
def Stop(self):
|
||||
WriteToLog('Try to kill')
|
||||
if self.proc and self.proc.poll() == None:
|
||||
self.proc.kill()
|
||||
self.ChangeState()
|
||||
WriteToLog('Job killed')
|
||||
|
||||
def GetState(self):
|
||||
return self.state
|
||||
def Finish(self, state, percent = None):
|
||||
self.proc = None
|
||||
self.state = state
|
||||
if percent:
|
||||
self.percent = percent
|
||||
self.ChangeState()
|
||||
|
||||
def GetResult(self):
|
||||
return self.result
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
import time, random
|
||||
from pprint import pprint
|
||||
|
||||
def main():
|
||||
pass
|
||||
s = LocalServer(workers = 2)
|
||||
s.LoadModels()
|
||||
s.Start()
|
||||
models = s.GetModels()
|
||||
model = models[0]
|
||||
md = task.DataDefinition(model)
|
||||
md['d'] = 10
|
||||
md['r'] = 3.14
|
||||
|
||||
slots = [ s.CreateJob() for i in xrange(5) ]
|
||||
for jid in slots:
|
||||
md['n'] = random.randint(20, 30)
|
||||
print jid, md['n']
|
||||
s.LaunchJob(jid, md)
|
||||
|
||||
time.sleep(30)
|
||||
|
||||
for jid in slots:
|
||||
pprint(s.GetJobResult(jid))
|
||||
print ''
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -12,29 +12,7 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import copy
|
||||
|
||||
class TaskDescription:
|
||||
"""
|
||||
Description of the task. Task runs on server.
|
||||
"""
|
||||
def __init__(self, server, execpath, data):
|
||||
"""
|
||||
``server`` is owner of task process
|
||||
|
||||
``execpath`` - path to task executable
|
||||
|
||||
``data`` is parsed data presentation about models, methods
|
||||
and meta information
|
||||
"""
|
||||
self.server = server
|
||||
self.execpath = execpath
|
||||
self.data = data
|
||||
self.models = []
|
||||
for label, data in self.data['models'].iteritems():
|
||||
self.models.append(DataDescription(None, label, data, self))
|
||||
|
||||
def GetModelsDescriptions(self):
|
||||
return self.models
|
||||
import json
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -68,14 +46,15 @@ class Parameter:
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
class DataDescription:
|
||||
def __init__(self, parent, label, data, taskd):
|
||||
def __init__(self, parent, label, data, tid):
|
||||
self.parent = parent
|
||||
self.label = label
|
||||
self.data = data
|
||||
self.taskd = taskd
|
||||
self.tid = tid
|
||||
|
||||
# создание описаний параметров
|
||||
self.pdata = self.data.get('params', {})
|
||||
# заменяем текстовое описание на объект-параметр
|
||||
for label in self.pdata:
|
||||
par = Parameter(self.pdata[label])
|
||||
self.pdata[label] = par
|
||||
@ -83,7 +62,7 @@ class DataDescription:
|
||||
self.specs = []
|
||||
# рекурсивное создание описаний спецификаций
|
||||
for label, data in self.data.get('spec', {}).iteritems():
|
||||
self.specs.append(DataDescription(self, label, data, self.taskd))
|
||||
self.specs.append(DataDescription(self, label, data, self.tid))
|
||||
|
||||
def GetLabel(self):
|
||||
return self.label
|
||||
@ -142,50 +121,3 @@ class DataDefinition:
|
||||
package.reverse()
|
||||
return json.dumps(package)
|
||||
|
||||
def Flush(self):
|
||||
server = self.DD.taskd.server
|
||||
datadump = self.PackParams()
|
||||
self.job = server.AddJob(self.DD.taskd, datadump)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
import server, json, time
|
||||
from pprint import pprint
|
||||
|
||||
def main():
|
||||
s = server.LocalServer()
|
||||
s.LoadTasksDescriptions()
|
||||
ds = s.GetTasksDescriptions()
|
||||
models = []
|
||||
for d in ds:
|
||||
models.extend(d.GetModelsDescriptions())
|
||||
|
||||
model = models[0]
|
||||
|
||||
mdef = DataDefinition(model)
|
||||
pprint(mdef.DD.data)
|
||||
mdef['r'] = 3.14
|
||||
mdef['n'] = 5
|
||||
mdef['d'] = 0
|
||||
mdef2 = mdef.Copy()
|
||||
mdef2['d'] = 30
|
||||
p = mdef.PackParams()
|
||||
pprint(p)
|
||||
p = mdef2.PackParams()
|
||||
pprint(p)
|
||||
|
||||
#mdef.Flush()
|
||||
mdef2.Flush()
|
||||
|
||||
time.sleep(1)
|
||||
mdef2.job.Stop()
|
||||
|
||||
time.sleep(5)
|
||||
print mdef2.job.GetState()
|
||||
|
||||
print 'RESULT'
|
||||
#pprint(mdef.job.result)
|
||||
pprint(mdef2.job.result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"title": "Example task",
|
||||
"author": "Anton Vakhrushev",
|
||||
"meta": "av-example-task",
|
||||
|
||||
"models": {
|
||||
|
||||
|
@ -42,10 +42,7 @@ def result(r):
|
||||
return json.dumps({
|
||||
"answer": "result",
|
||||
"result": {
|
||||
"table": {
|
||||
"head": [{"x": "double"}, {"y": "double"}],
|
||||
"body": r
|
||||
}
|
||||
"table": [[ {"x": "double"}, {"y": "double"} ]] + r
|
||||
}
|
||||
})
|
||||
|
||||
@ -81,7 +78,7 @@ def main():
|
||||
res.append([l, y])
|
||||
write(answer(l / r))
|
||||
l += h
|
||||
time.sleep(0.2)
|
||||
#time.sleep(0.1)
|
||||
|
||||
write(result(res))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user