-
Notifications
You must be signed in to change notification settings - Fork 9
/
requestManager.py
168 lines (123 loc) · 3.88 KB
/
requestManager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
"""
Remote Render HTTP Server with REST API
Also manages render request (which currently only involves assigning
jobs to worker)
"""
import logging
import time
import os
from flask import Flask
from flask import request
from flask import render_template
from util import renderRequest
MODULE_PATH = os.path.dirname(os.path.abspath(__file__))
HTML_FOLDER = os.path.join(MODULE_PATH, 'html')
LOGGER = logging.getLogger(__name__)
# region HTTP REST API
app = Flask(__name__)
FLASK_EXE = r'E:\Epic\UE_5.0\Engine\Binaries\ThirdParty\Python3\Win64\Scripts\flask.exe'
@app.route('/')
def index_page():
"""
Server landing page
"""
rrequests = renderRequest.read_all()
if not rrequests:
return 'Welcome!'
jsons = [rrequest.to_dict() for rrequest in rrequests]
return render_template('index.html', requests=jsons)
@app.get('/api/get')
def get_all_requests():
"""
Server GET api response, query database
:return: dict. an encapsulated dictionary with all render request serialized
"""
rrequests = renderRequest.read_all()
jsons = [rrequest.to_dict() for rrequest in rrequests]
return {"results": jsons}
@app.get('/api/get/<uid>')
def get_request(uid):
"""
Server GET api response for a specific uid request, query database
:param uid: str. render request uid
:return: dict. a render request serialized as dictionary
"""
rr = renderRequest.RenderRequest.from_db(uid)
return rr.to_dict()
@app.delete('/api/delete/<uid>')
def delete_request(uid):
"""
Server DELETE api response, delete render request from database
:param uid: str. render request uid
"""
renderRequest.remove_db(uid)
@app.post('/api/post')
def create_request():
"""
Server POST api response handling, with json data attached, creates
a render request in database
:return: dict. newly created render request serialized as dictionary
"""
data = request.get_json(force=True)
rrequest = renderRequest.RenderRequest.from_dict(data)
rrequest.write_json()
new_request_trigger(rrequest)
return rrequest.to_dict()
@app.put('/api/put/<uid>')
def update_request(uid):
"""
Server PUT api response handling, update render request in database
:param uid: str. uid of render request to update
:return: dict. updated render request serialized as dictionary
"""
# unreal sends plain text
content = request.data.decode('utf-8')
progress, time_estimate, status = content.split(';')
rr = renderRequest.RenderRequest.from_db(uid)
if not rr:
return {}
rr.update(
progress=int(float(progress)),
time_estimate=time_estimate,
status=status
)
return rr.to_dict()
# endregion
def new_request_trigger(rrequest):
"""
Triggers when a client posts a new render request to the server
"""
if rrequest.worker:
return
# currently, as a test, assigns all job to one worker
worker = 'RENDER_MACHINE_01'
assign_request(rrequest, worker)
# if multiple jobs came in at once, interval between each assignment
time.sleep(4)
LOGGER.info('assigned job %s to %s', rrequest.uid, worker)
def assign_request(rrequest, worker):
"""
Assign render request to worker
:param rrequest: renderRequest.RenderRequest. a render request object
:param worker: str. worker name
"""
rrequest.assign(worker)
rrequest.update(status=renderRequest.RenderStatus.ready_to_start)
if __name__ == '__main__':
import subprocess
import os
env = os.environ.copy()
env['PYTHONPATH'] += os.pathsep + MODULE_PATH
command = [
FLASK_EXE,
'--app',
'requestManager.py',
'--debug', # debug mode to auto reload script changes
'run',
'-h',
'localhost',
'-p',
'5000'
]
proc = subprocess.Popen(command, env=env)
LOGGER.info(proc.communicate())