Skip to content

Task Runners

jool edited this page Nov 17, 2014 · 4 revisions

What Is A Task Runner?

A task runner is a callback module implementing the ponos_task_runner_callbacks behaviour and its purpose is to give the caller more fine graned control of how a task is executed. Whenever a load generator decides it is time to trigger a task, control is handed over to the task runner. The default task runner does only one thing: apply the task. The ponos_file_task_runner, which serves more as an example than anything else, is a more intriguing example of how a task runner can be used.

How Do I Implement My Own Task Runner?

Whenever you feel the provided default task runners are insufficient, implementing your own is rather straight forward. Each load generator can have separate task runners, but typically the same is used for all.

Currently, there are 5 callbacks one must implement:

Typically you'd want to implement at least call/3. The init/2 and start/2 may return a State object that gets threaded to all other callback functions. As the triggering of tasks is asynchronous, the caller is only allowed to modify the state during init/2 and start/2. All other callbacks can only read from the state.

init

init(Name, Args) -> {ok, State}

The init/2 callback is applied by the load generator when the load generator is being added. This is a good time to do any setup-code you might need, for instance open a file or a socket.

start

start(Name, State) -> {ok, State}

The start/2 callback is applied by the load generator when ponos:init_load_generators/1 is run. This happens right before the actual load starts and it is the last opportunity the caller has to modify the state.

call

call(Name, Task, State) -> ok

The call/3 callback is applied for every single trigger the load generator generates. This is the only place where Task is ever touched. If the caller wish to inject arguments to the task, this is where he should do it, i.e. Task(Args).

pause

pause(Name, State) -> ok

The pause/2 callback is applied when a load generator is paused. If the load generator is started again, the start/2 callback will be called.

terminate

terminate(Name, State) -> ok

The terminate/2 callback is applied when the load generator is removed. Either through a call to ponos:remove_load_generators/1, or if application is terminated. If you wish to close a file or a socket, this is the time to do it.

Adding a Task Runner

The task runner is configured per load generator and is passed as part of the Options proplist. There are two relevant options:

  • task_runner
  • task_runner_args

where task_runner is a module() implementing the ponos_task_runner_callbacks behaviour, and task_runner_args is any() args the caller wishes to pass to the task runner in the init call. For example:

Name     = my_load_generator,
Task     = fun() -> ok end,
LoadSpec = ponos_load_specs:make_constant(150.0),
Options  = [ {task_runner, ponos_file_task_runner}
           , {task_runner_args, "/tmp/my_file.log"}
           ],
ponos:add_load_generators([ {name, Name}
                          , {task, Task}
                          , {load_spec, LoadSpec}
                          , {options, Options}
                          ]).
Clone this wiki locally