[erlang-questions] Deterministic playback of a simulation?

Hynek Vychodil hynek@REDACTED
Fri May 18 11:04:26 CEST 2012


What about using erlang tracing facility. It hase some nice features.
There will be zero inpact in production code. There will be zero
inpact in production environment if you turn it on only in testing
environment and also there is "automatic" ordering of events. I think
it is best fit for purpose.

Hynek Vychodil

On Fri, May 18, 2012 at 4:36 AM, Richard Evans
<richardprideauxevans@REDACTED> wrote:
> I have a multiplayer simulation game running in erlang, involving
> multiple characters making decisions etc. Each game instance uses a
> few (currently, 4) erlang processes running concurrently,
> communicating with an AI simulator written in C.
> Everything is working well and I am enjoying using erlang.
> But there is one thing I am finding tricky.
> For QA purposes, I want to be able to record the exact sequence of
> function-calls, so I can play the game back exactly,
> deterministically.
> My current approach is this: I have a global ets table storing a list
> of function-calls. Then, whenever I was calling a function I want to
> record - instead of calling the function directly - I call a procedure
> which adds the function to the list of function-calls, and then calls
> it:
> call_and_store(Fun, Args) ->
>    add_to_script(Fun, Args);
>    apply(lobby, Fun, Args).
> add_to_script(Fun, Args) ->
>    Info = ets:info(script),
>    {size, Size} = lists:keyfind(size, 1, Info),
>    io:format("Inserting {~p,~p,~p}~n", [Size,Fun,Args]),
>    ets:insert(script, {Size, Fun, Args}).
> This approach does not seem to work well because of erlang's
> pre-emptive scheduling. If two concurrent processes both invoke
> call_and_store, then it is possible (and seems to actually be
> happening) that erlang's pre-emptive scheduler may stop processing one
> instance of call_and_store between execution of add_to_script and
> execution of apply. If this happens, the order of execution and the
> order of recorded function-calls will diverge, we don't have an
> accurate recording of the set of function-calls, and we won't be able
> to deterministically playback.
> So my question is: is there a way to prevent the scheduler from
> yielding during a block of code? Some way to insist the block is
> called as one unit, like this:
> call_and_store(Fun, Args) ->
>        !!!prevent_yielding,
>    add_to_script(Fun, Args);
>    apply(lobby, Fun, Args),
>        !!!allow_yielding.
> My guess is: no. This does not seem very erlangy.
> Alternatively, is there a different approach which can produce the
> desired list of function-calls? My current approach seems to go
> against the erlang grain, involving writing to a shared global table.
> Is there a better, more erlangy, way of doing this?
> thanks,
> ~Richard
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

More information about the erlang-questions mailing list