elixirscript / processes

Erlang style processes in JavaScript
https://elixirscript.github.io/processes/
55 stars 4 forks source link

Can make a test code run #2

Closed lin7sh closed 5 years ago

lin7sh commented 7 years ago

Dear maintainer of the this project, I'm trying to learn how to use this code by translate the following code into process.js

-module(counter_server).
-export([start/1, add/1, get/1]).

start(State) ->
    spawn(fun() -> loop(State) end).

add(Pid) ->
    cast(Pid, {add}).

get(Pid) ->
    call(Pid, {get}).

call(Pid, {Request}) ->
    Pid ! {Request, self()},
    receive
        Response -> Response
    end.

cast(Pid, {Request}) ->
    Pid ! {Request}.

loop(State) ->
    receive
        {add} ->
            loop(State + 1);
        {get, From} ->
            From ! State,
            loop(State)
    end.

the following is my attempt

const { ProcessSystem } = require("./process.js")

const system = new ProcessSystem()

main()

function main() {
    const p = start(10)
    console.log(get(p)) // undefined
}

function start(state) {
    return system.spawn(function*() {
        yield* loop(state)
    })
}

function add(pid) {
    cast(pid, ["add"])
}

function get(pid) {
    const G = ProcessSystem.run(call, [pid, ["get"]], this)
}

function* call(pid, [request]) {
    console.log("send") // never get called
    let response
    system.send([request, system.pid()])
    yield system.receive(response1 => response = response1)
    return response

}
function cast(pid, [request]) {
    system.send([request])
}

function* loop(state) {
    system.receive(([mesg, from]) => {
        console.log(mesg, from)
        if(mesg === "add" && !from)
            yield* loop(state + 1)
        else if(mesg === "get" && from) {
            console.log(from)
            system.send(from, state)
            yield* loop(state)
        }
    })
}

the first comment line log undefined, the second comment line never execute which I think where the problem is, Could you help a look where I did wrong

======= version 2

const { ProcessSystem } = require("./process.js")

const system = new ProcessSystem()

main()

function main() {
    const p = start(10)
    const g = get(p)
    const result = g.next()
    console.log(result)
}

function start(state) {
    return system.spawn(function*() {
        yield* loop(state)
    })
}

function add(pid) {
    cast(pid, ["add"])
}

function* get(pid) {
    yield* ProcessSystem.run(call, [pid, ["get"]], null)
}

function* call(pid, [request]) {
    let response
    system.send(pid, [request, system.pid()])
    console.log("mark1")
    yield system.receive(response1 => {
        response = response1
        console.log("mark2")
    })
    console.log("mark3")
    return response
}

function cast(pid, [request]) {
    system.send([request])
}
function* loop(state) {
    system.receive(([mesg, from]) => {
        console.log("mark4")
        if(mesg === "add" && !from)
            yield* loop(state + 1)
        else if(mesg === "get" && from) {
            console.log(from)
            system.send(from, state)
            yield* loop(state)
        }
    })
}
mark1
{ value: [ Symbol(receive), [Function], null, [Function: timeoutFn] ],
  done: false }
bryanjos commented 7 years ago

Sure, so the reason get(p) is coming back as undefined is because you aren't returning anything in get. Second, ProcessSystem.run makes calls that are not to generators into generator calls and for ones that are, it passes them through. So I think get should be a generator function and you would have to yield the result from ProcessSystem.run

lin7sh commented 7 years ago

@bryanjos I updated the to version2, There are 4 console.log marks, only mark1 has shown in the log, It seems like the both receive function never execute,