cloudpss 4.0.2__py3-none-any.whl → 4.1.1a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cloudpss/__init__.py +2 -3
- cloudpss/function/functionExecution.py +1 -1
- cloudpss/job/job.py +98 -135
- cloudpss/job/messageStreamReceiver.py +58 -51
- cloudpss/job/messageStreamSender.py +35 -32
- cloudpss/model/model.py +365 -324
- cloudpss/model/revision.py +9 -9
- cloudpss/model/topology.py +4 -2
- cloudpss/runner/__init__.py +5 -3
- cloudpss/runner/receiver.py +2 -0
- cloudpss/runner/runner.py +91 -18
- cloudpss/utils/AsyncIterable.py +27 -0
- cloudpss/utils/__init__.py +5 -1
- cloudpss/utils/httpAsyncRequest.py +88 -0
- cloudpss/utils/httprequests.py +6 -1
- cloudpss/utils/yamlLoader.py +40 -41
- cloudpss/version.py +1 -1
- {cloudpss-4.0.2.dist-info → cloudpss-4.1.1a1.dist-info}/METADATA +3 -1
- {cloudpss-4.0.2.dist-info → cloudpss-4.1.1a1.dist-info}/RECORD +21 -19
- {cloudpss-4.0.2.dist-info → cloudpss-4.1.1a1.dist-info}/WHEEL +0 -0
- {cloudpss-4.0.2.dist-info → cloudpss-4.1.1a1.dist-info}/top_level.txt +0 -0
cloudpss/__init__.py
CHANGED
@@ -6,17 +6,16 @@ from .model import Model, ModelRevision, ModelTopology
|
|
6
6
|
from .project import Project
|
7
7
|
from .utils import MatlabDataEncoder, DateTimeEncode
|
8
8
|
from . import function
|
9
|
-
|
9
|
+
from .job import Job
|
10
10
|
from .function import FunctionExecution
|
11
11
|
from .version import __version__
|
12
12
|
__all__ = [
|
13
13
|
'setToken', 'Model', 'ModelRevision', 'ModelTopology', 'Runner', 'Result',
|
14
14
|
'PowerFlowResult', 'EMTResult', 'MatlabDataEncoder', 'DateTimeEncode',
|
15
|
-
'function', 'Project', 'currentJob', 'IESLabSimulation', 'IESLabPlan','__version__'
|
15
|
+
'function', 'Project', 'currentJob', 'IESLabSimulation', 'IESLabPlan','__version__','Job'
|
16
16
|
]
|
17
17
|
|
18
18
|
|
19
|
-
|
20
19
|
def currentJob():
|
21
20
|
"""
|
22
21
|
获取当前的 currentExecution 实例
|
@@ -163,7 +163,7 @@ class FunctionExecution(object):
|
|
163
163
|
sys.exit(code)
|
164
164
|
|
165
165
|
def print(self, data):
|
166
|
-
print(json.dumps(data, cls=MatlabDataEncoder), flush=True)
|
166
|
+
print(json.dumps(data, cls=MatlabDataEncoder)+'\n', flush=True)
|
167
167
|
|
168
168
|
def log(self, content, level='info', html=False, key=None):
|
169
169
|
'''
|
cloudpss/job/job.py
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
+
import asyncio
|
1
2
|
import random
|
2
3
|
import re
|
3
4
|
import time
|
5
|
+
from cloudpss.utils.AsyncIterable import CustomAsyncIterable
|
6
|
+
|
7
|
+
from cloudpss.utils.httpAsyncRequest import graphql_fetch
|
4
8
|
from .view import getViewClass
|
5
9
|
|
6
10
|
from cloudpss.utils.IO import IO
|
@@ -12,20 +16,33 @@ from .jobMachine import JobMachine
|
|
12
16
|
from .messageStreamSender import MessageStreamSender
|
13
17
|
|
14
18
|
|
15
|
-
|
16
19
|
class Job(object):
|
17
20
|
"""docstring for Job"""
|
18
21
|
|
19
|
-
def __init__(
|
20
|
-
|
21
|
-
|
22
|
+
def __init__(
|
23
|
+
self,
|
24
|
+
id,
|
25
|
+
args,
|
26
|
+
createTime,
|
27
|
+
startTime,
|
28
|
+
endTime,
|
29
|
+
status,
|
30
|
+
context,
|
31
|
+
user,
|
32
|
+
priority,
|
33
|
+
policy,
|
34
|
+
machine,
|
35
|
+
input,
|
36
|
+
output,
|
37
|
+
position,
|
38
|
+
):
|
22
39
|
super(Job, self).__init__()
|
23
40
|
self.id = id
|
24
41
|
self.args = args
|
25
42
|
self.createTime = createTime
|
26
43
|
self.startTime = startTime
|
27
44
|
self.endTime = endTime
|
28
|
-
self.
|
45
|
+
self.job_status = status #这里的status字段与原本的status()冲突
|
29
46
|
self.context = context
|
30
47
|
self.user = user
|
31
48
|
self.priority = priority
|
@@ -36,15 +53,16 @@ class Job(object):
|
|
36
53
|
self.position = position
|
37
54
|
self.__receiver = None
|
38
55
|
self.__sender = None
|
56
|
+
self._result = None
|
39
57
|
|
40
58
|
@staticmethod
|
41
|
-
def fetch(id):
|
59
|
+
async def fetch(id):
|
42
60
|
"""
|
43
61
|
获取job信息
|
44
62
|
"""
|
45
63
|
if id is None:
|
46
|
-
raise Exception(
|
47
|
-
query =
|
64
|
+
raise Exception("id is None")
|
65
|
+
query = """query($_a:JobInput!){
|
48
66
|
job(input:$_a){
|
49
67
|
id
|
50
68
|
args
|
@@ -79,165 +97,103 @@ class Job(object):
|
|
79
97
|
output
|
80
98
|
position
|
81
99
|
}
|
82
|
-
}
|
100
|
+
}"""
|
83
101
|
variables = {"_a": {"id": id}}
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
102
|
+
|
103
|
+
r = await graphql_fetch(query, variables)
|
104
|
+
if "errors" in r:
|
105
|
+
raise Exception(r["errors"])
|
106
|
+
return Job(**r["data"]["job"])
|
88
107
|
|
89
108
|
@staticmethod
|
90
|
-
def fetchMany(
|
109
|
+
def fetchMany(*args):
|
91
110
|
"""
|
92
111
|
批量获取任务信息
|
93
112
|
"""
|
94
|
-
|
95
|
-
raise Exception('input is None')
|
96
|
-
query = '''query($_a:JobsInput!){
|
97
|
-
jobs(input:$_a){
|
98
|
-
item {
|
99
|
-
id
|
100
|
-
args
|
101
|
-
createTime
|
102
|
-
startTime
|
103
|
-
endTime
|
104
|
-
status
|
105
|
-
context
|
106
|
-
user
|
107
|
-
priority
|
108
|
-
policy {
|
109
|
-
id
|
110
|
-
name
|
111
|
-
users
|
112
|
-
functions
|
113
|
-
tres {
|
114
|
-
cpu
|
115
|
-
ecpu
|
116
|
-
mem
|
117
|
-
}
|
118
|
-
minPriority
|
119
|
-
maxPriority
|
120
|
-
maxDuration
|
121
|
-
createTime
|
122
|
-
updateTime
|
123
|
-
visibility
|
124
|
-
queue
|
125
|
-
}
|
126
|
-
machine {
|
127
|
-
id
|
128
|
-
name
|
129
|
-
tres {
|
130
|
-
cpu
|
131
|
-
ecpu
|
132
|
-
mem
|
133
|
-
}
|
134
|
-
valid
|
135
|
-
}
|
136
|
-
input
|
137
|
-
output
|
138
|
-
position
|
139
|
-
}
|
140
|
-
cursor
|
141
|
-
count
|
142
|
-
total
|
143
|
-
}
|
144
|
-
}'''
|
145
|
-
variables = {"_a": input}
|
146
|
-
r = graphql_request(query, variables)
|
147
|
-
if 'errors' in r:
|
148
|
-
raise Exception(r['errors'])
|
149
|
-
jobs = []
|
150
|
-
for job in r['data']['jobs']['item']:
|
151
|
-
jobs.append(Job(**job))
|
113
|
+
jobs = CustomAsyncIterable(Job.fetch,*args)
|
152
114
|
return jobs
|
115
|
+
|
153
116
|
|
154
117
|
@staticmethod
|
155
|
-
def create(revisionHash,
|
156
|
-
|
157
|
-
|
158
|
-
name=None,
|
159
|
-
rid='',
|
160
|
-
policy=None,
|
161
|
-
**kwargs):
|
162
|
-
'''
|
163
|
-
创建一个运行任务
|
118
|
+
async def create(revisionHash, job, config, name=None, rid="", policy=None, **kwargs):
|
119
|
+
"""
|
120
|
+
创建一个运行任务
|
164
121
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
122
|
+
:params: revision 项目版本号
|
123
|
+
:params: job 调用仿真时使用的计算方案,为空时使用项目的第一个计算方案
|
124
|
+
:params: config 调用仿真时使用的参数方案,为空时使用项目的第一个参数方案
|
125
|
+
:params: name 任务名称,为空时使用项目的参数方案名称和计算方案名称
|
126
|
+
:params: rid 项目rid,可为空
|
170
127
|
|
171
|
-
|
128
|
+
:return: 返回一个运行实例
|
172
129
|
|
173
|
-
|
174
|
-
|
130
|
+
>>> runner = Runner.runRevision(revision,job,config,'')
|
131
|
+
"""
|
175
132
|
|
176
|
-
|
133
|
+
# 处理policy字段
|
177
134
|
if policy is None:
|
178
135
|
policy = {}
|
179
|
-
if policy.get(
|
180
|
-
policy[
|
181
|
-
policy[
|
182
|
-
policy[
|
183
|
-
tres = {
|
184
|
-
tresStr = job[
|
185
|
-
for t in re.split(
|
186
|
-
if t ==
|
136
|
+
if policy.get("tres", None) is None:
|
137
|
+
policy["tres"] = {}
|
138
|
+
policy["queue"] = job["args"].get("@queue", 1)
|
139
|
+
policy["priority"] = job["args"].get("@priority", 0)
|
140
|
+
tres = {"cpu": 1, "ecpu": 0, "mem": 0}
|
141
|
+
tresStr = job["args"].get("@tres", "")
|
142
|
+
for t in re.split("\s+", tresStr):
|
143
|
+
if t == "":
|
187
144
|
continue
|
188
|
-
k, v = t.split(
|
189
|
-
tres[k] = float(v) #type: ignore
|
190
|
-
policy[
|
145
|
+
k, v = t.split("=")
|
146
|
+
tres[k] = float(v) # type: ignore
|
147
|
+
policy["tres"] = tres
|
191
148
|
|
192
|
-
query =
|
193
|
-
function = job[
|
194
|
-
'function/CloudPSS/')
|
149
|
+
query = """mutation($input:CreateJobInput!){job:createJob(input:$input){id input output status position}}"""
|
150
|
+
function = job["rid"].replace("job-definition/cloudpss/", "function/CloudPSS/")
|
195
151
|
variables = {
|
196
|
-
|
152
|
+
"input": {
|
197
153
|
"args": {
|
198
|
-
**job[
|
199
|
-
|
154
|
+
**job["args"],
|
155
|
+
"_ModelRevision": revisionHash,
|
156
|
+
"_ModelArgs": config["args"],
|
200
157
|
},
|
201
158
|
"context": [
|
202
159
|
function,
|
203
160
|
rid,
|
204
|
-
f"model/@sdk/{str(int(time.time() * random.random()))}"
|
161
|
+
f"model/@sdk/{str(int(time.time() * random.random()))}",
|
205
162
|
],
|
206
|
-
"policy":
|
207
|
-
policy,
|
163
|
+
"policy": policy,
|
208
164
|
}
|
209
165
|
}
|
210
|
-
r =
|
211
|
-
if
|
212
|
-
raise Exception(r[
|
213
|
-
id = r[
|
214
|
-
return Job.fetch(id)
|
166
|
+
r = await graphql_fetch(query, variables)
|
167
|
+
if "errors" in r:
|
168
|
+
raise Exception(r["errors"])
|
169
|
+
id = r["data"]["job"]["id"]
|
170
|
+
return await Job.fetch(id)
|
215
171
|
|
216
172
|
@staticmethod
|
217
|
-
def abort(id, timeout):
|
173
|
+
async def abort(id, timeout):
|
218
174
|
"""
|
219
175
|
结束当前运行的算例
|
220
176
|
|
221
177
|
"""
|
222
|
-
query =
|
178
|
+
query = """mutation ($input: AbortJobInput!) {
|
223
179
|
job: abortJob(input: $input) {
|
224
180
|
id
|
225
181
|
status
|
226
182
|
}
|
227
183
|
}
|
228
|
-
|
229
|
-
variables = {
|
230
|
-
|
184
|
+
"""
|
185
|
+
variables = {"input": {"id": id, "timeout": timeout}}
|
186
|
+
await graphql_fetch(query, variables)
|
231
187
|
|
232
188
|
@staticmethod
|
233
|
-
def load(file, format=
|
189
|
+
def load(file, format="yaml"):
|
234
190
|
return IO.load(file, format)
|
235
191
|
|
236
192
|
@staticmethod
|
237
|
-
def dump(job, file, format=
|
193
|
+
def dump(job, file, format="yaml", compress="gzip"):
|
238
194
|
return IO.dump(job, file, format, compress)
|
239
195
|
|
240
|
-
def read(self, receiver=None, dev=False, **kwargs):
|
196
|
+
async def read(self, receiver=None, dev=False, **kwargs):
|
241
197
|
"""
|
242
198
|
使用接收器获取当前运行实例的输出
|
243
199
|
"""
|
@@ -245,33 +201,40 @@ class Job(object):
|
|
245
201
|
self.__sender = receiver
|
246
202
|
if self.__receiver is None:
|
247
203
|
self.__receiver = MessageStreamReceiver(self, dev)
|
248
|
-
self.__receiver.connect(**kwargs)
|
204
|
+
await self.__receiver.connect(**kwargs)
|
249
205
|
return self.__receiver
|
250
206
|
|
251
|
-
def write(self,sender=None, dev=False, **kwargs)->MessageStreamSender:
|
207
|
+
async def write(self, sender=None, dev=False, **kwargs) -> MessageStreamSender:
|
252
208
|
"""
|
253
|
-
|
209
|
+
使用发送器为当前运行实例输入
|
254
210
|
"""
|
255
|
-
|
211
|
+
|
256
212
|
if sender is not None:
|
257
213
|
self.__sender = sender
|
258
214
|
if self.__sender is None:
|
259
|
-
self.__sender =MessageStreamSender(self,dev)
|
260
|
-
self.__sender.connect(**kwargs)
|
215
|
+
self.__sender = MessageStreamSender(self, dev)
|
216
|
+
await self.__sender.connect(**kwargs)
|
261
217
|
return self.__sender
|
262
218
|
|
219
|
+
def status(self):
|
220
|
+
if self.__receiver is not None:
|
221
|
+
return self.__receiver.status
|
222
|
+
return 0
|
223
|
+
|
263
224
|
@property
|
264
225
|
def result(self):
|
265
226
|
"""
|
266
227
|
获取当前运行实例的输出
|
267
228
|
"""
|
268
|
-
|
269
|
-
|
229
|
+
if self._result is None:
|
230
|
+
viewType = getViewClass(self.context[0])
|
231
|
+
self._result = asyncio.run(self.view(viewType))
|
232
|
+
return self._result
|
270
233
|
|
271
|
-
def view(self, viewType):
|
234
|
+
async def view(self, viewType):
|
272
235
|
"""
|
273
236
|
获取当前运行实例的输出
|
274
237
|
"""
|
275
|
-
receiver = self.read()
|
276
|
-
sender=self.write()
|
277
|
-
return viewType(receiver,sender)
|
238
|
+
receiver = await self.read()
|
239
|
+
sender = await self.write()
|
240
|
+
return viewType(receiver, sender)
|
@@ -1,35 +1,30 @@
|
|
1
1
|
import logging
|
2
|
+
|
3
|
+
from cloudpss.utils.httpAsyncRequest import websocket_connect
|
2
4
|
from .jobReceiver import JobReceiver
|
3
5
|
import os
|
4
6
|
from urllib.parse import urlparse
|
5
|
-
import websocket
|
6
7
|
import pytz
|
7
|
-
|
8
|
-
|
9
|
-
utc_tz = pytz.timezone('UTC')
|
8
|
+
|
9
|
+
utc_tz = pytz.timezone("UTC")
|
10
10
|
|
11
11
|
from ..utils.IO import IO
|
12
12
|
|
13
13
|
|
14
14
|
class Message(object):
|
15
|
-
|
16
15
|
def __init__(self, id, token):
|
17
16
|
self.id = id
|
18
17
|
self.token = token
|
19
|
-
|
20
18
|
|
21
19
|
|
22
20
|
class MessageStreamReceiver(JobReceiver):
|
23
|
-
|
24
21
|
def __init__(self, job, dev=False):
|
25
22
|
super().__init__()
|
26
23
|
self.job = job
|
27
24
|
self.dev = dev
|
28
|
-
self.origin = os.environ.get(
|
29
|
-
'https://cloudpss.net/')
|
30
|
-
self.__hasOpen=False
|
25
|
+
self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
|
31
26
|
|
32
|
-
def receive(self, id, fr0m, on_open, on_message, on_error, on_close):
|
27
|
+
async def receive(self, id, fr0m, on_open, on_message, on_error, on_close):
|
33
28
|
"""
|
34
29
|
读取消息流中的数据
|
35
30
|
id: 消息流id
|
@@ -40,28 +35,31 @@ class MessageStreamReceiver(JobReceiver):
|
|
40
35
|
on_close: 连接关闭时的回调函数
|
41
36
|
"""
|
42
37
|
if id is None:
|
43
|
-
raise Exception(
|
38
|
+
raise Exception("id is None")
|
44
39
|
u = list(urlparse(self.origin))
|
45
|
-
head =
|
40
|
+
head = "wss" if u[0] == "https" else "ws"
|
46
41
|
|
47
|
-
path = head +
|
42
|
+
path = head + "://" + str(u[1]) + "/api/streams/id/" + id
|
48
43
|
if fr0m is not None:
|
49
|
-
path = path +
|
44
|
+
path = path + "&from=" + str(fr0m)
|
50
45
|
logging.info(f"receive data from websocket: {path}")
|
51
|
-
ws =
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
46
|
+
ws = await websocket_connect(
|
47
|
+
path,
|
48
|
+
open_func=on_open,
|
49
|
+
receive_func=on_message,
|
50
|
+
error_func=on_error,
|
51
|
+
closed_func=on_close,
|
52
|
+
)
|
53
|
+
|
57
54
|
return ws
|
58
|
-
|
55
|
+
|
59
56
|
###下面是兼容Receiver部分功能实现
|
60
57
|
|
61
|
-
def on_message(self,
|
62
|
-
data = IO.deserialize(message,
|
63
|
-
msg = IO.deserialize(data[
|
64
|
-
|
58
|
+
def on_message(self, message):
|
59
|
+
data = IO.deserialize(message, "ubjson")
|
60
|
+
msg = IO.deserialize(data["data"], "ubjson")
|
61
|
+
logging.debug(f"receive message: {msg}")
|
62
|
+
if msg.get("type", None) == "log" and self.dev:
|
65
63
|
print(msg)
|
66
64
|
self.messages.append(msg)
|
67
65
|
# if msg and type(msg) is dict and msg.get('type', None) == 'terminate':
|
@@ -70,12 +68,12 @@ class MessageStreamReceiver(JobReceiver):
|
|
70
68
|
def on_error(self, ws, error):
|
71
69
|
logging.info("MessageStreamReceiver error")
|
72
70
|
msg = {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
"type": "log",
|
72
|
+
"verb": "create",
|
73
|
+
"version": 1,
|
74
|
+
"data": {
|
75
|
+
"level": "error",
|
76
|
+
"content": "websocket error",
|
79
77
|
},
|
80
78
|
}
|
81
79
|
self.messages.append(msg)
|
@@ -84,37 +82,46 @@ class MessageStreamReceiver(JobReceiver):
|
|
84
82
|
logging.info("MessageStreamReceiver close")
|
85
83
|
self._status = 0
|
86
84
|
msg = {
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
85
|
+
"type": "log",
|
86
|
+
"verb": "create",
|
87
|
+
"version": 1,
|
88
|
+
"data": {
|
89
|
+
"level": "error",
|
90
|
+
"content": "websocket closed",
|
93
91
|
},
|
94
92
|
}
|
95
93
|
self.messages.append(msg)
|
96
94
|
|
97
|
-
def on_open(self
|
95
|
+
def on_open(self):
|
98
96
|
self._status = 1
|
99
|
-
self.__hasOpen=True
|
97
|
+
self.__hasOpen = True
|
100
98
|
pass
|
101
99
|
|
102
100
|
def close(self, ws):
|
103
101
|
self._status = 0
|
104
102
|
ws.close()
|
105
103
|
|
104
|
+
@property
|
105
|
+
def status(self):
|
106
|
+
return self._status
|
107
|
+
|
106
108
|
@property
|
107
109
|
def end(self):
|
108
|
-
return
|
110
|
+
return not self._status
|
109
111
|
|
110
|
-
def connect(self):
|
112
|
+
async def connect(self):
|
111
113
|
self._status = 0
|
112
|
-
self.ws = self.receive(
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
114
|
+
self.ws = await self.receive(
|
115
|
+
self.job.output,
|
116
|
+
None,
|
117
|
+
self.on_open,
|
118
|
+
self.on_message,
|
119
|
+
self.on_error,
|
120
|
+
self.on_close,
|
121
|
+
)
|
122
|
+
|
123
|
+
# thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 6, 3))
|
124
|
+
# thread.setDaemon(True)
|
125
|
+
# thread.start()
|
126
|
+
# while not self.__hasOpen:
|
127
|
+
# time.sleep(0.2)
|
@@ -1,7 +1,10 @@
|
|
1
|
-
import sys,os
|
1
|
+
import sys, os
|
2
2
|
import threading
|
3
3
|
from urllib.parse import urlparse
|
4
|
-
|
4
|
+
|
5
|
+
from cloudpss.utils.httpAsyncRequest import websocket_connect
|
6
|
+
|
7
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), "../"))
|
5
8
|
|
6
9
|
import websocket
|
7
10
|
|
@@ -9,36 +12,34 @@ from cloudpss.utils.IO import IO
|
|
9
12
|
import time
|
10
13
|
import logging
|
11
14
|
|
12
|
-
class MessageStreamSender():
|
13
15
|
|
16
|
+
class MessageStreamSender:
|
14
17
|
def __init__(self, job, dev=False):
|
15
18
|
super().__init__()
|
16
19
|
self.job = job
|
17
20
|
self.dev = dev
|
18
|
-
self.origin = os.environ.get(
|
19
|
-
'https://cloudpss.net/')
|
21
|
+
self.origin = os.environ.get("CLOUDPSS_API_URL", "https://cloudpss.net/")
|
20
22
|
|
21
23
|
###下面是兼容Receiver部分功能实现
|
22
24
|
|
23
25
|
def on_message(self, ws, message):
|
24
|
-
logging.info(
|
26
|
+
logging.info("on_message", message)
|
25
27
|
|
26
28
|
def on_error(self, ws, error):
|
27
|
-
logging.info(
|
29
|
+
logging.info("on_error")
|
28
30
|
|
29
31
|
def on_close(self, *args, **kwargs):
|
30
32
|
time.sleep(0.5)
|
31
33
|
self._status = 0
|
32
|
-
|
33
|
-
logging.info('on_close')
|
34
34
|
|
35
|
-
|
35
|
+
logging.info("on_close")
|
36
|
+
|
37
|
+
def on_open(self):
|
36
38
|
self._status = 1
|
37
|
-
logging.info(
|
39
|
+
logging.info("on_open")
|
38
40
|
pass
|
39
41
|
|
40
42
|
def close(self):
|
41
|
-
|
42
43
|
self._status = 0
|
43
44
|
self.ws.close()
|
44
45
|
|
@@ -47,28 +48,30 @@ class MessageStreamSender():
|
|
47
48
|
return self._status
|
48
49
|
|
49
50
|
def write(self, message):
|
50
|
-
data = IO.serialize(message,
|
51
|
-
self.ws.
|
52
|
-
|
53
|
-
def connect(self):
|
54
|
-
logging.info(
|
51
|
+
data = IO.serialize(message, "ubjson", None)
|
52
|
+
self.ws.send_bytes(data)
|
53
|
+
|
54
|
+
async def connect(self):
|
55
|
+
logging.info("connect")
|
55
56
|
self._status = 0
|
56
57
|
if self.job.input is None:
|
57
|
-
raise Exception(
|
58
|
+
raise Exception("id is None")
|
58
59
|
u = list(urlparse(self.origin))
|
59
|
-
head =
|
60
|
+
head = "wss" if u[0] == "https" else "ws"
|
60
61
|
|
61
|
-
path = head +
|
62
|
+
path = head + "://" + str(u[1]) + "/api/streams/token/" + self.job.input
|
62
63
|
logging.info(f"receive data from websocket: {path}")
|
63
|
-
|
64
|
-
self.ws =
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
thread.
|
73
|
-
|
74
|
-
|
64
|
+
|
65
|
+
self.ws = await websocket_connect(
|
66
|
+
path,
|
67
|
+
open_func=self.on_open,
|
68
|
+
receive_func=self.on_message,
|
69
|
+
error_func=self.on_error,
|
70
|
+
closed_func=self.on_close,
|
71
|
+
)
|
72
|
+
|
73
|
+
# thread = threading.Thread(target=self.ws.run_forever, args=(None, None, 6, 3))
|
74
|
+
# thread.setDaemon(True)
|
75
|
+
# thread.start()
|
76
|
+
# while self.status != 1:
|
77
|
+
# time.sleep(0.2)
|