mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 21:14:28 -08:00
fix record io bug
This commit is contained in:
@@ -154,8 +154,10 @@ const make_patched_method = (original, name, use_context) => {
|
|||||||
)
|
)
|
||||||
){
|
){
|
||||||
cxt.io_trace_is_replay_aborted = true
|
cxt.io_trace_is_replay_aborted = true
|
||||||
// Try to finish fast
|
cxt.io_trace_abort_replay()
|
||||||
// TODO invoke callback to notify that code must be restarted?
|
// throw error to prevent further code execution. It
|
||||||
|
// is not necesseary, becuase execution would not have
|
||||||
|
// any effects anyway
|
||||||
const error = new Error('io replay aborted')
|
const error = new Error('io replay aborted')
|
||||||
error.__ignore = true
|
error.__ignore = true
|
||||||
throw error
|
throw error
|
||||||
@@ -188,7 +190,7 @@ const make_patched_method = (original, name, use_context) => {
|
|||||||
const next_event = cxt.io_trace[cxt.io_trace_index]
|
const next_event = cxt.io_trace[cxt.io_trace_index]
|
||||||
if(next_event.type == 'call') {
|
if(next_event.type == 'call') {
|
||||||
cxt.io_trace_is_replay_aborted = true
|
cxt.io_trace_is_replay_aborted = true
|
||||||
// TODO reject? Test for never resolved
|
cxt.io_trace_abort_replay()
|
||||||
} else {
|
} else {
|
||||||
while(
|
while(
|
||||||
cxt.io_trace_index < cxt.io_trace.length
|
cxt.io_trace_index < cxt.io_trace.length
|
||||||
|
|||||||
@@ -29,9 +29,18 @@ const gen_to_promise = gen_fn => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const make_promise_with_rejector = cxt => {
|
||||||
|
let rejector
|
||||||
|
const p = new cxt.window.Promise(r => rejector = r)
|
||||||
|
return [p, rejector]
|
||||||
|
}
|
||||||
|
|
||||||
const do_run = function*(module_fns, cxt, io_trace){
|
const do_run = function*(module_fns, cxt, io_trace){
|
||||||
let calltree
|
let calltree
|
||||||
|
|
||||||
|
const [replay_aborted_promise, io_trace_abort_replay] =
|
||||||
|
make_promise_with_rejector(cxt)
|
||||||
|
|
||||||
cxt = (io_trace == null || io_trace.length == 0)
|
cxt = (io_trace == null || io_trace.length == 0)
|
||||||
// TODO group all io_trace_ properties to single object?
|
// TODO group all io_trace_ properties to single object?
|
||||||
? {...cxt,
|
? {...cxt,
|
||||||
@@ -46,32 +55,38 @@ const do_run = function*(module_fns, cxt, io_trace){
|
|||||||
// Map of (index in io_trace) -> resolve
|
// Map of (index in io_trace) -> resolve
|
||||||
io_trace_resolvers: new Map(),
|
io_trace_resolvers: new Map(),
|
||||||
io_trace_index: 0,
|
io_trace_index: 0,
|
||||||
|
io_trace_abort_replay,
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_promise_patch(cxt)
|
apply_promise_patch(cxt)
|
||||||
set_current_context(cxt)
|
set_current_context(cxt)
|
||||||
|
|
||||||
for(let {module, fn} of module_fns) {
|
for(let {module, fn} of module_fns) {
|
||||||
cxt.found_call = null
|
cxt.found_call = null
|
||||||
cxt.children = null
|
cxt.children = null
|
||||||
calltree = {
|
calltree = {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
module,
|
module,
|
||||||
id: cxt.call_counter++
|
id: cxt.call_counter++
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cxt.modules[module] = {}
|
cxt.modules[module] = {}
|
||||||
yield fn(cxt, __trace, __trace_call, __do_await)
|
const result = fn(cxt, __trace, __trace_call, __do_await)
|
||||||
calltree.ok = true
|
if(result instanceof cxt.window.Promise) {
|
||||||
} catch(error) {
|
yield cxt.window.Promise.race([replay_aborted_promise, result])
|
||||||
calltree.ok = false
|
} else {
|
||||||
calltree.error = error
|
yield result
|
||||||
}
|
}
|
||||||
calltree.children = cxt.children
|
calltree.ok = true
|
||||||
if(!calltree.ok) {
|
} catch(error) {
|
||||||
break
|
calltree.ok = false
|
||||||
}
|
calltree.error = error
|
||||||
|
}
|
||||||
|
calltree.children = cxt.children
|
||||||
|
if(!calltree.ok) {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cxt.is_recording_deferred_calls = true
|
cxt.is_recording_deferred_calls = true
|
||||||
|
|||||||
24
test/test.js
24
test/test.js
@@ -3416,4 +3416,28 @@ const y = x()`
|
|||||||
'object',
|
'object',
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
test('record io hangs bug', async () => {
|
||||||
|
patch_builtin(
|
||||||
|
'fetch',
|
||||||
|
() => new Promise(resolve => original_setTimeout(resolve, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
const code = `
|
||||||
|
const p = fetch('')
|
||||||
|
Math.random()
|
||||||
|
await p
|
||||||
|
`
|
||||||
|
|
||||||
|
const i = await test_initial_state_async(code)
|
||||||
|
|
||||||
|
assert_equal(i.io_trace.length, 3)
|
||||||
|
|
||||||
|
const next_code = `await fetch('')`
|
||||||
|
|
||||||
|
const state = await command_input_async(i, next_code, 0)
|
||||||
|
assert_equal(state.io_trace.length, 2)
|
||||||
|
|
||||||
|
patch_builtin('fetch', null)
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user