Samo Penic
2018-05-05 ec673dd8b594a808cb9d9a14937b3dcd4a365dc5
commit | author | age
57af9d 1 #!/usr/bin/python3
SP 2 import requests
3 import json
4 from time import sleep
5 import uuid
6 import subprocess
7 from trisurf import trisurf
8 import os
9 import shutil
10 import signal
11 import sys
12 import socket
13 CONNECT_ADDR='http://localhost:8000'
14
15 p=None
16 workingdir=None
17
18
19
20 #--- SIGINT and SIGTERM HANDLING ---
21 def signal_handler(signal,frame):
22     global p
23     global wirkingdir
24     if p is not None:
25         p.terminate()
26     if(workingdir is not None):
27         removeDir(workingdir.fullpath())
28     print("Process ended with signal " +str(signal))
29     sys.exit(0)
30 signal.signal(signal.SIGINT, signal_handler)
31 signal.signal(signal.SIGTERM, signal_handler)
32 #--- END SIGINT and SIGTERM----
33
34
35
36 def get_hostname():
37     return socket.gethostname()
38
39 def get_ip():
40     return ((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])
41
42 def get_client_id(addr, my_ip, my_hostname):
43     client_auth={'ip':my_ip,'hostname':my_hostname}
44     response=requests.post(addr+"/api/register/", data=client_auth)
45     if(response.status_code==200):
46         client_data=json.loads(response.text)
47         client_id=client_data['id']
48         return client_id
49     else:
50         raise ValueError
51
52
53 def get_run(addr,cid):
54     response=requests.get(addr+"/api/getrun/"+str(cid)+"/")
55     if(response.status_code==200):
56         client_data=json.loads(response.text)
57         rid=client_data['id']
58         tape=client_data['tape']
59         vtu=client_data['lastVTU']
60         status=client_data['status']
61         return (rid,tape,vtu,status)
62     else:
aae035 63         print(response.text)
57af9d 64         raise ValueError
SP 65
66
67 def ping_run(addr,cid, rid):
68     client_data={'client_id':cid, 'run_id':rid}
69     response=requests.post(addr+"/api/ping/", data=client_data)
70     if(response.status_code==200):
71         return
72     else:
73         raise ValueError
74
1d3d12 75 def send_error_report(addr,cid, rid,errcode):
SP 76     client_data={'client_id':cid, 'run_id':rid, 'error_code':errcode}
77     response=requests.post(addr+"/api/reporterr/", data=client_data)
78     if(response.status_code==200):
79         return
80     else:
81         raise ValueError
82
57af9d 83 def upload(addr,cid, rid, vtu, status):
SP 84     client_data={'client_id': cid, 'run_id': rid, 'lastVTU': vtu, 'status': status}
85     response=requests.post(addr+"/api/upload/", data=client_data)
86     if(response.status_code==200):
87         return
88     else:
89         raise ValueError
90
91 def getNewVTU(directory):
92     fset=set()
93     for file in os.listdir(directory):
94         if file.endswith(".vtu") and file.startswith("timestep_"):
95             fset.add(file)
96     return fset
97
98
99 def removeDir(directory):
100     os.chdir('/')
101     try:
102         shutil.rmtree(directory)
103     except:
104         print("Cannot remove directory "+directory+ "\n")
105     return
106
107
108 while(True):
109     try:
110         cid=get_client_id(CONNECT_ADDR, get_ip(),get_hostname())
111     except:
112         print("Cannot get CID.")
113         sleep(10)
114         continue
115     print("Got CID. getting RID.")
116     while(True):
117         try:
118             (rid,tape,vtu,status)=get_run(CONNECT_ADDR,cid)
119         except:
120             print("Could not get RID.")
121             sleep(10)
122             break
123         else:
124             #start separate thread with simulations.
125             workingdir=trisurf.Directory('/tmp/ts_'+str(uuid.uuid4()))
126             workingdir.makeifnotexist()
127             workingdir.goto()
128             with open(workingdir.fullpath()+"/tape", 'w') as f:
129                 f.write(tape)
130             if(int(status)==-1):
131                 cmd=['trisurf', '--force-from-tape']
132                 print("Run id="+str(rid)+ " :: Starting from tape")
133             else:
134                 with open(workingdir.fullpath()+"/.status",'w') as f:
135                     f.write(status)
136                 with open(workingdir.fullpath()+"/initial.vtu",'w') as f:
137                     f.write(vtu)
138                 cmd=['trisurf', '--restore-from-vtk', 'initial.vtu']
139                 print("Run id="+str(rid)+ " :: Restoring from vtk, last timestep "+status)
140             p=subprocess.Popen(cmd, stdout=subprocess.DEVNULL)
141             s=int(status)
142             while(True):
143                 #monitor for new file. If file is present, upload it!
144                 newVTU=getNewVTU(workingdir.fullpath())
145                 if newVTU: #upload
146                     try:
147                         for nv in sorted(newVTU):
148                             with open(nv,'r') as f:
149                                 fc=f.read()
150                             s=s+1
151                             print('Uploading '+nv)
152                             upload(CONNECT_ADDR, cid, rid, fc, s)
153                             os.unlink(nv)
154                     except:
155                         print("Could not upload")
156                         p.terminate()
157                         removeDir(workingdir.fullpath())
158                         break
159                     else:
160                         print("VTU uploaded")
161                 else: #ping
162                     try:
163                         ping_run(CONNECT_ADDR, cid, rid)
164                     except:
165                         print("Could not ping")
166                         p.terminate()
167                         removeDir(workingdir.fullpath())
168                         #stop simulations
169                         break
170                 #check if trisurf is still running. If not break the highest level loop.
171                 sleep(1)
172                 if(p.poll() is not None): # trisurf exited!
1d3d12 173                     print("Trisurf was stopped with return code {}".format(p.returncode))
4db06c 174                     if(p.returncode>0):
1d3d12 175                         try:
SP 176                             send_error_report(CONNECT_ADDR, cid, rid, p.returncode)
177                         except:
178                             print("Server didn't accept error report")
57af9d 179                     removeDir(workingdir.fullpath())
SP 180                     break
181                 sleep(100)            
182
183                 
184