Samo Penic
2018-05-04 24419f3f161dd937649f645f6259fb7f3d2f1e06
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:
63         raise ValueError
64
65
66 def ping_run(addr,cid, rid):
67     client_data={'client_id':cid, 'run_id':rid}
68     response=requests.post(addr+"/api/ping/", data=client_data)
69     if(response.status_code==200):
70         return
71     else:
72         raise ValueError
73
1d3d12 74 def send_error_report(addr,cid, rid,errcode):
SP 75     client_data={'client_id':cid, 'run_id':rid, 'error_code':errcode}
76     response=requests.post(addr+"/api/reporterr/", data=client_data)
77     if(response.status_code==200):
78         return
79     else:
80         raise ValueError
81
57af9d 82 def upload(addr,cid, rid, vtu, status):
SP 83     client_data={'client_id': cid, 'run_id': rid, 'lastVTU': vtu, 'status': status}
84     response=requests.post(addr+"/api/upload/", data=client_data)
85     if(response.status_code==200):
86         return
87     else:
88         raise ValueError
89
90 def getNewVTU(directory):
91     fset=set()
92     for file in os.listdir(directory):
93         if file.endswith(".vtu") and file.startswith("timestep_"):
94             fset.add(file)
95     return fset
96
97
98 def removeDir(directory):
99     os.chdir('/')
100     try:
101         shutil.rmtree(directory)
102     except:
103         print("Cannot remove directory "+directory+ "\n")
104     return
105
106
107 while(True):
108     try:
109         cid=get_client_id(CONNECT_ADDR, get_ip(),get_hostname())
110     except:
111         print("Cannot get CID.")
112         sleep(10)
113         continue
114     print("Got CID. getting RID.")
115     while(True):
116         try:
117             (rid,tape,vtu,status)=get_run(CONNECT_ADDR,cid)
118         except:
119             print("Could not get RID.")
120             sleep(10)
121             break
122         else:
123             #start separate thread with simulations.
124             workingdir=trisurf.Directory('/tmp/ts_'+str(uuid.uuid4()))
125             workingdir.makeifnotexist()
126             workingdir.goto()
127             with open(workingdir.fullpath()+"/tape", 'w') as f:
128                 f.write(tape)
129             if(int(status)==-1):
130                 cmd=['trisurf', '--force-from-tape']
131                 print("Run id="+str(rid)+ " :: Starting from tape")
132             else:
133                 with open(workingdir.fullpath()+"/.status",'w') as f:
134                     f.write(status)
135                 with open(workingdir.fullpath()+"/initial.vtu",'w') as f:
136                     f.write(vtu)
137                 cmd=['trisurf', '--restore-from-vtk', 'initial.vtu']
138                 print("Run id="+str(rid)+ " :: Restoring from vtk, last timestep "+status)
139             p=subprocess.Popen(cmd, stdout=subprocess.DEVNULL)
140             s=int(status)
141             while(True):
142                 #monitor for new file. If file is present, upload it!
143                 newVTU=getNewVTU(workingdir.fullpath())
144                 if newVTU: #upload
145                     try:
146                         for nv in sorted(newVTU):
147                             with open(nv,'r') as f:
148                                 fc=f.read()
149                             s=s+1
150                             print('Uploading '+nv)
151                             upload(CONNECT_ADDR, cid, rid, fc, s)
152                             os.unlink(nv)
153                     except:
154                         print("Could not upload")
155                         p.terminate()
156                         removeDir(workingdir.fullpath())
157                         break
158                     else:
159                         print("VTU uploaded")
160                 else: #ping
161                     try:
162                         ping_run(CONNECT_ADDR, cid, rid)
163                     except:
164                         print("Could not ping")
165                         p.terminate()
166                         removeDir(workingdir.fullpath())
167                         #stop simulations
168                         break
169                 #check if trisurf is still running. If not break the highest level loop.
170                 sleep(1)
171                 if(p.poll() is not None): # trisurf exited!
1d3d12 172                     print("Trisurf was stopped with return code {}".format(p.returncode))
24419f 173                     if(p.returncode>0):
1d3d12 174                         try:
SP 175                             send_error_report(CONNECT_ADDR, cid, rid, p.returncode)
176                         except:
177                             print("Server didn't accept error report")
57af9d 178                     removeDir(workingdir.fullpath())
SP 179                     break
180                 sleep(100)            
181
182                 
183