Cross platform run loop abstraction

To install, run:

haxelib install tink_runloop 0.1.0 

See using Haxelib in Haxelib documentation for more information.


Tink Runloop

Build Status

This library provides a cross platform run loop abstraction. It works in a single threaded mode, but does leverage multiple threads when available.

The very basis of the library is the concept of a worker, with the runloop itself being also a worker. Each worker can performed tasks. In this README we shall only sketch out minimal versions of the types involved to avoid complicating the matter.

A tasks, simply put, look very much like this:

abstract Task {
	var recurring(get, never):Bool;
	var state(get, never):TaskState;
	function cancel():Void;	
	function perform():Void;
  @:from static function ofFunction(f:Void->Void):Task;
  @:from static function repeat(f:Void->TaskRepeat):Task;
  static var NOOP(default, null):Task;

enum TaskState {

enum TaskRepeat {

Most of the time, you will want to simply create tasks from anonymous functions through the implicit conversion.

Tasks are meant to be run by workers, which essentially boild down to this:

interface Worker {	
	function work(task:Task):Task;
	function atNextStep(task:Task):Task;
	function asap(task:Task):Task;
  function kill():Void;

The default implementation of the worker has an internal queue of scheduled tasks, that are performed step by step. Commonly, you will want to add tasks at the end of the queue through work, but you can also use atNextStep to add the task at the beginning. If you're in a rush, then you can perform a task through asap, which if the calling thread is the thread that the worker runs on (which is always the case in single threaded environments), will perform the task immediately, and otherwise will add it at the beginning of the worker's queue. Try using this sparsely. Without calls to asap, it is guaranteed that a worker performs only one task at a time. Also, any task can only be performed by one worker at a time.

Run loops are particular implementors of the Worker interface and can be described like so:

class RunLoop implements Worker {
  static var current(get, never):RunLoop;
  function createSlave():Worker;

Currently, there is only one run loop, but that may change in the future - if a use case presents itself. You may get by, simply scheduling all tasks on the run loop and be done. But you can also create slaves. In single threaded mode, they progress when the run loop itself is idle, so they are suitable for background tasks.

Consider something like this:

import haxe.zip.*;
import tink.core.*;
class BackgroundCompression {
  static public function compress(entries:List<Entry>, level:Int, worker:Worker):Future<Noise> {
    for (e in entries)
      worker.work(function () if (!e.compressed) e.data = haxe.zip.Compress.run(e.data, level));
    return RunLoop.current.delegate(Noise, worker);

This allows you offloading compression into a slave like so:

BackgroundCompression.compress(someEntries, 9, RunLoop.current.createSlave());

Ideally, you'll want to pool slaves to avoid creating too many.

2 years ago

All libraries are free

Every month, more than thousand developers use haxelib to find, share, and reuse code — and assemble it in powerful new ways. Enjoy Haxe; It is great!

Explore Haxe

Haxe Manual

Haxe Code Cookbook

Haxe API documentation

You can try Haxe in the browser! try.haxe.org

Join us on Github!

Haxe is being developed on GitHub. Feel free to contribute or report issues to our projects.

Haxe on Github