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