Skip to content

Commit b8c4527

Browse files
committed
Adding method's return value, async methods, and example (of limitation)
1 parent dacd6a8 commit b8c4527

File tree

4 files changed

+58
-10
lines changed

4 files changed

+58
-10
lines changed

example-1.html

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<div id="main">
1515

1616
<h3>{{ title }}</h3>
17+
<a @click="titleReverse2()" class="button">swap</a>
18+
<!--a @click="title = meth3(title)" class="button">swap</a-->
19+
<a @click="titleReverse3()" class="button">swap</a> <!-- all methods are async -->
20+
<br/>
1721

1822
We can have a state in Python which is a counter "i".
1923
The Python side automatically adds 3 to the counter every few seconds. <br/>
@@ -45,7 +49,6 @@ <h3>{{ title }}</h3>
4549
Here is a button that modifies the list of buttons, as a test...
4650
<a @click="clone('more...')" class="button">+clone</a>
4751

48-
4952
</div>
5053

5154
<script src="vuejspython.js"></script>
@@ -56,6 +59,15 @@ <h3>{{ title }}</h3>
5659
i2_injs: function () {
5760
return this.i * this.i
5861
}
62+
},
63+
methods: {
64+
async titleReverse2 () { // to my knowledge, we cannot do await directly in @click
65+
this.title = await this.meth2(this.title)
66+
},
67+
async titleReverse3 () { // to my knowledge, we cannot do await directly in @click
68+
this.title = await this.meth3(this.title)
69+
// ^^^^^ async even if in pyton it is a non-async method
70+
},
5971
}
6072
})
6173
// ^ TODO: maybe handle startup callbacks

example-1.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ def meth1(self, v):
3737
if v == '+1':
3838
self.i += 1
3939

40+
async def meth2(self, v):
41+
await asyncio.sleep(1)
42+
return str(v[::-1])
43+
44+
def meth3(self, v):
45+
return str(v[::-1])
46+
4047
def clone(self, v):
4148
print("TEST: CLONE", type(self.suggestions))
4249
self.suggestions += [v]

vuejspython.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ vuejspython.start = function(wsurl, opt={}) {
1414
}
1515
vuejspython.wsurl = wsurl
1616
var ws = new WebSocket(wsurl)
17+
let calls = {}
1718
let atomic = false
1819
let toApply = {}
1920
let valuesWhere = {}
@@ -24,6 +25,9 @@ vuejspython.start = function(wsurl, opt={}) {
2425
})
2526
ws.addEventListener('message', function(a) {
2627
a = a.data
28+
if (Object.keys(calls).length > 5) {
29+
console.log('PROBABLY MISSING RETURN FOR METHOD CALLS', Object.keys(calls).length, 'PENDING')
30+
}
2731
if (a.startsWith('INIT ')) {
2832
a = JSON.parse(a.substr('INIT '.length))
2933
let computed = {...opt.computed}
@@ -49,11 +53,16 @@ vuejspython.start = function(wsurl, opt={}) {
4953
}
5054
}
5155
for (let k of a.methods) {
52-
methods[k] = function(...args) {
53-
ws.send('CALL')
54-
ws.send('ROOT')
55-
ws.send(k)
56-
ws.send(JSON.stringify(args))
56+
methods[k] = async function(...args) {
57+
return new Promise(function (resolve, reject) {
58+
ws.send('CALL')
59+
ws.send('ROOT')
60+
let callId = (Math.random()*1000).toString().replace(/\./, '')
61+
calls[callId] = {resolve, reject}
62+
ws.send(callId)
63+
ws.send(k)
64+
ws.send(JSON.stringify(args))
65+
})
5766
}
5867
}
5968
vm = new Vue({
@@ -68,8 +77,16 @@ vuejspython.start = function(wsurl, opt={}) {
6877
...opt,
6978
})
7079
window.vuejspython_vm = vm // for console-based introspection
71-
// TODO: ATOMIC also for the components
80+
} else if (a.startsWith('RETURN ')) {
81+
let parts = a.split(' ', 2)
82+
let callId = parts[1]
83+
if (calls[callId] !== undefined) {
84+
let v = JSON.parse(a.substr(parts.join(' ').length))
85+
calls[callId].resolve(v)
86+
delete calls[callId]
87+
}
7288
} else if (a.startsWith('ATOMIC ')) {
89+
// TODO: ATOMIC also for the components
7390
let parts = a.split(' ')
7491
let upid = parts[1]
7592
// let k = parts[2] '_v_ATOMIC'

vuejspython.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ def cleanup():
193193
del all[inited]
194194
try:
195195
while True:
196-
print({k:len(all[k]) for k in all})
197196
comm = await websocket.recv()
198197
if comm == 'INIT' or comm == 'INFO':
199198
clss_name = await websocket.recv()
@@ -255,13 +254,26 @@ def cleanup():
255254
elif comm == 'CALL':
256255
id = await websocket.recv()
257256
o = g_instances[id]
257+
call_id = await websocket.recv()
258+
info('IN', 'CALL_ID', call_id)
258259
meth = await websocket.recv()
259260
info('IN', 'METH', meth)
260261
data = await websocket.recv()
261262
info('IN', 'DATA', data)
262263
try:
263-
###############
264-
res = getattr(o, meth)(*json.loads(data))
264+
method_call = getattr(o, meth)(*json.loads(data))
265+
# local block scope
266+
async def local(method_call, call_id):
267+
async def on_return(res):
268+
info('OUT', '{:.80} ...'.format('RETURN %s %s'%(call_id, json.dumps(res))))
269+
await websocket.send('RETURN %s %s'%(call_id, json.dumps(res)))
270+
271+
if type(method_call).__name__ == 'coroutine':
272+
task = asyncio.ensure_future(method_call)
273+
task.add_done_callback(lambda t: asyncio.ensure_future(on_return(t.result())))
274+
else:
275+
await on_return(method_call)
276+
await local(method_call, call_id)
265277
except Exception as inst:
266278
info('ERR', 'Exception while calling method:', inst)
267279
info_exception('ERR', ' ')

0 commit comments

Comments
 (0)