diff --git a/lua/zapret-auto.lua b/lua/zapret-auto.lua index b808c0d..7e9115f 100644 --- a/lua/zapret-auto.lua +++ b/lua/zapret-auto.lua @@ -166,11 +166,11 @@ end -- args for failure detector - see standard_failure_detector or your own detector -- test case: nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-init=@zapret-auto.lua --in-range=-s1 --lua-desync=circular --lua-desync=argdebug:strategy=1 --lua-desync=argdebug:strategy=2 function circular(ctx, desync) - local function count_strategies(hrec, plan) + local function count_strategies(hrec) if not hrec.ctstrategy then local uniq={} local n=0 - for i,instance in pairs(plan) do + for i,instance in pairs(desync.plan) do if instance.arg.strategy then n = tonumber(instance.arg.strategy) if not n or n<1 then @@ -193,31 +193,24 @@ function circular(ctx, desync) end end - -- take over orchestration. prevent further instance execution in case of error - execution_plan_cancel(ctx) + -- take over execution. prevent further instance execution in case of error + orchestrate(ctx, desync) if not desync.track then DLOG_ERR("circular: conntrack is missing but required") return end - local plan = execution_plan(ctx) - if #plan==0 then - DLOG("circular: need some desync instances or useless") - return - end - local hrec = automate_host_record(desync) if not hrec then DLOG("circular: passing with no tampering") return end - count_strategies(hrec, plan) + count_strategies(hrec) if hrec.ctstrategy==0 then error("circular: add strategy=N tag argument to each following instance ! N must start from 1 and increment") end - if not hrec.nstrategy then DLOG("circular: start from strategy 1") hrec.nstrategy = 1 @@ -252,9 +245,11 @@ function circular(ctx, desync) DLOG("circular: current strategy "..hrec.nstrategy) local dcopy = desync_copy(desync) - for i=1,#plan do - if plan[i].arg.strategy and tonumber(plan[i].arg.strategy)==hrec.nstrategy then - verdict = plan_instance_execute(dcopy, verdict, plan[i]) + while true do + local instance = plan_instance_pop(desync) + if not instance then break end + if instance.arg.strategy and tonumber(instance.arg.strategy)==hrec.nstrategy then + verdict = plan_instance_execute(dcopy, verdict, instance) end end diff --git a/lua/zapret-lib.lua b/lua/zapret-lib.lua index 4e158a9..30c9c37 100644 --- a/lua/zapret-lib.lua +++ b/lua/zapret-lib.lua @@ -153,16 +153,16 @@ function plan_instance_execute(desync, verdict, instance) end return verdict end - --- redo what whould be done without orchestration -function replay_execution_plan(desync, plan) - local verdict = VERDICT_PASS - for i=1,#plan do - verdict = plan_instance_execute(desync, verdict, plan[i]) - end - return verdict +function plan_instance_pop(desync) + return (desync.plan and #desync.plan>0) and table.remove(desync.plan, 1) +end +-- this approach allows nested orchestrators +function orchestrate(ctx, desync) + if not desync.plan then + execution_plan_cancel(ctx) + desync.plan = execution_plan(ctx) + end end - -- copy desync preserving lua_state function desync_copy(desync) local dcopy = deepcopy(desync) @@ -172,18 +172,24 @@ function desync_copy(desync) end return dcopy end - +-- redo what whould be done without orchestration +function replay_execution_plan(desync) + local dcopy = desync_copy(desync) + local verdict = VERDICT_PASS + while true do + local instance = plan_instance_pop(dcopy) + if not instance then break end + verdict = plan_instance_execute(dcopy, verdict, instance) + end + return verdict +end -- this function demonstrates how to stop execution of upcoming desync instances and take over their job -- this can be used, for example, for orchestrating conditional processing without modifying of desync functions code -- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-desync=desync_orchestrator_example --lua-desync=pass --lua-desync=pass function desync_orchestrator_example(ctx, desync) - local plan = execution_plan(ctx) - if #plan>0 then - DLOG("orchestrator: taking over upcoming desync instances") - local dcopy = desync_copy(desync) - execution_plan_cancel(ctx) - return replay_execution_plan(dcopy, plan) - end + DLOG("orchestrator: taking over upcoming desync instances") + orchestrate(ctx, desync) + return replay_execution_plan(desync) end -- these functions duplicate range check logic from C code