Tasks

Tasks provide stateless fine-grained concurrency to Encore, which may lead to parallelism under certain circumstances.

A task executes an expression in parallel, returning immediately a future. Tasks can be spawned directly using the async keyword, or via the standard library Task.enc.

For example, an active object can spawn a task inside one of its methods to increase the parallelism in the system, e.g.:

active class Actor
  def readNews(): String
    val bbc = async(fetchURLContent("http://bbc.com")) ~~> scrapHTML
    val dn = async(fetchURLContent("http://dn.se"))~~> scrapHTML
    bbc.await()
    dn.await()
    this.presentInformation(get(bbc), get(dn))
  end
end

The async construct can also be used with blocks:

val bbc = async
  val content = fetchURLContent("http://bbc.com")
  scrapHTML(content)
end

Tasks do not spawn a new physical thread but a logical one, similar to actors. It is an abstraction detail whether a task spawns an actor or uses any other means.

Tasks are scheduled alongside of actors, and do not get special privileges. Note that tasks will not run in parallel unless the system is under-saturated, because tasks are queued on the same thread as the actor/task that spawned it, and will only run in parallel due to work-stealing.

Tasks can only refer to object instances with safe modes (active, read) and primitive types. For instance, the following example is allowed:

import Task

read trait NewspaperT
  require val web: String
  def fetchURLContent(): String
    -- fetch the content. simplification (e.g)
    "<b>BBC</b>"
  end
end

read class Newspaper : NewspaperT
  val web: String
  def init(web: String): unit
    this.web = web
  end
end

active class Main
  def main() : unit
    var newspaper = new Newspaper("http://bbc.com")
    async(newspaper.fetchURLContent())
  end
end

The type system makes sure that the Encore programming language is always free of data races, even in the presence of tasks, actors, hot objects and ParT types (Encore does not prevent deadlocks).

However, this other one is not allowed:

import Task

read trait NewspaperT
  require val web: String
  def fetchURLContent(): String
    -- fetch the content. simplification (e.g)
    "<b>BBC</b>"
  end
end

linear class Newspaper : NewspaperT
  val web: String
  def init(web: String): unit
    this.web = web
  end
end

active class Main
  def main() : unit
    var newspaper = new Newspaper("http://bbc.com")
    async(newspaper.fetchURLContent())
  end
end

As the compiler throws an error in the lines of:

*** Error during capturechecking *** 
"test.enc" (line 22, column 5)
Cannot capture variable 'newspaper' of linear type 'Newspaper' in a closure
In expression: 
  async(newspaper.fetchURLContent())

This is because the Newspaper class uses now a linear mode, which is not a safe mode.

results matching ""

    No results matching ""