dexscript / design

DexScript - for Better Developer EXperience
http://dexscript.com
Apache License 2.0
4 stars 0 forks source link

Actor Communication #24

Open taowen opened 5 years ago

taowen commented 5 years ago

Single actor

function Hello() {
  print('hello')
}

One actor blocking call another actor

function Hello() {
  print('hello')
  print(World())
}
function World(): String {
  return 'world'
}

One actor start then wait another actor

function Hello() {
  print('hello')
  world := World{'world'}
  print(await world)
}
function World(msg: String): String {
  return msg
}

One actor A start another actor B, A blocking call B's method

function Hello() {
  print('hello')
  world := World{}
  print(world.say())
}
function World() {
  await {
  say(): String {
    'world' -> say
  }}
}

Start actor from method

function Hello() {
  print('hello')
  world := World{}
  say := world.say{}
  print(<- say)
}
function World() {
  await {
  say(): String {
    'world' -> say
  }}
}

Wait for multiple actors, any one finishes, the wait unblocks

function Hello() {
  print('hello')
  world1 := World{'world1'}
  say1 := world1.say{}
  world2 := World{'world2'}
  say2 := world2.say{}
  await {
  msg := <- say1 {
    print(msg)
  }
  msg := <- say2 {
    print(msg)
  }}
}
function World(msg String) {
  await {
  say(): String {
    msg -> say
  }}
}

Wait for request and response at same time

function Hello() {
  print('hello')
  world1 := World{'world1'}
  say1 := world1.say{}
  world2 := World{'world2'}
  say2 := world2.say{}
  await {
  say() {
    print('hello')
  }
  msg := <- say1 {
    print(msg)
  }
  msg := <- say2 {
    print(msg)
  }}
}
function World(msg String) {
  await {
  say(): String {
    msg -> say
  }}
}

Reply message does not need to happen in the block, continuation can be saved.

function Hello() {
  print('hello')
  world := World{}
  say1 := world.say1{}
  say2 := world.say2{}
}
function World() {
  tasks := Task<string>[]{}
  await {
  say1(): String {
    tasks.push(say1)
  }}
  await {
  say2(): String {
    tasks.push(say2)
  }}
  for (var task of tasks) {
    'world' -> task
  }
}

For one function call, there is a "Result" object on the caller side, and a "Task" object on the callee side. You can use <- to get value from Result, and use -> to rely result of task.

The definition of Result is

interface ResultObserver {
  Observed(result: Result)
}
interface Result {
  T: type
  Value(): T
  Finished(): bool
  AddObserver(observer: ResultObserver)
}

The definition of Task is

interface Task {
  T: type
  Finish(T value)
}