Skip to content

Commit 66ae5b2

Browse files
committed
Proper atomic update (currently only with @atomic)
1 parent cce8a14 commit 66ae5b2

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

vuejspython.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ vuejspython.start = function(wsurl, opt={}) {
1414
}
1515
vuejspython.wsurl = wsurl
1616
var ws = new WebSocket(wsurl)
17+
let atomic = false
18+
let toApply = {}
1719
let valuesWhere = {}
1820
let vm = null
1921
ws.addEventListener('open', function(a) {
@@ -45,7 +47,6 @@ vuejspython.start = function(wsurl, opt={}) {
4547
let owk = watch[k]
4648
watch[k] = function (...args) { watchk(...args); owk.bind(this)(...args) }
4749
}
48-
4950
}
5051
for (let k of a.methods) {
5152
methods[k] = function(...args) {
@@ -67,15 +68,41 @@ vuejspython.start = function(wsurl, opt={}) {
6768
...opt,
6869
})
6970
window.vuejspython_vm = vm // for console-based introspection
71+
// TODO: ATOMIC also for the components
72+
} else if (a.startsWith('ATOMIC ')) {
73+
let parts = a.split(' ')
74+
let upid = parts[1]
75+
// let k = parts[2] '_v_ATOMIC'
76+
let setAtomic = JSON.parse(parts[3])
77+
if (upid === 'ROOT') {
78+
if (!atomic && setAtomic) {
79+
atomic = true
80+
toApply = {}
81+
} else if (atomic && !setAtomic) {
82+
atomic = false
83+
for (let k in toApply) {
84+
let v = toApply[k]
85+
valuesWhere[k] = v
86+
vm.$set(vm, k, v)
87+
}
88+
toApply = {}
89+
} else {
90+
console.log('INCOHERENT atomic STATE', atomic, setAtomic)
91+
}
92+
}
7093
} else if (a.startsWith('UPDATE ')) {
7194
let parts = a.split(' ', 3)
7295
let upid = parts[1]
7396
let k = parts[2]
7497
if (upid === 'ROOT') {
7598
let v = a.substr(parts.join(' ').length)
7699
v = JSON.parse(v)
77-
valuesWhere[k] = v
78-
vm.$set(vm, k, v)
100+
if (atomic) {
101+
toApply[k] = v
102+
} else {
103+
valuesWhere[k] = v
104+
vm.$set(vm, k, v)
105+
}
79106
}
80107
}
81108
})

vuejspython.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def recompute_scheduled_computed(o):
9696
if not hasattr(o, '_v_schedule_recomputing') or len(o._v_schedule_recomputing) == 0: return
9797
tocomp = o._v_schedule_recomputing
9898
o._v_schedule_recomputing = []
99+
99100
for k in tocomp:
100101
recompute_computed(o, k)
101102
recompute_scheduled_computed(o)
@@ -144,6 +145,10 @@ def broadcast(self, k):
144145
if k in self._v_nobroadcast: return
145146
asyncio.ensure_future(broadcast_update(self.__id, k, getattr(self, k)))
146147

148+
def broadcast_atomic(self, start):
149+
if not hasattr(self, '__id'): return # no id yet, still building
150+
asyncio.ensure_future(broadcast_update(self.__id, KEY_ATOMIC, start))
151+
147152
def call_watcher(o, k):
148153
watcher = 'watch_'+k
149154
if hasattr(o, watcher):
@@ -152,14 +157,19 @@ def call_watcher(o, k):
152157
watcher(getattr(o, k))
153158

154159
all = []
160+
KEY_ATOMIC = '_v_ATOMIC'
155161
async def broadcast_update(id, k, v):
156162
a = all.copy()
157163
all[:] = []
164+
if k == KEY_ATOMIC:
165+
comm = 'ATOMIC'
166+
else:
167+
comm = 'UPDATE'
158168
for ws in a:
159169
try:
160170
v = sanitize(v)
161-
await ws.send('UPDATE '+str(id)+' '+str(k)+' '+json.dumps(v))
162-
info('OUT', 'UPDATE', id, k, '{:.80} ...'.format(json.dumps(v)))
171+
await ws.send(comm+' '+str(id)+' '+str(k)+' '+json.dumps(v))
172+
info('OUT', comm, id, k, '{:.80} ...'.format(json.dumps(v)))
163173
all.append(ws)
164174
except:
165175
pass
@@ -225,8 +235,9 @@ async def handleClient(websocket, path):
225235
'state': state,
226236
'methods': methods
227237
}
228-
info('OUT', comm, to_send)
229-
await websocket.send(comm + ' ' + json.dumps(to_send))
238+
to_send = json.dumps(to_send)
239+
info('OUT', comm, '{:.80} ...'.format(to_send))
240+
await websocket.send(comm + ' ' + to_send)
230241
elif comm == 'CALL':
231242
id = await websocket.recv()
232243
o = g_instances[id]
@@ -268,10 +279,12 @@ async def handleClient(websocket, path):
268279
# decorator
269280
def atomic(f):
270281
def _decorator(self, *args, **kwargs):
271-
self._v_just_schedule = True
282+
self._v_just_schedule = True # for the python to wait
283+
broadcast_atomic(self, True) # for the js to wait
272284
f(self, *args, **kwargs)
273285
self._v_just_schedule = False
274286
recompute_scheduled_computed(self)
287+
broadcast_atomic(self, False)
275288
return _decorator
276289

277290
def setup_model_object_infra(o):

0 commit comments

Comments
 (0)